Dotclear

source: inc/core/class.dc.core.php @ 852:969647a6c35e

Revision 852:969647a6c35e, 30.8 KB checked in by Dsls <dsls@…>, 13 years ago (diff)

sexy step 3 : no more media.

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

Sites map