Dotclear

source: inc/core/class.dc.core.php @ 2715:a87ddf7dbfb5

Revision 2715:a87ddf7dbfb5, 39.8 KB checked in by Dsls, 11 years ago (diff)

Merge with default (admin/post.php still to update with editor preferences, in twig template)

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

Sites map