Dotclear

source: inc/core/class.dc.core.php @ 2641:1ec355180bff

Revision 2641:1ec355180bff, 36.3 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

New default theme is now berlin (for new installations).
Minor ARIA complement

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

Sites map