Dotclear


Ignore:
Timestamp:
03/08/18 17:58:39 (7 years ago)
Author:
franck <carnet.franck.paul@…>
Branch:
default
Message:

Code formatting (PSR-2)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • inc/core/class.dc.core.php

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

Sites map