Dotclear

source: inc/core/class.dc.core.php @ 3402:8681798c6491

Revision 3402:8681798c6491, 40.1 KB checked in by Jean-Christian Denis, 9 years ago (diff)

Revamped blogs list with full dcAction system,
closes #1551 , closes #2217 , addresses #1566 , addresses #776

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

Sites map