root/ngcms/trunk/engine/includes/inc/lib_admin.php @ 986

Revision 986, 38.0 KB (checked in by ngcms, 13 months ago)

+ Добавлена новая возможность - запрещать/разрешать пользователям размещать новости вне категорий.
Настраивается через права доступа, пока - вручную в файле perm.default.tpl, параметр personal.nocat и other.nocat

Line 
1<?php
2
3//
4// Copyright (C) 2006-2012 Next Generation CMS (http://ngcms.ru/)
5// Name: lib_admin.php
6// Description: General function for site administration calls
7// Author: Vitaly Ponomarev
8//
9
10//
11// Mass news flags modifier
12// $list        - array with news identities [only 1 field should be filled]
13//        'id'    - list of IDs
14//        'data'    - list of records (result of SELECT query from DB)
15// $setValue    - what to change in table (array with field => value)
16// $permCheck    - flag if permissions should be checked (0 - don't check, 1 - check if current user have required rights)
17//
18// Return value: number of successfully updated news
19//
20function massModifyNews($list, $setValue, $permCheck = true) {
21    global $mysql, $lang, $PFILTERS, $catmap, $userROW;
22
23    // Check if we have anything to update
24    if (!is_array($list))
25        return -1;
26
27    // Check for security token
28    if ($permCheck && (!isset($_REQUEST['token']))||($_REQUEST['token'] != genUToken('admin.news.edit'))) {
29        msg(array("type" => "error", "text" => $lang['error.security.token'], "info" => $lang['error.security.token#desc']));
30        return;
31    }
32
33    // Load permissions
34    $perm = checkPermission(array('plugin' => '#admin', 'item' => 'news'), null, array(
35        'personal.modify',
36        'personal.modify.published',
37        'personal.publish',
38        'personal.unpublish',
39        'personal.delete',
40        'personal.delete.published',
41        'personal.mainpage',
42        'personal.pinned',
43        'personal.customdate',
44        'other.view',
45        'other.modify',
46        'other.modify.published',
47        'other.publish',
48        'other.unpublish',
49        'other.delete',
50        'other.delete.published',
51        'other.html',
52        'other.mainpage',
53        'other.pinned',
54        'other.customdate',
55    ));
56
57
58    $nList = array();
59    $nData = array();
60
61    $results = array();
62
63    if (isset($list['data'])) {
64        $recList = $list['data'];
65    } else if (isset($list['id'])) {
66        $SNQ = array();
67        foreach ($list['id'] as $id)
68            $SNQ [] = db_squote($id);
69
70        $recList = $mysql->select("select * from ".prefix."_news where id in (".join(", ", $SNQ).")");
71    } else {
72        return array();
73    }
74
75    // Scan RECORDS and prepare output
76    foreach ($recList as $rec) {
77        // SKIP records if user has not enougt permissions
78        if ($permCheck) {
79            $isOwn = ($rec['author_id'] == $userROW['id'])?1:0;
80            $permGroupMode = $isOwn?'personal':'other';
81
82            // Manage `PUBLISHED` field
83            $ic = 0;
84            if (isset($setValue['approve'])) {
85                if ((($rec['approve'] == 1)&&($setValue['approve'] != 1) && (!$perm[$permGroupMode.'.unpublish']))||
86                    (($rec['approve'] < 1)&&($setValue['approve'] == 1) && (!$perm[$permGroupMode.'.publish']))) {
87                    $results []= '#'.$rec['id'].' ('.$rec['title'].') - '.$lang['perm.denied'];
88                    continue;
89                }
90                $ic++;
91            }
92
93            // Manage `MAINPAGE` flag
94            if (isset($setValue['mainpage'])) {
95                if (!$perm[$permGroupMode.'.mainpage']) {
96                    $results []= '#'.$rec['id'].' ('.$rec['title'].') - '.$lang['perm.denied'];
97                    continue;
98                }
99                $ic++;
100            }
101
102            // Check if we have other options except MAINPAGE/APPROVE
103            if (count($setValue) > $ic) {
104                if (!$perm[$permGroupMode.'.modify'.(($rec['approve'] == 1)?'.published':'')]) {
105                    $results []= '#'.$rec['id'].' ('.$rec['title'].') - '.$lang['perm.denied'];
106                    continue;
107                }
108            }
109
110//            if (($rec['status'] > 1) && ($rec['author_id'] != $userROW['id']))
111//                continue;
112        }
113        $results []= '#'.$rec['id'].' ('.$rec['title'].') - Ok';
114
115        $nList[]= $rec['id'];
116        $nData[$rec['id']] = $rec;
117    }
118
119    if (!count($nList))
120        return $results;
121
122
123    // Convert $setValue into SQL string
124    $sqllSET = array();
125    foreach ($setValue as $k => $v)
126        $sqllSET[] = $k." = ".db_squote($v);
127
128    $sqlSET = join(", ", $sqllSET);
129
130
131    // Call plugin filters
132    if (is_array($PFILTERS['news']))
133        foreach ($PFILTERS['news'] as $k => $v) { $v->massModifyNews($nList, $setValue, $nData); }
134
135    $mysql->query("UPDATE ".prefix."_news SET $sqlSET WHERE id in (".join(", ", $nList).")");
136
137    // Some activity if we change APPROVE flag for news
138    if (isset($setValue['approve'])) {
139        // Update user's news counters
140        foreach ($nData as $nid => $ndata) {
141            if (($ndata['approve'] == 1) && ($setValue['approve'] != 1)) {
142                $mysql->query("update ".uprefix."_users set news=news-1 where id = ".intval($ndata['author_id']));
143            } else if (($ndata['approve'] != 1) && ($setValue['approve'] == 1)) {
144                $mysql->query("update ".uprefix."_users set news=news+1 where id = ".intval($ndata['author_id']));
145            }
146        }
147
148        // DeApprove news
149        if ($setValue['approve'] < 1) {
150            // Count categories & counters to decrease - we have this news currently in _news_map because this news are marked as published
151            foreach ($mysql->select("select categoryID, count(newsID) as cnt from ".prefix."_news_map where newsID in (".join(", ", $nList).") group by categoryID") as $crec) {
152                $mysql->query("update ".prefix."_category set posts=posts-".intval($crec['cnt'])." where id = ".intval($crec['categoryID']));
153            }
154
155            // Delete news map
156            $mysql->query("delete from ".prefix."_news_map where newsID in (".join(", ", $nList).")");
157        } else if ($setValue['approve'] == 1) {
158            // Approve news
159            $clist = array();
160            foreach ($nData as $nr) {
161                // Skip already published news
162                if ($nr['approve'] == 1) continue;
163
164                // Calculate list
165                foreach (explode(",", $nr['catid']) as $cid) {
166                    if (!isset($catmap[$cid])) continue;
167                    $clist[$cid]++;
168                    $mysql->query("insert into ".prefix."_news_map (newsID, categoryID, dt) values (".intval($nr['id']).", ".intval($cid).", from_unixtime(".(($nr['editdate']>$nr['postdate'])?$nr['editdate']:$nr['postdate'])."))");
169                }
170            }
171            foreach ($clist as $cid => $cv) {
172                $mysql->query("update ".prefix."_category set posts=posts+".intval($cv)." where id = ".intval($cid));
173            }
174        }
175    }
176
177    // Call plugin filters [ NOTIFY ABOUT MODIFICATION ]
178    if (is_array($PFILTERS['news']))
179        foreach ($PFILTERS['news'] as $k => $v) { $v->massModifyNewsNotify($nList, $setValue, $nData); }
180
181    //return count($nList);
182    return $results;
183}
184
185
186//
187// Mass news delete function
188// $list        - array with news identities
189// $permCheck    - flag if permissions should be checked (0 - don't check, 1 - check if current user have required rights)
190//
191// Return value: number of successfully updated news
192//
193function massDeleteNews($list, $permCheck = true) {
194    global $mysql, $lang, $PFILTERS, $userROW;
195
196    $selected_news = $_REQUEST['selected_news'];
197
198    // Check for security token
199    if ($permCheck && (!isset($_REQUEST['token']))||($_REQUEST['token'] != genUToken('admin.news.edit'))) {
200        msg(array("type" => "error", "text" => $lang['error.security.token'], "info" => $lang['error.security.token#desc']));
201        return;
202    }
203
204    if ((!is_array($list))||(!count($list))) {
205        msg(array("type" => "error", "text" => $lang['msge_selectnews'], "info" => $lang['msgi_selectnews']));
206        return;
207    }
208
209    // Load permissions
210    $perm = checkPermission(array('plugin' => '#admin', 'item' => 'news'), null, array(
211        'personal.delete',
212        'personal.delete.published',
213        'other.delete',
214        'other.delete.published',
215    ));
216
217    $results = array();
218
219    // Scan list of news to be deleted
220    foreach ($list as $id) {
221        // Fetch news
222        if (!is_array($nrow = $mysql->record("select * from ".prefix."_news where id = ".db_squote($id)))) {
223            // Skip ID's of non-existent news
224            continue;
225        }
226
227        // Check for permissions
228        $isOwn = ($nrow['author_id'] == $userROW['id'])?1:0;
229        $permGroupMode = $isOwn?'personal':'other';
230
231        if ((!$perm[$permGroupMode.'.delete'.(($nrow['approve'] == 1)?'.published':'')]) && $permCheck) {
232            $results []= '#'.$nrow['id'].' ('.$nrow['title'].') - '.$lang['perm.denied'];
233            continue;
234        }
235
236        if (is_array($PFILTERS['news']))
237            foreach ($PFILTERS['news'] as $k => $v) { $v->deleteNews($nrow['id'], $nrow); }
238
239        // Update counters only if news is published
240        if ($nrow['approve'] == 1) {
241            if ($nrow['catid']) {
242                $oldcatsql = array();
243                foreach(explode(",",$nrow['catid']) as $key) {
244                    $oldcatsql[] = "id = ".db_squote($key);
245                }
246                $mysql->query("update ".prefix."_category set posts=posts-1 where ".implode(" or ",$oldcatsql));
247            }
248
249            // Update user's posts counter
250            if ($nrow['author_id']) {
251                $mysql->query("update ".uprefix."_users set news=news-1 where id=".$nrow['author_id']);
252            }
253        }
254
255        // Delete comments (with updating user's comment counter) [ if plugin comments is installed ]
256        if (getPluginStatusInstalled('comments')) {
257            foreach ($mysql->select("select * from ".prefix."_comments where post=".$nrow['id']) as $crow) {
258                if ($nrow['author_id']) {
259                    $mysql->query("update ".uprefix."_users set com=com-1 where id=".$crow['author_id']);
260                }
261            }
262            $mysql->query("delete from ".prefix."_comments WHERE post=".db_squote($nrow['id']));
263        }
264
265        $mysql->query("delete from ".prefix."_news where id=".db_squote($nrow['id']));
266        $mysql->query("delete from ".prefix."_news_map where newsID = ".db_squote($nrow['id']));
267
268        // Notify plugins about news deletion
269        if (is_array($PFILTERS['news']))
270            foreach ($PFILTERS['news'] as $k => $v) { $v->deleteNewsNotify($nrow['id'], $nrow); }
271
272        // Delete attached news/files if any
273        $fmanager = new file_managment();
274        // ** Files
275        foreach ($mysql->select("select * from ".prefix."_files where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($nrow['id']).")") as $frec) {
276            $fmanager->file_delete(array('type' => 'file', 'id' => $frec['id']));
277        }
278
279        // ** Images
280        foreach ($mysql->select("select * from ".prefix."_images where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($nrow['id']).")") as $frec) {
281            $fmanager->file_delete(array('type' => 'image', 'id' => $frec['id']));
282        }
283
284        $results []= '#'.$nrow['id'].' ('.$nrow['title'].') - Ok';
285    }
286    msg(array("text" => $lang['msgo_deleted'], "info" => join("<br/>\n", $results)));
287}
288
289
290
291
292// Generate backup for table list. If no list is given - backup ALL tables with system prefix
293function dbBackup($fname, $gzmode, $tlist = ''){
294    global $mysql;
295
296    if ($gzmode && (!function_exists('gzopen')))
297        $gzmode = 0;
298
299    if ($gzmode)    $fh = gzopen($fname, "w");
300    else            $fh = fopen($fname, "w");
301
302    if ($fh === false)
303        return 0;
304
305    // Generate a list of tables for backup
306    if (!is_array($tlist)) {
307        $tlist = array();
308
309        foreach ($mysql->select("show tables like '".prefix."_%'") as $tn)
310            $tlist [] = $tn[0];
311    }
312
313    // Now make a header
314    $out  = "# ".str_repeat('=', 60)."\n# Backup file for `Next Generation CMS`\n# ".str_repeat('=', 60)."\n# DATE: ".gmdate("d-m-Y H:i:s", time())." GMT\n# VERSION: ".engineVersion."\n#\n";
315    $out .= "# List of tables for backup: ".join(", ", $tlist)."\n#\n";
316
317    // Write a header
318    if ($gzmode)    gzwrite($fh, $out);
319    else            fwrite($fh, $out);
320
321    // Now, let's scan tables
322    foreach ($tlist as $tname) {
323        // Fetch create syntax for table and after - write table's content
324        if (is_array($csql = $mysql->record("show create table `".$tname."`"))) {
325            $out  = "\n#\n# Table `".$tname."`\n#\n";
326            $out .= "DROP TABLE IF EXISTS `".$tname."`;\n";
327            $out .= $csql[1].";\n";
328
329            if ($gzmode)    gzwrite($fh, $out);
330            else            fwrite($fh, $out);
331
332            // Now let's make content of the table
333            $query = mysql_query("select * from `".$tname."`", $mysql->connect);
334            $rowNo = 0;
335            while ($row = mysql_fetch_row($query)) {
336                $out = "insert into `".$tname."` values (";
337                $rowNo++;
338                $colNo = 0;
339                foreach ($row as $v)
340                    $out .= (($colNo++)?', ':'').db_squote($v);
341                $out .= ");\n";
342
343                if ($gzmode)    gzwrite($fh, $out);
344                else            fwrite($fh, $out);
345            }
346
347            $out = "# Total records: $rowNo\n";
348
349            if ($gzmode)    gzwrite($fh, $out);
350            else            fwrite($fh, $out);
351        } else {
352            $out = "#% Error fetching information for table `$tname`\n";
353
354            if ($gzmode)    gzwrite($fh, $out);
355            else            fwrite($fh, $out);
356        }
357    }
358    if ($gzmode)    gzclose($fh);
359    else            fclose($fh);
360
361    return 1;
362}
363
364
365// ======================================================================================================
366// Add news
367// ======================================================================================================
368// $mode - calling mode
369//    *    'no.meta'    - disable metatags
370//    *    'no.files'    - disable files
371//    *    'no.token'    - do not check for security token
372function addNews($mode = array()){
373    global $mysql, $lang, $userROW, $parse, $PFILTERS, $config, $catz, $catmap;
374
375    // Load required library
376    @include_once root.'includes/classes/upload.class.php';
377
378    // Check for security token
379    if ((!isset($mode['no.token']) || (!$mode['no.token'])) && ((!isset($_REQUEST['token']))||($_REQUEST['token'] != genUToken('admin.news.add')))) {
380        msg(array("type" => "error", "text" => $lang['error.security.token'], "info" => $lang['error.security.token#desc']));
381        return;
382    }
383
384
385    // Load permissions
386    $perm = checkPermission(array('plugin' => '#admin', 'item' => 'news'), null, array(
387        'add',
388        'add.approve',
389        'add.mainpage',
390        'add.pinned',
391        'add.favorite',
392        'add.html',
393        'personal.view',
394        'personal.modify',
395        'personal.modify.published',
396        'personal.publish',
397        'personal.unpublish',
398        'personal.delete',
399        'personal.delete.published',
400        'personal.html',
401        'personal.mainpage',
402        'personal.pinned',
403        'personal.catpinned',
404        'personal.favorite',
405        'personal.setviews',
406        'personal.multicat',
407        'personal.nocat',
408        'personal.customdate',
409        'personal.altname',
410    ));
411
412
413    // Check permissions
414    if (!$perm['add']) {
415        msg(array("type" => "error", "text" => $lang['perm.denied']));
416        return 0;
417    }
418
419
420    $title = $_REQUEST['title'];
421
422    // Fill content
423    $content    = '';
424
425    // Check if EDITOR SPLIT feature is activated
426    if ($config['news.edit.split']) {
427        // Prepare delimiter
428        $ed = '<!--more-->';
429        if ($config['extended_more'] && ($_REQUEST['content_delimiter'] != '')) {
430            // Disable `new line` + protect from XSS
431            $ed = '<!--more="'.str_replace(array("\r", "\n", '"'), '', $_REQUEST['content_delimiter']).'"-->';
432        }
433        $content = $_REQUEST['ng_news_content_short'].(($_REQUEST['ng_news_content_full'] != '')?$ed.$_REQUEST['ng_news_content_full']:'');
434
435    } else {
436        $content = $_REQUEST['ng_news_content'];
437    }
438
439    // Rewrite `\r\n` to `\n`
440    $content = str_replace("\r\n", "\n", $content);
441
442    // Check title
443    if ((!strlen(trim($title))) || ((!strlen(trim($content))) && (!$config['news_without_content']))) {
444        msg(array("type" => "error", "text" => $lang['addnews']['msge_fields'], "info" => $lang['addnews']['msgi_fields']));
445        return 0;
446    }
447
448    $SQL['title'] = $title;
449
450    // Check for dup if alt_name is specified
451    $alt_name = ($perm['personal.altname'] && isset($_REQUEST['alt_name']))?$parse->translit(trim($_REQUEST['alt_name']), 1):'';
452
453
454    if ($alt_name) {
455        if ( is_array($mysql->record("select id from ".prefix."_news where alt_name = ".db_squote($alt_name)." limit 1")) ) {
456            msg(array("type" => "error", "text" => $lang['addnews']['msge_alt_name'], "info" => $lang['addnews']['msgi_alt_name']));
457            return 0;
458        }
459        $SQL['alt_name'] = $alt_name;
460    } else {
461        // Generate uniq alt_name if no alt_name specified
462        $alt_name = strtolower($parse->translit(trim($title), 1));
463        // Make a conversion:
464        // * '.'  to '_'
465        // * '__' to '_' (several to one)
466        // * Delete leading/finishing '_'
467        $alt_name = preg_replace(array('/\./', '/(_{2,20})/', '/^(_+)/', '/(_+)$/'), array('_', '_'), $alt_name);
468
469        // Make alt_name equal to '_' if it appear to be blank after conversion
470        if ($alt_name == '') $alt_name = '_';
471
472        $i = '';
473        while ( is_array($mysql->record("select id from ".prefix."_news where alt_name = ".db_squote($alt_name.$i)." limit 1")) ) {
474            $i++;
475        }
476        $SQL['alt_name'] = $alt_name.$i;
477    }
478
479    // Custom date[ only while adding via admin panel ]
480    if (isset($_REQUEST['customdate']) && $_REQUEST['customdate'] && $perm['personal.customdate']) {
481        $SQL['postdate'] = mktime(intval($_REQUEST['c_hour']), intval($_REQUEST['c_minute']), 0, intval($_REQUEST['c_month']), intval($_REQUEST['c_day']), intval($_REQUEST['c_year'])) + ($config['date_adjust'] * 60);
482    } else {
483        $SQL['postdate'] = time() + ($config['date_adjust'] * 60);
484    }
485
486    $SQL['editdate'] = $SQL['postdate'];
487
488    // Fetch MASTER provided categories
489    $catids = array ();
490    if (intval($_POST['category']) && isset($catmap[intval($_POST['category'])])) {
491        $catids[intval($_POST['category'])] = 1;
492    }
493
494    // Fetch ADDITIONAL provided categories [if allowed]
495    if ($perm['personal.multicat']) {
496        foreach ($_POST as $k => $v) {
497            if (preg_match('#^category_(\d+)$#', $k, $match) && $v && isset($catmap[intval($match[1])]))
498                $catids[$match[1]] = 1;
499        }
500    }
501
502    // Check if no categories specified and user can post news without categories
503    if ((!count($catids)) && (!$perm['personal.nocat'])) {
504        msg(array("type" => "error", "text" => $lang['addnews']['error.nocat'], "info" => $lang['addnews']['error.nocat#desc']));
505        return 0;
506    }
507
508
509    // Metatags (only for adding via admin panel)
510    if ($config['meta'] && (!isset($mode['no.meta']) || !$mode['no.meta'])) {
511        $SQL['description']    = $_REQUEST['description'];
512        $SQL['keywords']    = $_REQUEST['keywords'];
513    }
514
515    $SQL['author']        = $userROW['name'];
516    $SQL['author_id']    = $userROW['id'];
517    $SQL['catid']        = implode(",", array_keys($catids));
518
519    // Variable FLAGS is a bit-variable:
520    // 0 = RAW mode        [if set, no conversion "\n" => "<br />" will be done]
521    // 1 = HTML enable    [if set, HTML codes may be used in news]
522
523    if ($perm['personal.html']) {
524        $SQL['flags']    =    ($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0);
525    } else {
526        $SQL['flags']    =    0;
527    }
528
529    $SQL['mainpage']    = intval($_REQUEST['mainpage']) && $perm['personal.mainpage'];
530    $SQL['favorite']    = intval($_REQUEST['favorite']) && $perm['personal.favorite'];
531    $SQL['pinned']        = intval($_REQUEST['pinned']) && $perm['personal.pinned'];
532    $SQL['catpinned']    = intval($_REQUEST['catpinned']) && $perm['personal.catpinned'];
533
534    switch (intval($_REQUEST['approve'])) {
535        case -1:    $SQL['approve'] = -1;                                break;
536        case 0:        $SQL['approve'] = 0;                                break;
537        case 1:        $SQL['approve'] = $perm['personal.publish']?1:0;    break;
538        default:    $SQL['approve']    = 0;
539    }
540
541    $SQL['content']        = $content;
542
543    exec_acts('addnews');
544
545    $pluginNoError = 1;
546    if (is_array($PFILTERS['news']))
547        foreach ($PFILTERS['news'] as $k => $v) {
548            if (!($pluginNoError = $v->addNews($tvars, $SQL))) {
549                msg(array("type" => "error", "text" => str_replace('{plugin}', $k, $lang['addnews']['msge_pluginlock'])));
550                break;
551            }
552        }
553
554    if (!$pluginNoError) {
555        return 0;
556    }
557
558    $vnames = array(); $vparams = array();
559    foreach ($SQL as $k => $v) { $vnames[]  = $k; $vparams[] = db_squote($v); }
560
561    $mysql->query("insert into ".prefix."_news (".implode(",",$vnames).") values (".implode(",",$vparams).")");
562    $id = $mysql->result("SELECT LAST_INSERT_ID() as id");
563
564    // Update category / user posts counter [ ONLY if news is approved ]
565    if ($SQL['approve'] == 1) {
566        if (count($catids)) {
567            $mysql->query("update ".prefix."_category set posts=posts+1 where id in (".implode(", ",array_keys($catids)).")");
568            foreach (array_keys($catids) as $catid) {
569                $mysql->query("insert into ".prefix."_news_map (newsID, categoryID, dt) values (".db_squote($id).", ".db_squote($catid).", now())");
570            }
571        }
572        $mysql->query("update ".uprefix."_users set news=news+1 where id=".$SQL['author_id']);
573    }
574
575    // Attaches are available only for admin panel
576    if (!$mode['no.files']) {
577
578        // Now let's manage attached files
579        $fmanager = new file_managment();
580
581        $flagUpdateAttachCount = false;
582
583        // Delete files (if needed)
584        foreach ($_POST as $k => $v) {
585            if (preg_match('#^delfile_(\d+)$#', $k, $match)) {
586                $fmanager->file_delete(array('type' => 'file', 'id' => $match[1]));
587                $flagUpdateAttachCount = true;
588            }
589        }
590
591        //print "<pre>".var_export($_FILES, true)."</pre>";
592        // PREPARE a list for upload
593        if (is_array($_FILES['userfile']['name']))
594            foreach($_FILES['userfile']['name'] as $i => $v) {
595                if ($v == '')
596                    continue;
597
598                $flagUpdateAttachCount = true;
599                //
600                $up = $fmanager->file_upload(array('dsn' => true, 'linked_ds' => 1, 'linked_id' => $id, 'type' => 'file', 'http_var' => 'userfile', 'http_varnum' => $i));
601                //print "OUT: <pre>".var_export($up, true)."</pre>";
602                if (!is_array($up)) {
603                    // Error uploading file
604                    // ... show error message ...
605                }
606            }
607    }
608
609    // Notify plugins about adding new news
610    if (is_array($PFILTERS['news']))
611        foreach ($PFILTERS['news'] as $k => $v) { $v->addNewsNotify($tvars, $SQL, $id); }
612
613    // Update attach count if we need this
614    $numFiles = $mysql->result("select count(*) as cnt from ".prefix."_files where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($id).")");
615    if ($numFiles) {
616        $mysql->query("update ".prefix."_news set num_files = ".intval($numFiles)." where id = ".db_squote($id));
617    }
618
619    $numImages = $mysql->result("select count(*) as cnt from ".prefix."_images where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($id).")");
620    if ($numImages) {
621        $mysql->query("update ".prefix."_news set num_images = ".intval($numImages)." where id = ".db_squote($id));
622    }
623
624    exec_acts('addnews_', $id);
625    msg(array("text" => $lang['addnews']['msgo_added'], "info" => sprintf($lang['addnews']['msgi_added'], admin_url.'/admin.php?mod=news&action=edit&id='.$id, admin_url.'/admin.php?mod=news')));
626
627    return 1;
628}
629
630
631// ======================================================================================================
632// Edit news
633// ======================================================================================================
634// $mode - calling mode [ we can disable processing of some features/functions ]
635//    *    'no.meta'    - disable changing metatags
636//    *    'no.files'    - disable updating files
637//    *    'no.token'    - do not check for security token
638function editNews($mode = array()) {
639    global $lang, $parse, $mysql, $config, $PFILTERS, $userROW, $catz, $catmap;
640
641    // Load permissions
642    $perm = checkPermission(array('plugin' => '#admin', 'item' => 'news'), null, array(
643        'personal.view',
644        'personal.modify',
645        'personal.modify.published',
646        'personal.publish',
647        'personal.unpublish',
648        'personal.delete',
649        'personal.delete.published',
650        'personal.html',
651        'personal.mainpage',
652        'personal.pinned',
653        'personal.catpinned',
654        'personal.favorite',
655        'personal.setviews',
656        'personal.multicat',
657        'personal.nocat',
658        'personal.customdate',
659        'personal.altname',
660        'other.view',
661        'other.modify',
662        'other.modify.published',
663        'other.publish',
664        'other.unpublish',
665        'other.delete',
666        'other.delete.published',
667        'other.html',
668        'other.mainpage',
669        'other.pinned',
670        'other.catpinned',
671        'other.favorite',
672        'other.setviews',
673        'other.multicat',
674        'other.nocat',
675        'other.customdate',
676        'other.altname',
677    ));
678
679    $id            = $_REQUEST['id'];
680
681    // Check for security token
682    if ((!isset($mode['no.token']) || (!$mode['no.token'])) && ((!isset($_REQUEST['token']))||($_REQUEST['token'] != genUToken('admin.news.edit')))) {
683        msg(array("type" => "error", "text" => $lang['error.security.token'], "info" => $lang['error.security.token#desc']));
684        return;
685    }
686
687
688    // Try to find news that we're trying to edit
689    if (!is_array($row = $mysql->record("select * from ".prefix."_news where id=".db_squote($id)))) {
690        msg(array("type" => "error", "text" => $lang['editnews']['msge_not_found']));
691        return;
692    }
693
694
695    $isOwn = ($row['author_id'] == $userROW['id'])?1:0;
696    $permGroupMode = $isOwn?'personal':'other';
697
698
699    // Check permissions
700    if (!$perm[$permGroupMode.'.modify'.(($row['approve'] == 1)?'.published':'')]) {
701        msg(array("type" => "error", "text" => $lang['perm.denied']));
702        return;
703    }
704
705
706    // Variable FLAGS is a bit-variable:
707    // 0 = RAW mode        [if set, no conversion "\n" => "<br />" will be done]
708    // 1 = HTML enable    [if set, HTML codes may be used in news]
709    $SQL = array();
710
711    $SQL['flags']    = ($perm[$permGroupMode.'.html'])?(($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0)):0;
712
713    $title        = $_REQUEST['title'];
714
715    // Fill content
716    $content    = '';
717
718    // Check if EDITOR SPLIT feature is activated
719    if ($config['news.edit.split']) {
720        // Prepare delimiter
721        $ed = '<!--more-->';
722        if ($_REQUEST['content_delimiter'] != '') {
723            // Disable `new line` + protect from XSS
724            $ed = '<!--more="'.str_replace(array("\r", "\n", '"'), '', $_REQUEST['content_delimiter']).'"-->';
725        }
726        $content = $_REQUEST['ng_news_content_short'].(($_REQUEST['ng_news_content_full'] != '')?$ed.$_REQUEST['ng_news_content_full']:'');
727
728    } else {
729        $content = $_REQUEST['ng_news_content'];
730    }
731
732    // Rewrite `\r\n` to `\n`
733    $content = str_replace("\r\n", "\n", $content);
734
735
736    // Check if we have content
737    if ((!strlen(trim($title))) || ((!strlen(trim($content))) && (!$config['news_without_content']))) {
738        msg(array("type" => "error", "text" => $lang['msge_fields'], "info" => $lang['msgi_fields']));
739        return;
740    }
741
742    // Manage alt name
743    if ($perm[$permGroupMode.'.altname'] && isset($_REQUEST['alt_name'])) {
744        $alt_name    = $_REQUEST['alt_name'];
745        // Check if alt name should be generated again
746        if (trim($alt_name) == '') {
747            $alt_name = strtolower($parse->translit(trim($title), 1));
748            // Make a conversion:
749            // * '.'  to '_'
750            // * '__' to '_' (several to one)
751            // * Delete leading/finishing '_'
752            $alt_name = preg_replace(array('/\./', '/(_{2,20})/', '/^(_+)/', '/(_+)$/'), array('_', '_'), $alt_name);
753
754            // Make alt_name equal to '_' if it appear to be blank after conversion
755            if ($alt_name == '') $alt_name = '_';
756
757            $i = '';
758            while ( is_array($mysql->record("select id from ".prefix."_news where alt_name = ".db_squote($alt_name.$i)." limit 1")) ) {
759                $i++;
760            }
761            $alt_name = $alt_name.$i;
762        }
763
764        // Check if alt name was changed
765        if ($alt_name != $row['alt_name']) {
766            // Check for allowed chars in alt name
767            if (!$parse->nameCheck($alt_name)) {
768                msg(array("type" => "error", "text" => $lang['editnews']['err.altname.wrong']));
769                return;
770            }
771        }
772
773        // Check if we try to use duplicate alt_name
774        if (is_array($mysql->record("select * from ".prefix."_news where alt_name=".db_squote($alt_name)." and id <> ".db_squote($row['id'])." limit 1"))) {
775            msg(array("type" => "error", "text" => $lang['editnews']['err.altname.dup']));
776            return;
777        }
778    } else {
779        // Alt name was not modified or modification is not allowed
780        $alt_name = $row['alt_name'];
781    }
782
783    // Generate SQL old cats list
784    $oldcatids = array();
785    foreach (explode(",", $row['catid']) as $cat)
786        if (preg_match('#^(\d+)$#', trim($cat), $cmatch))
787            $oldcatids[$cmatch[1]] = 1;
788
789    // Fetch MASTER provided categories
790    $catids = array ();
791    if (intval($_POST['category']) && isset($catmap[intval($_POST['category'])])) {
792        $catids[intval($_POST['category'])] = 1;
793    }
794
795    // Fetch ADDITIONAL provided categories [if allowed]
796    if ($perm[$permGroupMode.'.multicat']) {
797        foreach ($_POST as $k => $v) {
798            if (preg_match('#^category_(\d+)$#', $k, $match) && $v && isset($catmap[intval($match[1])]))
799                $catids[$match[1]] = 1;
800        }
801    }
802
803    // Check if no categories specified and user can post news without categories
804    if ((!count($catids)) && (!$perm[$permGroupMode.'.nocat'])) {
805        msg(array("type" => "error", "text" => $lang['editnews']['error.nocat'], "info" => $lang['addnews']['error.nocat#desc']));
806        return 0;
807    }
808
809    if ($config['meta'] && (!isset($mode['no.meta']) || !$mode['no.meta'])) {
810        $SQL['description'] = $_REQUEST['description'];
811        $SQL['keywords']    = $_REQUEST['keywords'];
812    } else {
813        $SQL['description'] = $row['description'];
814        $SQL['keywords']    = $row['keywords'];
815    }
816
817    if ($perm[$permGroupMode.'.customdate']) {
818        if ($_REQUEST['setdate_custom']) {
819            $SQL['postdate'] = mktime(intval($_REQUEST['c_hour']), intval($_REQUEST['c_minute']), 0, intval($_REQUEST['c_month']), intval($_REQUEST['c_day']), intval($_REQUEST['c_year'])) + ($config['date_adjust'] * 60);
820        } else if ($_REQUEST['setdate_current']) {
821            $SQL['postdate'] = time() + ($config['date_adjust'] * 60);
822        }
823    }
824
825    $SQL['title']     = $title;
826    $SQL['content']   = $content;
827
828    // Check if user can modify altname
829    if ($perm[$permGroupMode.'.altname']) {
830        $SQL['alt_name']  = $alt_name;
831    } else {
832        $SQL['alt_name']  = $row['alt_name'];
833    }
834    $SQL['editdate']  = time();
835    $SQL['catid']     = implode(",", array_keys($catids));
836
837    // Change this parameters if user have enough access level
838    $SQL['mainpage']    = ($perm[$permGroupMode.'.mainpage']    && intval($_REQUEST['mainpage']))?1:0;
839    $SQL['pinned']        = ($perm[$permGroupMode.'.pinned']        && intval($_REQUEST['pinned']))?1:0;
840    $SQL['catpinned']    = ($perm[$permGroupMode.'.catpinned']    && intval($_REQUEST['catpinned']))?1:0;
841    $SQL['favorite']    = ($perm[$permGroupMode.'.favorite']    && intval($_REQUEST['favorite']))?1:0;
842
843    switch (intval($_REQUEST['approve'])) {
844        case -1:    $SQL['approve'] = -1;                                break;
845        case 0:        $SQL['approve'] = 0;                                break;
846        case 1:        $SQL['approve'] = (($row['approve'] == 1)||(($row['approve'] < 1) && ($perm[$permGroupMode.'.publish'])))?1:0;
847            break;
848        default:    $SQL['approve']    = 0;
849    }
850
851
852    if ($perm[$permGroupMode.'.setviews'] && $_REQUEST['setViews']) {
853        $SQL['views'] = intval($_REQUEST['views']);
854    }
855
856
857    // Load list of attached images/files
858    $row['#files']    = $mysql->select("select *, date_format(from_unixtime(date), '%d.%m.%Y') as date from ".prefix."_files where (linked_ds = 1) and (linked_id = ".db_squote($row['id']).')', 1);
859    $row['#images']    = $mysql->select("select *, date_format(from_unixtime(date), '%d.%m.%Y') as date from ".prefix."_images where (linked_ds = 1) and (linked_id = ".db_squote($row['id']).')', 1);
860
861    exec_acts('editnews', $id);
862
863    $pluginNoError = 1;
864    if (is_array($PFILTERS['news']))
865        foreach ($PFILTERS['news'] as $k => $v) {
866            if (!($pluginNoError = $v->editNews($id, $row, $SQL, $tvars))) {
867                msg(array("type" => "error", "text" => str_replace('{plugin}', $k, $lang['editnews']['msge_pluginlock'])));
868                break;
869            }
870        }
871
872    if (!$pluginNoError) {
873        return;
874    }
875
876    $SQLparams = array();
877    foreach ($SQL as $k => $v) { $SQLparams[] = $k.' = '.db_squote($v); }
878
879    $mysql->query("update ".prefix."_news set ".implode(", ",$SQLparams)." where id = ".db_squote($id));
880
881    // Update category posts counters
882    if (($row['approve'] == 1) && sizeof($oldcatids)) {
883        $mysql->query("update ".prefix."_category set posts=posts-1 where id in (".implode(",",array_keys($oldcatids)).")");
884    }
885
886    $mysql->query("delete from ".prefix."_news_map where newsID = ".db_squote($id));
887
888    // Check if we need to update user's counters [ only if news was or will be published ]
889    if (($row['approve'] != $SQL['approve']) && (($row['approve'] == 1)||($SQL['approve'] == 1))) {
890        $mysql->query("update ".uprefix."_users set news=news".(($row['approve'] == 1)?'-':'+')."1 where id=".$row['author_id']);
891    }
892
893    if ($SQL['approve'] == 1) {
894        if (sizeof($catids)) {
895            $mysql->query("update ".prefix."_category set posts=posts+1 where id in (".implode(",",array_keys($catids)).")");
896            foreach (array_keys($catids) as $catid) {
897                $mysql->query("insert into ".prefix."_news_map (newsID, categoryID, dt) values (".db_squote($id).", ".db_squote($catid).", from_unixtime(".intval($SQL['editdate'])."))");
898            }
899        }
900    }
901
902
903    // Skip file processing (if requested)
904    if (!(isset($params['no.files']) && $params['no.files'])) {
905
906        // Now let's manage attached files
907        $fmanager = new file_managment();
908
909        $flagUpdateAttachCount = false;
910
911        // Delete files (if needed)
912        foreach ($_POST as $k => $v) {
913            if (preg_match('#^delfile_(\d+)$#', $k, $match)) {
914                $fmanager->file_delete(array('type' => 'file', 'id' => $match[1]));
915                $flagUpdateAttachCount = true;
916            }
917        }
918
919        // PREPARE a list for upload
920        if (is_array($_FILES['userfile']['name']))
921            foreach($_FILES['userfile']['name'] as $i => $v) {
922                if ($v == '')
923                    continue;
924
925                $flagUpdateAttachCount = true;
926                //
927                $up = $fmanager->file_upload(array('dsn' => true, 'linked_ds' => 1, 'linked_id' => $id, 'type' => 'file', 'http_var' => 'userfile', 'http_varnum' => $i));
928                //print "OUT: <pre>".var_export($up, true)."</pre>";
929                if (!is_array($up)) {
930                    // Error uploading file
931                    // ... show error message ...
932                }
933
934            }
935    }
936
937
938    // Notify plugins about news edit completion
939    if (is_array($PFILTERS['news']))
940        foreach ($PFILTERS['news'] as $k => $v) { $v->editNewsNotify($id, $row, $SQL, $tvars); }
941
942    // Update attach count if we need this
943    $numFiles    = $mysql->result("select count(*) as cnt from ".prefix."_files where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($id).")");
944    if ($numFiles != $row['num_files']) {
945        $mysql->query("update ".prefix."_news set num_files = ".intval($numFiles)." where id = ".db_squote($id));
946    }
947
948    $numImages    = $mysql->result("select count(*) as cnt from ".prefix."_images where (storage=1) and (linked_ds=1) and (linked_id=".db_squote($id).")");
949    if ($numImages != $row['num_images']) {
950        $mysql->query("update ".prefix."_news set num_images = ".intval($numImages)." where id = ".db_squote($id));
951    }
952
953    // Show link to the news if it's published
954    if ($row['approve']) {
955        $nlink = newsGenerateLink($row, false, 0, true);
956        msg(array("text" => $lang['editnews']['msgo_edited'], "info" => str_replace('{link}', $nlink, $lang['msgo_edited#link'])));
957
958    } else {
959        msg(array("text" => $lang['editnews']['msgo_edited']));
960    }
961}
962
963
964
965function admcookie_get(){
966    if (isset($_COOKIE['ng_adm']) && is_array($x = unserialize($_COOKIE['ng_adm'])))
967        return $x;
968
969    return array();
970}
971
972function admcookie_set($x = array()) {
973    return setcookie('ng_adm', serialize($x), time() + 365*86400);
974    return setcookie('ng_adm', serialize($x), time() + 365*86400);
975}
976
977
978function showPreview() {
979    global $userROW, $EXTRA_CSS, $EXTRA_HTML_VARS, $PFILTERS, $tpl, $parse, $mysql, $config, $catmap;
980
981    $SQL = array( 'id' => -1 );
982    // ��������� ������ ���� ������� ������� ���������� �� ����������� �������.
983    // ��������� ��������������� ����
984    if ($_REQUEST['customdate']) {
985        $SQL['postdate'] = mktime(intval($_REQUEST['c_hour']), intval($_REQUEST['c_minute']), 0, intval($_REQUEST['c_month']), intval($_REQUEST['c_day']), intval($_REQUEST['c_year'])) + ($config['date_adjust'] * 60);
986    } else {
987        $SQL['postdate'] = time() + ($config['date_adjust'] * 60);
988    }
989    $SQL['title'] = $_REQUEST['title'];
990    $SQL['alt_name'] = $parse->translit(trim($_REQUEST['alt_name']?$_REQUEST['alt_name']:$_REQUEST['title']));
991
992    // Fetch MASTER provided categories
993    $catids = array ();
994    if (intval($_POST['category']) && isset($catmap[intval($_POST['category'])])) {
995        $catids[intval($_POST['category'])] = 1;
996    }
997
998    // Fetch ADDITIONAL provided categories
999    foreach ($_POST as $k => $v) {
1000        if (preg_match('#^category_(\d+)$#', $k, $match) && $v && isset($catmap[intval($_POST['category'])]))
1001            $catids[$match[1]] = 1;
1002    }
1003
1004
1005    $SQL['author']        = $userROW['name'];
1006    $SQL['author_id']    = $userROW['id'];
1007    $SQL['catid']        = implode(",", array_keys($catids));
1008    $SQL['allow_com']    = $_REQUEST['allow_com'];
1009
1010    // Variable FLAGS is a bit-variable:
1011    // 0 = RAW mode        [if set, no conversion "\n" => "<br />" will be done]
1012    // 1 = HTML enable    [if set, HTML codes may be used in news]
1013
1014    $SQL['flags'] = 0;
1015    switch ($userROW['status']) {
1016        case 1:        // admin can do anything
1017            $SQL['flags']    =    ($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0);
1018            break;
1019
1020        case 2:        // Editor. Check if we have permissions
1021            if (!$config['htmlsecure_2'])
1022                $SQL['flags']    =    ($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0);
1023            break;
1024
1025        case 3:        // Journalists. Check if we have permissions
1026            if (!$config['htmlsecure_3'])
1027                $SQL['flags']    =    ($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0);
1028            break;
1029
1030        case 4:        // Commentors. Check if we have permissions
1031            if (!$config['htmlsecure_4'])
1032                $SQL['flags']    =    ($_REQUEST['flag_RAW']?1:0) + ($_REQUEST['flag_HTML']?2:0);
1033            break;
1034    }
1035
1036    // This actions are allowed only for admins & Edtiors
1037    if (($userROW['status'] == 1)||($userROW['status'] == 2)) {
1038        $SQL['mainpage']    = $_REQUEST['mainpage'];
1039        $SQL['approve']        = $_REQUEST['approve'];
1040        $SQL['favorite']    = $_REQUEST['favorite'];
1041        $SQL['pinned']        = $_REQUEST['pinned'];
1042    }
1043
1044    // Fill content
1045    $content    = '';
1046
1047    // Check if EDITOR SPLIT feature is activated
1048    if ($config['news.edit.split']) {
1049        // Prepare delimiter
1050        $ed = '<!--more-->';
1051        if ($_REQUEST['content_delimiter'] != '') {
1052            // Disable `new line` + protect from XSS
1053            $ed = '<!--more="'.str_replace(array("\r", "\n", '"'), '', $_REQUEST['content_delimiter']).'"-->';
1054        }
1055        $content = $_REQUEST['ng_news_content_short'].(($_REQUEST['ng_news_content_full'] != '')?$ed.$_REQUEST['ng_news_content_full']:'');
1056
1057    } else {
1058        $content = $_REQUEST['ng_news_content'];
1059    }
1060
1061    // Rewrite `\r\n` to `\n`
1062    $content = str_replace("\r\n", "\n", $content);
1063
1064    $SQL['content']        = $content;
1065
1066    // Process plugin variables to make proper SQL filling
1067    $tvx = array();
1068    if (is_array($PFILTERS['news']))
1069        foreach ($PFILTERS['news'] as $k => $v) { $v->editNews(-1, $SQL, $SQL, $tvx); }
1070
1071    $tvx = array();
1072    $tvx['vars']['short'] = news_showone(-1, '', array('emulate' => $SQL, 'style' => 'short'));
1073    $tvx['vars']['full']  = news_showone(-1, '', array('emulate' => $SQL, 'style' => 'full'));
1074
1075    // Fill extra CSS links
1076    foreach ($EXTRA_CSS as $css => $null)
1077        $EXTRA_HTML_VARS[] = array('type' => 'css', 'data' => $css);
1078
1079    // Generate metatags
1080    $EXTRA_HTML_VARS[] = array('type' => 'plain', 'data' => GetMetatags());
1081
1082    $txv['vars']['htmlvars'] = '';
1083    // Fill additional HTML vars
1084    $htmlrow = array();
1085    $dupCheck = array();
1086    foreach ($EXTRA_HTML_VARS as $htmlvar) {
1087        if (in_array($htmlvar['data'], $dupCheck))
1088            continue;
1089        $dupCheck[] = $htmlvar['data'];
1090        switch ($htmlvar['type']) {
1091            case 'css'    :     $htmlrow[] = "<link href=\"".$htmlvar['data']."\" rel=\"stylesheet\" type=\"text/css\" />";
1092                            break;
1093            case 'js'    :    $htmlrow[] = "<script type=\"text/javascript\" src=\"".$htmlvar['data']."\"></script>";
1094                            break;
1095            case 'rss'    :    $htmlrow[] = "<link href=\"".$htmlvar['data']."\" rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" />";
1096                            break;
1097            case 'plain':    $htmlrow[] = $htmlvar['data'];
1098                break;
1099        }
1100    }
1101
1102    if (count($htmlrow))
1103        $tvx['vars']['htmlvars'] = join("\n",$htmlrow);
1104
1105    $tvx['vars']['extracss'] = '';
1106
1107    $tpl -> template('preview', tpl_actions);
1108    $tpl -> vars('preview', $tvx);
1109    echo $tpl -> show('preview');
1110}
Note: See TracBrowser for help on using the browser.