Dotclear

source: inc/core/class.dc.core.php @ 2682:cac55fdd7178

Revision 2682:cac55fdd7178, 38.3 KB checked in by Nicolas <nikrou77@…>, 12 years ago (diff)

Addresses #1896. Multiple editors.
Fix issue when no editor is activated or when choosen editor has been deactivated.

RevLine 
[0]1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
[2682]6# Copyright (c) 2003-2014 Olivier Meunier & Association Dotclear
[0]7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14/**
15@defgroup DC_CORE Dotclear Core Classes
16*/
17
18/**
19@ingroup DC_CORE
20@nosubgrouping
21@brief Dotclear core class
22
23True to its name dcCore is the core of Dotclear. It handles everything related
24to blogs, database connection, plugins...
25*/
26class dcCore
27{
28     public $con;        ///< <b>connection</b>        Database connection object
[407]29     public $prefix;          ///< <b>string</b>            Database tables prefix
[0]30     public $blog;       ///< <b>dcBlog</b>            dcBlog object
31     public $error;      ///< <b>dcError</b>           dcError object
32     public $auth;       ///< <b>dcAuth</b>            dcAuth object
33     public $session;    ///< <b>sessionDB</b>         sessionDB object
34     public $url;        ///< <b>urlHandler</b>        urlHandler object
35     public $wiki2xhtml; ///< <b>wiki2xhtml</b>        wiki2xhtml object
36     public $plugins;    ///< <b>dcModules</b>         dcModules object
37     public $media;      ///< <b>dcMedia</b>           dcMedia object
[407]38     public $postmedia;  ///< <b>dcPostMedia</b>       dcPostMedia object
39     public $rest;       ///< <b>dcRestServer</b> dcRestServer object
[0]40     public $log;        ///< <b>dcLog</b>             dcLog object
[2595]41     public $stime;      ///< <b>float</b>             starting time
[2566]42
[0]43     private $versions = null;
44     private $formaters = array();
45     private $behaviors = array();
46     private $post_types = array();
[2566]47
[0]48     /**
49     dcCore constructor inits everything related to Dotclear. It takes arguments
50     to init database connection.
[2566]51
[0]52     @param    driver    <b>string</b>  Database driver name
53     @param    host      <b>string</b>  Database hostname
54     @param    db        <b>string</b>  Database name
55     @param    user      <b>string</b>  Database username
56     @param    password  <b>string</b>  Database password
57     @param    prefix    <b>string</b>  DotClear tables prefix
58     @param    persist   <b>boolean</b> Persistent database connection
59     */
60     public function __construct($driver, $host, $db, $user, $password, $prefix, $persist)
61     {
[2595]62          if (defined('DC_START_TIME')) {
63               $this->stime=DC_START_TIME;
64          } else {
65               $this->stime = microtime(true);
66          }
67
[0]68          $this->con = dbLayer::init($driver,$host,$db,$user,$password,$persist);
[2566]69
[0]70          # define weak_locks for mysql
71          if ($this->con instanceof mysqlConnection) {
72               mysqlConnection::$weak_locks = true;
[1743]73          } elseif ($this->con instanceof mysqliConnection) {
74               mysqliConnection::$weak_locks = true;
[0]75          }
[2566]76
[331]77          # define searchpath for postgresql
78          if ($this->con instanceof pgsqlConnection)
79          {
80               $searchpath = explode ('.',$prefix,2);
81               if (count($searchpath) > 1)
82               {
83                    $prefix = $searchpath[1];
84                    $sql = 'SET search_path TO '.$searchpath[0].',public;';
85                    $this->con->execute($sql);
86               }
87          }
[2566]88
[0]89          $this->prefix = $prefix;
[2566]90
[0]91          $this->error = new dcError();
92          $this->auth = $this->authInstance();
93          $this->session = new sessionDB($this->con,$this->prefix.'session',DC_SESSION_NAME,'',null,DC_ADMIN_SSL);
94          $this->url = new dcUrlHandlers();
[2566]95
[2492]96          $this->plugins = new dcPlugins($this);
[2566]97
[0]98          $this->rest = new dcRestServer($this);
[2566]99
[0]100          $this->meta = new dcMeta($this);
[2566]101
[0]102          $this->log = new dcLog($this);
103     }
[2566]104
[0]105     private function authInstance()
106     {
107          # You can set DC_AUTH_CLASS to whatever you want.
108          # Your new class *should* inherits dcAuth.
109          if (!defined('DC_AUTH_CLASS')) {
110               $c = 'dcAuth';
111          } else {
112               $c = DC_AUTH_CLASS;
113          }
[2566]114
[0]115          if (!class_exists($c)) {
116               throw new Exception('Authentication class '.$c.' does not exist.');
117          }
[2566]118
[0]119          if ($c != 'dcAuth' && !is_subclass_of($c,'dcAuth')) {
120               throw new Exception('Authentication class '.$c.' does not inherit dcAuth.');
121          }
[2566]122
[0]123          return new $c($this);
124     }
[2566]125
126
[0]127     /// @name Blog init methods
128     //@{
129     /**
130     Sets a blog to use in <var>blog</var> property.
[2566]131
[0]132     @param    id        <b>string</b>       Blog ID
133     */
134     public function setBlog($id)
135     {
136          $this->blog = new dcBlog($this, $id);
137     }
[2566]138
[0]139     /**
140     Unsets <var>blog</var> property.
141     */
142     public function unsetBlog()
143     {
144          $this->blog = null;
145     }
146     //@}
[2566]147
148
[0]149     /// @name Blog status methods
150     //@{
151     /**
152     Returns an array of available blog status codes and names.
[2566]153
[0]154     @return   <b>array</b> Simple array with codes in keys and names in value
155     */
156     public function getAllBlogStatus()
157     {
158          return array(
159               1 => __('online'),
160               0 => __('offline'),
161               -1 => __('removed')
162          );
163     }
[2566]164
[0]165     /**
166     Returns a blog status name given to a code. This is intended to be
167     human-readable and will be translated, so never use it for tests.
168     If status code does not exist, returns <i>offline</i>.
[2566]169
[0]170     @param    s    <b>integer</b> Status code
171     @return   <b>string</b> Blog status name
172     */
173     public function getBlogStatus($s)
174     {
175          $r = $this->getAllBlogStatus();
176          if (isset($r[$s])) {
177               return $r[$s];
178          }
179          return $r[0];
180     }
181     //@}
[2566]182
[0]183     /// @name Admin nonce secret methods
184     //@{
[2566]185
[0]186     public function getNonce()
187     {
188          return crypt::hmac(DC_MASTER_KEY,session_id());
189     }
[2566]190
[0]191     public function checkNonce($secret)
192     {
193          if (!preg_match('/^([0-9a-f]{40,})$/i',$secret)) {
194               return false;
195          }
[2566]196
[0]197          return $secret == crypt::hmac(DC_MASTER_KEY,session_id());
198     }
[2566]199
[0]200     public function formNonce()
201     {
202          if (!session_id()) {
203               return;
204          }
[2566]205
[0]206          return form::hidden(array('xd_check'),$this->getNonce());
207     }
208     //@}
[2566]209
[2679]210     /// @name Text Formatters methods
211     //@{
212     /**
213     Adds a new text formater which will call the function <var>$func</var> to
214     transform text. The function must be a valid callback and takes one
215     argument: the string to transform. It returns the transformed string.
216
217     @param    editor_id <b>string</b>  Editor id (dcLegacyEditor, dcCKEditor, ...)
218     @param    name      <b>string</b>  Formater name
219     @param    func      <b>callback</b>     Function to use, must be a valid and callable callback
220     */
221     public function addEditorFormater($editor_id,$name,$func)
222     {
223          if (is_callable($func)) {
224               $this->formaters[$editor_id][$name] = $func;
225          }
226     }
[2566]227
[0]228     /// @name Text Formatters methods
229     //@{
230     /**
231     Adds a new text formater which will call the function <var>$func</var> to
232     transform text. The function must be a valid callback and takes one
233     argument: the string to transform. It returns the transformed string.
[2566]234
[0]235     @param    name      <b>string</b>       Formater name
236     @param    func      <b>callback</b>     Function to use, must be a valid and callable callback
237     */
238     public function addFormater($name,$func)
239     {
[2679]240          $this->addEditorFormater('dcLegacyEditor',$name,$func);
[0]241     }
[2566]242
[0]243     /**
[2679]244     Returns editors list
[2566]245
[2679]246     @return   <b>array</b> An array of editors values.
247     */
248     public function getEditors()
249     {
250          $editors = array();
251
252          foreach (array_keys($this->formaters) as $editor_id) {
253               $editors[$editor_id] = $this->plugins->moduleInfo($editor_id,'name');
254          }
255
256          return $editors;
257     }
258
259     /**
260     Returns formaters list by editor
261
262     @param    editor_id <b>string</b>  Editor id (dcLegacyEditor, dcCKEditor, ...)
[0]263     @return   <b>array</b> An array of formaters names in values.
[2682]264
265    /**
266    if @param editor_id is empty:
267    return all formaters sorted by actives editors
268   
269    if @param editor_id is not empty
270    return formaters for an editor if editor is active
271    return empty() array if editor is not active.
272    It can happens when a user choose an editor and admin deactivate that editor later
[0]273     */
[2679]274     public function getFormaters($editor_id='')
[0]275     {
[2679]276          $formaters_list = array();
277
[2682]278          if (!empty($editor_id)) {
279            if (isset($this->formaters[$editor_id])) {
280                $formaters_list = array_keys($this->formaters[$editor_id]);
281            }
[2679]282          } else {
283               foreach ($this->formaters as $editor => $formaters) {
284                    $formaters_list[$editor] = array_keys($formaters);
285               }
286          }
287
288          return $formaters_list;
[0]289     }
[2566]290
[0]291     /**
292     If <var>$name</var> is a valid formater, it returns <var>$str</var>
293     transformed using that formater.
[2566]294
[2679]295     @param    editor_id <b>string</b>  Editor id (dcLegacyEditor, dcCKEditor, ...)
296     @param    name      <b>string</b>       Formater name
297     @param    str       <b>string</b>       String to transform
298     @return   <b>string</b>  String transformed
299     */
300     public function callEditorFormater($editor_id,$name,$str)
301     {
302          if (isset($this->formaters[$editor_id]) && isset($this->formaters[$editor_id][$name])) {
303               return call_user_func($this->formaters[$editor_id][$name],$str);
304          }
305
306          return $str;
307     }
308     //@}
309
310     /**
311     If <var>$name</var> is a valid formater, it returns <var>$str</var>
312     transformed using that formater.
313
[0]314     @param    name      <b>string</b>       Formater name
315     @param    str       <b>string</b>       String to transform
316     @return   <b>string</b>  String transformed
317     */
318     public function callFormater($name,$str)
319     {
[2679]320          return $this->callEditorFormater('dcLegacyEditor',$name,$str);
[0]321     }
322     //@}
[2566]323
324
[0]325     /// @name Behaviors methods
326     //@{
327     /**
328     Adds a new behavior to behaviors stack. <var>$func</var> must be a valid
329     and callable callback.
[2566]330
[0]331     @param    behavior  <b>string</b>       Behavior name
332     @param    func      <b>callback</b>     Function to call
333     */
334     public function addBehavior($behavior,$func)
335     {
336          if (is_callable($func)) {
337               $this->behaviors[$behavior][] = $func;
338          }
339     }
[2566]340
[0]341     /**
342     Tests if a particular behavior exists in behaviors stack.
[2566]343
[0]344     @param    behavior  <b>string</b>  Behavior name
345     @return   <b>boolean</b>
346     */
347     public function hasBehavior($behavior)
348     {
349          return isset($this->behaviors[$behavior]);
350     }
[2566]351
[0]352     /**
353     Get behaviors stack (or part of).
[2566]354
[0]355     @param    behavior  <b>string</b>       Behavior name
356     @return   <b>array</b>
357     */
358     public function getBehaviors($behavior='')
359     {
360          if (empty($this->behaviors)) return null;
[2566]361
[0]362          if ($behavior == '') {
363               return $this->behaviors;
364          } elseif (isset($this->behaviors[$behavior])) {
365               return $this->behaviors[$behavior];
366          }
[2566]367
[0]368          return array();
369     }
[2566]370
[0]371     /**
372     Calls every function in behaviors stack for a given behavior and returns
373     concatened result of each function.
[2566]374
[0]375     Every parameters added after <var>$behavior</var> will be pass to
376     behavior calls.
[2566]377
[0]378     @param    behavior  <b>string</b>  Behavior name
379     @return   <b>string</b> Behavior concatened result
380     */
381     public function callBehavior($behavior)
382     {
383          if (isset($this->behaviors[$behavior]))
384          {
385               $args = func_get_args();
386               array_shift($args);
[2566]387
[0]388               $res = '';
[2566]389
[0]390               foreach ($this->behaviors[$behavior] as $f) {
391                    $res .= call_user_func_array($f,$args);
392               }
[2566]393
[0]394               return $res;
395          }
396     }
397     //@}
[2566]398
[0]399     /// @name Post types URLs management
400     //@{
401     public function getPostAdminURL($type,$post_id,$escaped=true)
402     {
403          if (!isset($this->post_types[$type])) {
404               $type = 'post';
405          }
[2566]406
[0]407          $url = sprintf($this->post_types[$type]['admin_url'],$post_id);
408          return $escaped ? html::escapeURL($url) : $url;
409     }
[2566]410
[0]411     public function getPostPublicURL($type,$post_url,$escaped=true)
412     {
413          if (!isset($this->post_types[$type])) {
414               $type = 'post';
415          }
[2566]416
[0]417          $url = sprintf($this->post_types[$type]['public_url'],$post_url);
418          return $escaped ? html::escapeURL($url) : $url;
419     }
[2566]420
[1694]421     public function setPostType($type,$admin_url,$public_url,$label='')
[0]422     {
423          $this->post_types[$type] = array(
424               'admin_url' => $admin_url,
[1694]425               'public_url' => $public_url,
426               'label' => ($label != '' ? $label : $type)
[0]427          );
428     }
[2566]429
[0]430     public function getPostTypes()
431     {
432          return $this->post_types;
433     }
434     //@}
[2566]435
[0]436     /// @name Versions management methods
437     //@{
438     /**
439     Returns a given $module version.
[2566]440
[0]441     @param    module    <b>string</b>  Module name
442     @return   <b>string</b>  Module version
443     */
444     public function getVersion($module='core')
445     {
446          # Fetch versions if needed
447          if (!is_array($this->versions))
448          {
449               $strReq = 'SELECT module, version FROM '.$this->prefix.'version';
450               $rs = $this->con->select($strReq);
[2566]451
[0]452               while ($rs->fetch()) {
453                    $this->versions[$rs->module] = $rs->version;
454               }
455          }
[2566]456
[0]457          if (isset($this->versions[$module])) {
458               return $this->versions[$module];
459          } else {
460               return null;
461          }
462     }
[2566]463
[0]464     /**
465     Sets $version to given $module.
[2566]466
[0]467     @param    module    <b>string</b>  Module name
468     @param    version   <b>string</b>  Module version
469     */
470     public function setVersion($module,$version)
471     {
472          $cur_version = $this->getVersion($module);
[2566]473
[0]474          $cur = $this->con->openCursor($this->prefix.'version');
475          $cur->module = (string) $module;
476          $cur->version = (string) $version;
[2566]477
[0]478          if ($cur_version === null) {
479               $cur->insert();
480          } else {
481               $cur->update("WHERE module='".$this->con->escape($module)."'");
482          }
[2566]483
[0]484          $this->versions[$module] = $version;
485     }
[2566]486
[0]487     /**
488     Removes given $module version entry.
[2566]489
[0]490     @param    module    <b>string</b>  Module name
491     */
492     public function delVersion($module)
493     {
494          $strReq =
495          'DELETE FROM '.$this->prefix.'version '.
496          "WHERE module = '".$this->con->escape($module)."' ";
[2566]497
[0]498          $this->con->execute($strReq);
[2566]499
[0]500          if (is_array($this->versions)) {
501               unset($this->versions[$module]);
502          }
503     }
[2566]504
[0]505     //@}
[2566]506
[0]507     /// @name Users management methods
508     //@{
509     /**
510     Returns a user by its ID.
[2566]511
[0]512     @param    id        <b>string</b>       User ID
513     @return   <b>record</b>
514     */
515     public function getUser($id)
516     {
517          $params['user_id'] = $id;
[2566]518
[0]519          return $this->getUsers($params);
520     }
[2566]521
[0]522     /**
523     Returns a users list. <b>$params</b> is an array with the following
524     optionnal parameters:
[2566]525
[0]526      - <var>q</var>: search string (on user_id, user_name, user_firstname)
527      - <var>user_id</var>: user ID
528      - <var>order</var>: ORDER BY clause (default: user_id ASC)
529      - <var>limit</var>: LIMIT clause (should be an array ![limit,offset])
[2566]530
[0]531     @param    params         <b>array</b>        Parameters
532     @param    count_only     <b>boolean</b>      Only counts results
533     @return   <b>record</b>
534     */
535     public function getUsers($params=array(),$count_only=false)
536     {
537          if ($count_only)
538          {
539               $strReq =
540               'SELECT count(U.user_id) '.
541               'FROM '.$this->prefix.'user U '.
542               'WHERE NULL IS NULL ';
543          }
544          else
545          {
546               $strReq =
547               'SELECT U.user_id,user_super,user_status,user_pwd,user_change_pwd,'.
548               'user_name,user_firstname,user_displayname,user_email,user_url,'.
549               'user_desc, user_lang,user_tz, user_post_status,user_options, '.
550               'count(P.post_id) AS nb_post '.
551               'FROM '.$this->prefix.'user U '.
552                    'LEFT JOIN '.$this->prefix.'post P ON U.user_id = P.user_id '.
553               'WHERE NULL IS NULL ';
554          }
[2566]555
[0]556          if (!empty($params['q'])) {
557               $q = $this->con->escape(str_replace('*','%',strtolower($params['q'])));
558               $strReq .= 'AND ('.
559                    "LOWER(U.user_id) LIKE '".$q."' ".
560                    "OR LOWER(user_name) LIKE '".$q."' ".
561                    "OR LOWER(user_firstname) LIKE '".$q."' ".
562                    ') ';
563          }
[2566]564
[0]565          if (!empty($params['user_id'])) {
566               $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' ";
567          }
[2566]568
[0]569          if (!$count_only) {
570               $strReq .= 'GROUP BY U.user_id,user_super,user_status,user_pwd,user_change_pwd,'.
571               'user_name,user_firstname,user_displayname,user_email,user_url,'.
572               'user_desc, user_lang,user_tz,user_post_status,user_options ';
[2566]573
[0]574               if (!empty($params['order']) && !$count_only) {
575                    $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' ';
576               } else {
577                    $strReq .= 'ORDER BY U.user_id ASC ';
578               }
579          }
[2566]580
[0]581          if (!$count_only && !empty($params['limit'])) {
582               $strReq .= $this->con->limit($params['limit']);
583          }
[2566]584
[0]585          $rs = $this->con->select($strReq);
586          $rs->extend('rsExtUser');
587          return $rs;
588     }
[2566]589
[0]590     /**
591     Create a new user. Takes a cursor as input and returns the new user ID.
[2566]592
[0]593     @param    cur       <b>cursor</b>       User cursor
594     @return   <b>string</b>
595     */
596     public function addUser($cur)
597     {
598          if (!$this->auth->isSuperAdmin()) {
599               throw new Exception(__('You are not an administrator'));
600          }
[2566]601
[0]602          if ($cur->user_id == '') {
603               throw new Exception(__('No user ID given'));
604          }
[2566]605
[0]606          if ($cur->user_pwd == '') {
607               throw new Exception(__('No password given'));
608          }
[2566]609
[0]610          $this->getUserCursor($cur);
[2566]611
[0]612          if ($cur->user_creadt === null) {
613               $cur->user_creadt = date('Y-m-d H:i:s');
614          }
[2566]615
[0]616          $cur->insert();
[2566]617
[0]618          $this->auth->afterAddUser($cur);
[2566]619
[0]620          return $cur->user_id;
621     }
[2566]622
[0]623     /**
624     Updates an existing user. Returns the user ID.
[2566]625
[0]626     @param    id        <b>string</b>       User ID
627     @param    cur       <b>cursor</b>       User cursor
628     @return   <b>string</b>
629     */
630     public function updUser($id,$cur)
631     {
632          $this->getUserCursor($cur);
[2566]633
[0]634          if (($cur->user_id !== null || $id != $this->auth->userID()) &&
635          !$this->auth->isSuperAdmin()) {
636               throw new Exception(__('You are not an administrator'));
637          }
[2566]638
[0]639          $cur->update("WHERE user_id = '".$this->con->escape($id)."' ");
[2566]640
[0]641          $this->auth->afterUpdUser($id,$cur);
[2566]642
[0]643          if ($cur->user_id !== null) {
644               $id = $cur->user_id;
645          }
[2566]646
[0]647          # Updating all user's blogs
648          $rs = $this->con->select(
649               'SELECT DISTINCT(blog_id) FROM '.$this->prefix.'post '.
650               "WHERE user_id = '".$this->con->escape($id)."' "
651               );
[2566]652
[0]653          while ($rs->fetch()) {
654               $b = new dcBlog($this,$rs->blog_id);
655               $b->triggerBlog();
656               unset($b);
657          }
[2566]658
[0]659          return $id;
660     }
[2566]661
[0]662     /**
663     Deletes a user.
[2566]664
[0]665     @param    id        <b>string</b>       User ID
666     */
667     public function delUser($id)
668     {
669          if (!$this->auth->isSuperAdmin()) {
670               throw new Exception(__('You are not an administrator'));
671          }
[2566]672
[0]673          if ($id == $this->auth->userID()) {
674               return;
675          }
[2566]676
[0]677          $rs = $this->getUser($id);
[2566]678
[0]679          if ($rs->nb_post > 0) {
680               return;
681          }
[2566]682
[0]683          $strReq = 'DELETE FROM '.$this->prefix.'user '.
684                    "WHERE user_id = '".$this->con->escape($id)."' ";
[2566]685
[0]686          $this->con->execute($strReq);
[2566]687
[0]688          $this->auth->afterDelUser($id);
689     }
[2566]690
[0]691     /**
692     Checks whether a user exists.
[2566]693
[0]694     @param    id        <b>string</b>       User ID
695     @return   <b>boolean</b>
696     */
697     public function userExists($id)
698     {
699          $strReq = 'SELECT user_id '.
700                    'FROM '.$this->prefix.'user '.
701                    "WHERE user_id = '".$this->con->escape($id)."' ";
[2566]702
[0]703          $rs = $this->con->select($strReq);
[2566]704
[0]705          return !$rs->isEmpty();
706     }
[2566]707
[0]708     /**
709     Returns all user permissions as an array which looks like:
[2566]710
[0]711      - [blog_id]
712        - [name] => Blog name
713        - [url] => Blog URL
714        - [p]
[2679]715          - [permission] => true
[0]716          - ...
[2566]717
[0]718     @param    id        <b>string</b>       User ID
719     @return   <b>array</b>
720     */
721     public function getUserPermissions($id)
722     {
723          $strReq = 'SELECT B.blog_id, blog_name, blog_url, permissions '.
724                    'FROM '.$this->prefix.'permissions P '.
725                    'INNER JOIN '.$this->prefix.'blog B ON P.blog_id = B.blog_id '.
726                    "WHERE user_id = '".$this->con->escape($id)."' ";
[2566]727
[0]728          $rs = $this->con->select($strReq);
[2566]729
[0]730          $res = array();
[2566]731
[0]732          while ($rs->fetch())
733          {
734               $res[$rs->blog_id] = array(
735                    'name' => $rs->blog_name,
736                    'url' => $rs->blog_url,
737                    'p' => $this->auth->parsePermissions($rs->permissions)
738               );
739          }
[2566]740
[0]741          return $res;
742     }
[2566]743
[0]744     /**
745     Sets user permissions. The <var>$perms</var> array looks like:
[2566]746
[0]747      - [blog_id] => '|perm1|perm2|'
748      - ...
[2566]749
[0]750     @param    id        <b>string</b>       User ID
751     @param    perms     <b>array</b>        Permissions array
752     */
753     public function setUserPermissions($id,$perms)
754     {
755          if (!$this->auth->isSuperAdmin()) {
756               throw new Exception(__('You are not an administrator'));
757          }
[2566]758
[0]759          $strReq = 'DELETE FROM '.$this->prefix.'permissions '.
760                    "WHERE user_id = '".$this->con->escape($id)."' ";
[2566]761
[0]762          $this->con->execute($strReq);
[2566]763
[0]764          foreach ($perms as $blog_id => $p) {
765               $this->setUserBlogPermissions($id, $blog_id, $p, false);
766          }
767     }
[2566]768
[0]769     /**
770     Sets user permissions for a given blog. <var>$perms</var> is an array with
771     permissions in values
[2566]772
[0]773     @param    id             <b>string</b>       User ID
774     @param    blog_id        <b>string</b>       Blog ID
775     @param    perms          <b>array</b>        Permissions
776     @param    delete_first   <b>boolean</b>      Delete permissions before
777     */
778     public function setUserBlogPermissions($id, $blog_id, $perms, $delete_first=true)
779     {
780          if (!$this->auth->isSuperAdmin()) {
781               throw new Exception(__('You are not an administrator'));
782          }
[2566]783
[0]784          $no_perm = empty($perms);
[2566]785
[0]786          $perms = '|'.implode('|',array_keys($perms)).'|';
[2566]787
[0]788          $cur = $this->con->openCursor($this->prefix.'permissions');
[2566]789
[0]790          $cur->user_id = (string) $id;
791          $cur->blog_id = (string) $blog_id;
792          $cur->permissions = $perms;
[2566]793
[0]794          if ($delete_first || $no_perm)
795          {
796               $strReq = 'DELETE FROM '.$this->prefix.'permissions '.
797                         "WHERE blog_id = '".$this->con->escape($blog_id)."' ".
798                         "AND user_id = '".$this->con->escape($id)."' ";
[2566]799
[0]800               $this->con->execute($strReq);
801          }
[2566]802
[0]803          if (!$no_perm) {
804               $cur->insert();
805          }
806     }
[2566]807
[0]808     /**
809     Sets a user default blog. This blog will be selected when user log in.
[2566]810
[0]811     @param    id             <b>string</b>       User ID
812     @param    blog_id        <b>string</b>       Blog ID
813     */
814     public function setUserDefaultBlog($id, $blog_id)
815     {
816          $cur = $this->con->openCursor($this->prefix.'user');
[2566]817
[0]818          $cur->user_default_blog = (string) $blog_id;
[2566]819
[0]820          $cur->update("WHERE user_id = '".$this->con->escape($id)."'");
821     }
[2566]822
[0]823     private function getUserCursor($cur)
824     {
825          if ($cur->isField('user_id')
826          && !preg_match('/^[A-Za-z0-9@._-]{2,}$/',$cur->user_id)) {
827               throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.'));
828          }
[2566]829
[0]830          if ($cur->user_url !== null && $cur->user_url != '') {
831               if (!preg_match('|^http(s?)://|',$cur->user_url)) {
832                    $cur->user_url = 'http://'.$cur->user_url;
833               }
834          }
[2566]835
[0]836          if ($cur->isField('user_pwd')) {
837               if (strlen($cur->user_pwd) < 6) {
838                    throw new Exception(__('Password must contain at least 6 characters.'));
839               }
840               $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$cur->user_pwd);
841          }
[2566]842
[0]843          if ($cur->user_lang !== null && !preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$cur->user_lang)) {
844               throw new Exception(__('Invalid user language code'));
845          }
[2566]846
[0]847          if ($cur->user_upddt === null) {
848               $cur->user_upddt = date('Y-m-d H:i:s');
849          }
[2566]850
[0]851          if ($cur->user_options !== null) {
852               $cur->user_options = serialize((array) $cur->user_options);
853          }
854     }
[2566]855
[0]856     /**
857     Returns user default settings in an associative array with setting names in
858     keys.
[2566]859
[0]860     @return   <b>array</b>
861     */
862     public function userDefaults()
863     {
864          return array(
865               'edit_size' => 24,
866               'enable_wysiwyg' => true,
[696]867               'post_format' => 'wiki'
[0]868          );
869     }
870     //@}
[2566]871
[0]872     /// @name Blog management methods
873     //@{
874     /**
875     Returns all blog permissions (users) as an array which looks like:
[2566]876
[0]877      - [user_id]
878        - [name] => User name
879        - [firstname] => User firstname
880        - [displayname] => User displayname
881        - [super] => (true|false) super admin
882        - [p]
[2679]883          - [permission] => true
[0]884          - ...
[2566]885
[0]886     @param    id             <b>string</b>       Blog ID
887     @param    with_super     <b>boolean</b>      Includes super admins in result
888     @return   <b>array</b>
889     */
890     public function getBlogPermissions($id,$with_super=true)
891     {
892          $strReq =
893          'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '.
[1698]894          'user_displayname, user_email, permissions '.
[0]895          'FROM '.$this->prefix.'user U '.
896          'JOIN '.$this->prefix.'permissions P ON U.user_id = P.user_id '.
897          "WHERE blog_id = '".$this->con->escape($id)."' ";
[2566]898
[0]899          if ($with_super) {
900               $strReq .=
901               'UNION '.
902               'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '.
[1698]903               "user_displayname, user_email, NULL AS permissions ".
[0]904               'FROM '.$this->prefix.'user U '.
905               'WHERE user_super = 1 ';
906          }
[2566]907
[0]908          $rs = $this->con->select($strReq);
[2566]909
[0]910          $res = array();
[2566]911
[0]912          while ($rs->fetch())
913          {
914               $res[$rs->user_id] = array(
915                    'name' => $rs->user_name,
916                    'firstname' => $rs->user_firstname,
917                    'displayname' => $rs->user_displayname,
[1698]918                    'email' => $rs->user_email,
[0]919                    'super' => (boolean) $rs->user_super,
920                    'p' => $this->auth->parsePermissions($rs->permissions)
921               );
922          }
[2566]923
[0]924          return $res;
925     }
[2566]926
[0]927     /**
928     Returns a blog of given ID.
[2566]929
[0]930     @param    id        <b>string</b>       Blog ID
931     @return   <b>record</b>
932     */
933     public function getBlog($id)
934     {
935          $blog = $this->getBlogs(array('blog_id'=>$id));
[2566]936
[0]937          if ($blog->isEmpty()) {
938               return false;
939          }
[2566]940
[0]941          return $blog;
942     }
[2566]943
[0]944     /**
945     Returns a record of blogs. <b>$params</b> is an array with the following
946     optionnal parameters:
[2566]947
[0]948      - <var>blog_id</var>: Blog ID
949      - <var>q</var>: Search string on blog_id, blog_name and blog_url
950      - <var>limit</var>: limit results
[2566]951
[0]952     @param    params         <b>array</b>        Parameters
953     @param    count_only     <b>boolean</b>      Count only results
954     @return   <b>record</b>
955     */
956     public function getBlogs($params=array(),$count_only=false)
957     {
958          $join = '';    // %1$s
959          $where = '';   // %2$s
[2566]960
[0]961          if ($count_only)
962          {
963               $strReq = 'SELECT count(B.blog_id) '.
964                         'FROM '.$this->prefix.'blog B '.
965                         '%1$s '.
966                         'WHERE NULL IS NULL '.
967                         '%2$s ';
968          }
969          else
970          {
971               $strReq =
972               'SELECT B.blog_id, blog_uid, blog_url, blog_name, blog_desc, blog_creadt, '.
973               'blog_upddt, blog_status '.
974               'FROM '.$this->prefix.'blog B '.
975               '%1$s '.
976               'WHERE NULL IS NULL '.
977               '%2$s ';
[2566]978
[0]979               if (!empty($params['order'])) {
980                    $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' ';
981               } else {
982                    $strReq .= 'ORDER BY B.blog_id ASC ';
983               }
[2566]984
[0]985               if (!empty($params['limit'])) {
986                    $strReq .= $this->con->limit($params['limit']);
987               }
988          }
[2566]989
[0]990          if ($this->auth->userID() && !$this->auth->isSuperAdmin())
991          {
992               $join = 'INNER JOIN '.$this->prefix.'permissions PE ON B.blog_id = PE.blog_id ';
993               $where =
994               "AND PE.user_id = '".$this->con->escape($this->auth->userID())."' ".
995               "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ".
996               "AND blog_status IN (1,0) ";
997          } elseif (!$this->auth->userID()) {
998               $where = 'AND blog_status IN (1,0) ';
999          }
[2566]1000
[0]1001          if (!empty($params['blog_id'])) {
1002               $where .= "AND B.blog_id = '".$this->con->escape($params['blog_id'])."' ";
1003          }
[2566]1004
[0]1005          if (!empty($params['q'])) {
[1593]1006               $params['q'] = strtolower(str_replace('*','%',$params['q']));
[0]1007               $where .=
1008               'AND ('.
1009               "LOWER(B.blog_id) LIKE '".$this->con->escape($params['q'])."' ".
1010               "OR LOWER(B.blog_name) LIKE '".$this->con->escape($params['q'])."' ".
1011               "OR LOWER(B.blog_url) LIKE '".$this->con->escape($params['q'])."' ".
1012               ') ';
1013          }
[2566]1014
[0]1015          $strReq = sprintf($strReq,$join,$where);
1016          return $this->con->select($strReq);
1017     }
[2566]1018
[0]1019     /**
1020     Creates a new blog.
[2566]1021
[0]1022     @param    cur            <b>cursor</b>       Blog cursor
1023     */
1024     public function addBlog($cur)
1025     {
1026          if (!$this->auth->isSuperAdmin()) {
1027               throw new Exception(__('You are not an administrator'));
1028          }
[2566]1029
[0]1030          $this->getBlogCursor($cur);
[2566]1031
[0]1032          $cur->blog_creadt = date('Y-m-d H:i:s');
1033          $cur->blog_upddt = date('Y-m-d H:i:s');
1034          $cur->blog_uid = md5(uniqid());
[2566]1035
[0]1036          $cur->insert();
1037     }
[2566]1038
[0]1039     /**
1040     Updates a given blog.
[2566]1041
[0]1042     @param    id        <b>string</b>       Blog ID
1043     @param    cur       <b>cursor</b>       Blog cursor
1044     */
1045     public function updBlog($id,$cur)
1046     {
1047          $this->getBlogCursor($cur);
[2566]1048
[0]1049          $cur->blog_upddt = date('Y-m-d H:i:s');
[2566]1050
[0]1051          $cur->update("WHERE blog_id = '".$this->con->escape($id)."'");
1052     }
[2566]1053
[0]1054     private function getBlogCursor($cur)
1055     {
[2596]1056          if (($cur->blog_id !== null
1057               && !preg_match('/^[A-Za-z0-9._-]{2,}$/',$cur->blog_id)) ||
1058               (!$cur->blog_id)) {
[2566]1059               throw new Exception(__('Blog ID must contain at least 2 characters using letters, numbers or symbols.'));
[0]1060          }
[2566]1061
[2596]1062          if (($cur->blog_name !== null && $cur->blog_name == '') ||
1063               (!$cur->blog_name)) {
[0]1064               throw new Exception(__('No blog name'));
1065          }
[2566]1066
[2596]1067          if (($cur->blog_url !== null && $cur->blog_url == '') ||
1068               (!$cur->blog_url)) {
[0]1069               throw new Exception(__('No blog URL'));
1070          }
[2566]1071
[0]1072          if ($cur->blog_desc !== null) {
1073               $cur->blog_desc = html::clean($cur->blog_desc);
1074          }
1075     }
[2566]1076
[0]1077     /**
1078     Removes a given blog.
1079     @warning This will remove everything related to the blog (posts,
1080     categories, comments, links...)
[2566]1081
[0]1082     @param    id        <b>string</b>       Blog ID
1083     */
1084     public function delBlog($id)
1085     {
1086          if (!$this->auth->isSuperAdmin()) {
1087               throw new Exception(__('You are not an administrator'));
1088          }
[2566]1089
[0]1090          $strReq = 'DELETE FROM '.$this->prefix.'blog '.
1091                    "WHERE blog_id = '".$this->con->escape($id)."' ";
[2566]1092
[0]1093          $this->con->execute($strReq);
1094     }
[2566]1095
[0]1096     /**
1097     Checks if a blog exist.
[2566]1098
[0]1099     @param    id        <b>string</b>       Blog ID
1100     @return   <b>boolean</b>
1101     */
1102     public function blogExists($id)
1103     {
1104          $strReq = 'SELECT blog_id '.
1105                    'FROM '.$this->prefix.'blog '.
1106                    "WHERE blog_id = '".$this->con->escape($id)."' ";
[2566]1107
[0]1108          $rs = $this->con->select($strReq);
[2566]1109
[0]1110          return !$rs->isEmpty();
1111     }
[2566]1112
[0]1113     /**
1114     Count posts on a blog
[2566]1115
[0]1116     @param    id        <b>string</b>       Blog ID
1117     @param    type      <b>string</b>       Post type
1118     @return   <b>boolean</b>
1119     */
1120     public function countBlogPosts($id,$type=null)
1121     {
1122          $strReq = 'SELECT COUNT(post_id) '.
1123                    'FROM '.$this->prefix.'post '.
1124                    "WHERE blog_id = '".$this->con->escape($id)."' ";
[2566]1125
[0]1126          if ($type) {
1127               $strReq .= "AND post_type = '".$this->con->escape($type)."' ";
1128          }
[2566]1129
[0]1130          return $this->con->select($strReq)->f(0);
1131     }
1132     //@}
[2566]1133
[0]1134     /// @name HTML Filter methods
1135     //@{
1136     /**
1137     Calls HTML filter to drop bad tags and produce valid XHTML output (if
1138     tidy extension is present). If <b>enable_html_filter</b> blog setting is
1139     false, returns not filtered string.
[2566]1140
[0]1141     @param    str  <b>string</b>       String to filter
1142     @return   <b>string</b> Filtered string.
1143     */
1144     public function HTMLfilter($str)
1145     {
1146          if ($this->blog instanceof dcBlog && !$this->blog->settings->system->enable_html_filter) {
1147               return $str;
1148          }
[2566]1149
[0]1150          $filter = new htmlFilter;
1151          $str = trim($filter->apply($str));
1152          return $str;
1153     }
1154     //@}
[2566]1155
[0]1156     /// @name wiki2xhtml methods
1157     //@{
1158     private function initWiki()
1159     {
1160          $this->wiki2xhtml = new wiki2xhtml;
1161     }
[2566]1162
[0]1163     /**
1164     Returns a transformed string with wiki2xhtml.
[2566]1165
[0]1166     @param    str       <b>string</b>       String to transform
1167     @return   <b>string</b>  Transformed string
1168     */
1169     public function wikiTransform($str)
1170     {
1171          if (!($this->wiki2xhtml instanceof wiki2xhtml)) {
1172               $this->initWiki();
1173          }
1174          return $this->wiki2xhtml->transform($str);
1175     }
[2566]1176
[0]1177     /**
1178     Inits <var>wiki2xhtml</var> property for blog post.
1179     */
1180     public function initWikiPost()
1181     {
1182          $this->initWiki();
[2566]1183
[0]1184          $this->wiki2xhtml->setOpts(array(
1185               'active_title' => 1,
1186               'active_setext_title' => 0,
1187               'active_hr' => 1,
1188               'active_lists' => 1,
1189               'active_quote' => 1,
1190               'active_pre' => 1,
1191               'active_empty' => 1,
1192               'active_auto_br' => 0,
1193               'active_auto_urls' => 0,
1194               'active_urls' => 1,
1195               'active_auto_img' => 0,
1196               'active_img' => 1,
1197               'active_anchor' => 1,
1198               'active_em' => 1,
1199               'active_strong' => 1,
1200               'active_br' => 1,
1201               'active_q' => 1,
1202               'active_code' => 1,
1203               'active_acronym' => 1,
1204               'active_ins' => 1,
1205               'active_del' => 1,
1206               'active_footnotes' => 1,
1207               'active_wikiwords' => 0,
1208               'active_macros' => 1,
1209               'parse_pre' => 1,
1210               'active_fr_syntax' => 0,
1211               'first_title_level' => 3,
1212               'note_prefix' => 'wiki-footnote',
1213               'note_str' => '<div class="footnotes"><h4>Notes</h4>%s</div>'
1214          ));
[2566]1215
[0]1216          $this->wiki2xhtml->registerFunction('url:post',array($this,'wikiPostLink'));
[2566]1217
[0]1218          # --BEHAVIOR-- coreWikiPostInit
1219          $this->callBehavior('coreInitWikiPost',$this->wiki2xhtml);
1220     }
[2566]1221
[0]1222     /**
1223     Inits <var>wiki2xhtml</var> property for simple blog comment (basic syntax).
1224     */
1225     public function initWikiSimpleComment()
1226     {
1227          $this->initWiki();
[2566]1228
[0]1229          $this->wiki2xhtml->setOpts(array(
1230               'active_title' => 0,
1231               'active_setext_title' => 0,
1232               'active_hr' => 0,
1233               'active_lists' => 0,
1234               'active_quote' => 0,
1235               'active_pre' => 0,
1236               'active_empty' => 0,
1237               'active_auto_br' => 1,
1238               'active_auto_urls' => 1,
1239               'active_urls' => 0,
1240               'active_auto_img' => 0,
1241               'active_img' => 0,
1242               'active_anchor' => 0,
1243               'active_em' => 0,
1244               'active_strong' => 0,
1245               'active_br' => 0,
1246               'active_q' => 0,
1247               'active_code' => 0,
1248               'active_acronym' => 0,
1249               'active_ins' => 0,
1250               'active_del' => 0,
1251               'active_footnotes' => 0,
1252               'active_wikiwords' => 0,
1253               'active_macros' => 0,
1254               'parse_pre' => 0,
1255               'active_fr_syntax' => 0
1256          ));
[2566]1257
[0]1258          # --BEHAVIOR-- coreInitWikiSimpleComment
1259          $this->callBehavior('coreInitWikiSimpleComment',$this->wiki2xhtml);
1260     }
[2566]1261
[0]1262     /**
1263     Inits <var>wiki2xhtml</var> property for blog comment.
1264     */
1265     public function initWikiComment()
1266     {
1267          $this->initWiki();
[2566]1268
[0]1269          $this->wiki2xhtml->setOpts(array(
1270               'active_title' => 0,
1271               'active_setext_title' => 0,
1272               'active_hr' => 0,
1273               'active_lists' => 1,
1274               'active_quote' => 0,
1275               'active_pre' => 1,
1276               'active_empty' => 0,
1277               'active_auto_br' => 1,
1278               'active_auto_urls' => 1,
1279               'active_urls' => 1,
1280               'active_auto_img' => 0,
1281               'active_img' => 0,
1282               'active_anchor' => 0,
1283               'active_em' => 1,
1284               'active_strong' => 1,
1285               'active_br' => 1,
1286               'active_q' => 1,
1287               'active_code' => 1,
1288               'active_acronym' => 1,
1289               'active_ins' => 1,
1290               'active_del' => 1,
1291               'active_footnotes' => 0,
1292               'active_wikiwords' => 0,
1293               'active_macros' => 0,
1294               'parse_pre' => 0,
1295               'active_fr_syntax' => 0
1296          ));
[2566]1297
[0]1298          # --BEHAVIOR-- coreInitWikiComment
1299          $this->callBehavior('coreInitWikiComment',$this->wiki2xhtml);
1300     }
[2566]1301
[0]1302     public function wikiPostLink($url,$content)
1303     {
[2566]1304          if (!($this->blog instanceof dcBlog)) {
[0]1305               return array();
1306          }
[2566]1307
[0]1308          $post_id = abs((integer) substr($url,5));
1309          if (!$post_id) {
1310               return array();
1311          }
[2566]1312
[0]1313          $post = $this->blog->getPosts(array('post_id'=>$post_id));
1314          if ($post->isEmpty()) {
1315               return array();
1316          }
[2566]1317
[0]1318          $res = array('url' => $post->getURL());
1319          $post_title = $post->post_title;
[2566]1320
[0]1321          if ($content != $url) {
1322               $res['title'] = html::escapeHTML($post->post_title);
1323          }
[2566]1324
[0]1325          if ($content == '' || $content == $url) {
1326               $res['content'] = html::escapeHTML($post->post_title);
1327          }
[2566]1328
[0]1329          if ($post->post_lang) {
1330               $res['lang'] = $post->post_lang;
1331          }
[2566]1332
[0]1333          return $res;
1334     }
1335     //@}
[2566]1336
[0]1337     /// @name Maintenance methods
1338     //@{
1339     /**
1340     Creates default settings for active blog. Optionnal parameter
1341     <var>defaults</var> replaces default params while needed.
[2566]1342
[0]1343     @param    defaults       <b>array</b>   Default parameters
1344     */
1345     public function blogDefaults($defaults=null)
1346     {
1347          if (!is_array($defaults))
1348          {
1349               $defaults = array(
1350                    array('allow_comments','boolean',true,
1351                    'Allow comments on blog'),
1352                    array('allow_trackbacks','boolean',true,
1353                    'Allow trackbacks on blog'),
1354                    array('blog_timezone','string','Europe/London',
1355                    'Blog timezone'),
1356                    array('comments_nofollow','boolean',true,
1357                    'Add rel="nofollow" to comments URLs'),
1358                    array('comments_pub','boolean',true,
1359                    'Publish comments immediately'),
1360                    array('comments_ttl','integer',0,
1361                    'Number of days to keep comments open (0 means no ttl)'),
1362                    array('copyright_notice','string','','Copyright notice (simple text)'),
1363                    array('date_format','string','%A, %B %e %Y',
1364                    'Date format. See PHP strftime function for patterns'),
1365                    array('editor','string','',
1366                    'Person responsible of the content'),
1367                    array('enable_html_filter','boolean',0,
1368                    'Enable HTML filter'),
1369                    array('enable_xmlrpc','boolean',0,
1370                    'Enable XML/RPC interface'),
1371                    array('lang','string','en',
1372                    'Default blog language'),
[706]1373                    array('media_exclusion','string','/\.php$/i',
[0]1374                    'File name exclusion pattern in media manager. (PCRE value)'),
1375                    array('media_img_m_size','integer',448,
1376                    'Image medium size in media manager'),
1377                    array('media_img_s_size','integer',240,
1378                    'Image small size in media manager'),
1379                    array('media_img_t_size','integer',100,
1380                    'Image thumbnail size in media manager'),
1381                    array('media_img_title_pattern','string','Title ;; Date(%b %Y) ;; separator(, )',
1382                    'Pattern to set image title when you insert it in a post'),
[2577]1383                    array('nb_post_for_home','integer',20,
1384                    'Number of entries on first home page'),
[0]1385                    array('nb_post_per_page','integer',20,
[2577]1386                    'Number of entries on home pages and category pages'),
[0]1387                    array('nb_post_per_feed','integer',20,
1388                    'Number of entries on feeds'),
1389                    array('nb_comment_per_feed','integer',20,
1390                    'Number of comments on feeds'),
1391                    array('post_url_format','string','{y}/{m}/{d}/{t}',
1392                    'Post URL format. {y}: year, {m}: month, {d}: day, {id}: post id, {t}: entry title'),
1393                    array('public_path','string','public',
1394                    'Path to public directory, begins with a / for a full system path'),
1395                    array('public_url','string','/public',
1396                    'URL to public directory'),
1397                    array('robots_policy','string','INDEX,FOLLOW',
1398                    'Search engines robots policy'),
1399                    array('short_feed_items','boolean',false,
1400                    'Display short feed items'),
[2641]1401                    array('theme','string','berlin',
[0]1402                    'Blog theme'),
1403                    array('themes_path','string','themes',
1404                    'Themes root path'),
1405                    array('themes_url','string','/themes',
1406                    'Themes root URL'),
1407                    array('time_format','string','%H:%M',
1408                    'Time format. See PHP strftime function for patterns'),
1409                    array('tpl_allow_php','boolean',false,
1410                    'Allow PHP code in templates'),
1411                    array('tpl_use_cache','boolean',true,
1412                    'Use template caching'),
1413                    array('trackbacks_pub','boolean',true,
1414                    'Publish trackbacks immediately'),
1415                    array('trackbacks_ttl','integer',0,
1416                    'Number of days to keep trackbacks open (0 means no ttl)'),
1417                    array('url_scan','string','query_string',
1418                    'URL handle mode (path_info or query_string)'),
1419                    array('use_smilies','boolean',false,
1420                    'Show smilies on entries and comments'),
[2198]1421                    array('inc_subcats','boolean',false,
1422                    'Include sub-categories in category page and category posts feed'),
[0]1423                    array('wiki_comments','boolean',false,
1424                    'Allow commenters to use a subset of wiki syntax')
1425               );
1426          }
[2566]1427
[0]1428          $settings = new dcSettings($this,null);
1429          $settings->addNamespace('system');
[2566]1430
[0]1431          foreach ($defaults as $v) {
1432               $settings->system->put($v[0],$v[2],$v[1],$v[3],false,true);
1433          }
1434     }
[2566]1435
[0]1436     /**
1437     Recreates entries search engine index.
[2566]1438
[0]1439     @param    start     <b>integer</b>      Start entry index
1440     @param    limit     <b>integer</b>      Number of entry to index
[2566]1441
[0]1442     @return   <b>integer</b>      <var>$start</var> and <var>$limit</var> sum
1443     */
1444     public function indexAllPosts($start=null,$limit=null)
1445     {
1446          $strReq = 'SELECT COUNT(post_id) '.
1447                    'FROM '.$this->prefix.'post';
1448          $rs = $this->con->select($strReq);
1449          $count = $rs->f(0);
[2566]1450
[0]1451          $strReq = 'SELECT post_id, post_title, post_excerpt_xhtml, post_content_xhtml '.
1452                    'FROM '.$this->prefix.'post ';
[2566]1453
[0]1454          if ($start !== null && $limit !== null) {
1455               $strReq .= $this->con->limit($start,$limit);
1456          }
[2566]1457
[0]1458          $rs = $this->con->select($strReq,true);
[2566]1459
[0]1460          $cur = $this->con->openCursor($this->prefix.'post');
[2566]1461
[0]1462          while ($rs->fetch())
1463          {
1464               $words = $rs->post_title.' '. $rs->post_excerpt_xhtml.' '.
1465               $rs->post_content_xhtml;
[2566]1466
[0]1467               $cur->post_words = implode(' ',text::splitWords($words));
1468               $cur->update('WHERE post_id = '.(integer) $rs->post_id);
1469               $cur->clean();
1470          }
[2566]1471
[0]1472          if ($start+$limit > $count) {
1473               return null;
1474          }
1475          return $start+$limit;
1476     }
[2566]1477
[0]1478     /**
1479     Recreates comments search engine index.
[2566]1480
[0]1481     @param    start     <b>integer</b>      Start comment index
1482     @param    limit     <b>integer</b>      Number of comments to index
[2566]1483
[0]1484     @return   <b>integer</b>      <var>$start</var> and <var>$limit</var> sum
1485     */
1486     public function indexAllComments($start=null,$limit=null)
1487     {
1488          $strReq = 'SELECT COUNT(comment_id) '.
1489                    'FROM '.$this->prefix.'comment';
1490          $rs = $this->con->select($strReq);
1491          $count = $rs->f(0);
[2566]1492
[0]1493          $strReq = 'SELECT comment_id, comment_content '.
1494                    'FROM '.$this->prefix.'comment ';
[2566]1495
[0]1496          if ($start !== null && $limit !== null) {
1497               $strReq .= $this->con->limit($start,$limit);
1498          }
[2566]1499
[0]1500          $rs = $this->con->select($strReq);
[2566]1501
[0]1502          $cur = $this->con->openCursor($this->prefix.'comment');
[2566]1503
[0]1504          while ($rs->fetch())
1505          {
1506               $cur->comment_words = implode(' ',text::splitWords($rs->comment_content));
1507               $cur->update('WHERE comment_id = '.(integer) $rs->comment_id);
1508               $cur->clean();
1509          }
[2566]1510
[0]1511          if ($start+$limit > $count) {
1512               return null;
1513          }
1514          return $start+$limit;
1515     }
[2566]1516
[0]1517     /**
1518     Reinits nb_comment and nb_trackback in post table.
1519     */
1520     public function countAllComments()
1521     {
[2566]1522
[136]1523          $updCommentReq = 'UPDATE '.$this->prefix.'post P '.
1524               'SET nb_comment = ('.
1525                    'SELECT COUNT(C.comment_id) from '.$this->prefix.'comment C '.
1526                    'WHERE C.post_id = P.post_id AND C.comment_trackback <> 1 '.
1527                    'AND C.comment_status = 1 '.
1528               ')';
1529          $updTrackbackReq = 'UPDATE '.$this->prefix.'post P '.
1530               'SET nb_trackback = ('.
1531                    'SELECT COUNT(C.comment_id) from '.$this->prefix.'comment C '.
1532                    'WHERE C.post_id = P.post_id AND C.comment_trackback = 1 '.
1533                    'AND C.comment_status = 1 '.
1534               ')';
1535          $this->con->execute($updCommentReq);
1536          $this->con->execute($updTrackbackReq);
[0]1537     }
[2566]1538
[0]1539     /**
1540     Empty templates cache directory
1541     */
1542     public function emptyTemplatesCache()
1543     {
1544          if (is_dir(DC_TPL_CACHE.'/cbtpl')) {
1545               files::deltree(DC_TPL_CACHE.'/cbtpl');
1546          }
1547     }
[2595]1548
1549     /**
1550      Return elapsed time since script has been started
[2679]1551      @param     $mtime <b>float</b> timestamp (microtime format) to evaluate delta from
1552                                          current time is taken if null
1553      @return <b>float</b>          elapsed time
[2595]1554      */
1555     public function getElapsedTime ($mtime=null) {
1556          if ($mtime !== null) {
1557               return $mtime-$this->stime;
1558          } else {
1559               return microtime(true)-$this->stime;
1560          }
1561     }
[0]1562     //@}
[2595]1563
1564
1565
[0]1566}
Note: See TracBrowser for help on using the repository browser.

Sites map