OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / libs / SKIN.php
1 <?php
2 /*
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4  * Copyright (C) 2002-2009 The Nucleus Group
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * (see nucleus/documentation/index.html#license for more info)
11  */
12 /**
13  * Class representing a skin
14  *
15  * @license http://nucleuscms.org/license.txt GNU General Public License
16  * @copyright Copyright (C) 2002-2009 The Nucleus Group
17 <<<<<<< HEAD
18  * @version $Id: SKIN.php 1816 2012-05-03 01:40:10Z sakamocchi $
19 =======
20  * @version $Id: SKIN.php 1886 2012-06-17 08:27:27Z sakamocchi $
21 >>>>>>> skinnable-master
22  */
23
24 if ( !function_exists('requestVar') )
25 {
26         exit;
27 }
28
29 class Skin
30 {
31         // after creating a SKIN object, evaluates to true when the skin exists
32         private $valid;
33         
34         // skin characteristics. Use the getXXX methods rather than accessing directly
35         private $id;
36         private $description;
37         private $contentType;
38         private $includeMode;           // either 'normal' or 'skindir'
39         private $includePrefix;
40         private $name;
41         
42         /* action class */
43         private $action_class;
44         private $event_identifier;
45         
46         /**
47          * Skin::__construct()
48          * Constructor for a new SKIN object
49          * 
50          * @param       integer $id                                     id of the skin
51          * @param       string  $action_class           name of class extended from BaseActions
52          * @param       string  $event_identifier       event identifier. for example, InitAdminSkinParse if AdminSkin is used
53          * @return      void
54          */
55         public function __construct($id, $action_class='Actions', $event_identifier='Skin')
56         {
57                 global $DIR_LIBS;
58                 
59                 $this->id = (integer) $id;
60                 
61 <<<<<<< HEAD
62                 /*
63                  * NOTE: include needed action class
64                  */
65 =======
66                 /* NOTE: include needed action class */
67 >>>>>>> skinnable-master
68                 if ( $action_class != 'Actions' )
69                 {
70                         if ( !class_exists($action_class, FALSE)
71                           && (!file_exists("{$DIR_LIBS}{$action_class}.php")
72                            || !include("{$DIR_LIBS}{$action_class}.php")) )
73                         {
74                                 return;
75                         }
76                 }
77                 else
78                 {
79                         if ( !class_exists('Actions', FALSE)
80                           && (!file_exists("{$DIR_LIBS}ACTIONS.php")
81                            || !include("{$DIR_LIBS}ACTIONS.php")) )
82                         {
83                                 return;
84                         }
85                 }
86                 
87                 $this->action_class = $action_class;
88                 $this->event_identifier = $event_identifier;
89                 
90                 // read skin name/description/content type
91                 $query = "SELECT * FROM %s WHERE sdnumber=%d;";
92                 $query = sprintf($query, sql_table('skin_desc'), $this->id);
93                 $res = DB::getRow($query);
94                 
95                 $this->valid = !empty($res);
96                 if ( $this->valid )
97                 {
98                         $this->name = $res['sdname'];
99                         $this->description = $res['sddesc'];
100                         $this->contentType = $res['sdtype'];
101                         $this->includeMode = $res['sdincmode'];
102                         $this->includePrefix = $res['sdincpref'];
103                 }
104                 
105                 return;
106         }
107         
108         /**
109          * Skin::getID()
110          * Get SKIN id
111          * 
112          * @param       void
113          * @return      integer id for this skin instance
114          */
115         public function getID()
116         {
117                 return (integer) $this->id;
118         }
119         
120         /**
121          * Skin::isValid()
122          * 
123          * @param       void
124          * @return      boolean
125          */
126         public function isValid()
127         {
128                 return (boolean) $this->valid;
129         }
130         
131         /**
132          * Skin::getName()
133          * Get SKIN name
134          * 
135          * @param       void
136          * @return      string  name of this skin instance
137          */
138         public function getName()
139         {
140                 return (string) $this->name;
141         }
142         
143         /**
144          * Skin::getDescription()
145          * Get SKIN description
146          * 
147          * @param       void
148          * @return      string  description of this skin instance
149          */
150         public function getDescription()
151         {
152                 return (string) $this->description;
153         }
154         
155         /**
156          * Skin::getContentType()
157          * Get SKIN content type
158          * e.g. text/xml, text/html, application/atom+xml
159          * 
160          * @param       void
161          * @return      string  name of this skin instance
162          */
163         public function getContentType()
164         {
165                 return (string) $this->contentType;
166         }
167         
168         /**
169          * Skin::getIncludeMode()
170          * Get include mode of the SKIN
171          * 
172          * Returns either 'normal' or 'skindir':
173          * 'normal': if a all data of the skin can be found in the databse
174          * 'skindir': if the skin has data in the it's skin driectory
175          * 
176          * @param       void
177          * @return      string  normal/skindir
178          */
179         public function getIncludeMode()
180         {
181                 return (string) $this->includeMode;
182         }
183         
184         /**
185          * Skin::getIncludePrefix()
186          * Get include prefix of the SKIN
187          * 
188          * Get name of the subdirectory (with trailing slash) where
189          * the files of the current skin can be found (e.g. 'default/')
190          * 
191          * @param       void
192          * @return      string  include prefix of this skin instance
193          */
194         public function getIncludePrefix()
195         {
196                 return (string) $this->includePrefix;
197         }
198         
199         /**
200          * Skin::exists()
201          * Checks if a skin with a given shortname exists
202          * 
203          * @static
204          * @param       string  $name   Skin short name
205          * @return      integer number of skins with the given ID
206          */
207         static public function exists($name)
208         {
209                 $query = "SELECT COUNT(*) AS result FROM %s WHERE sdname=%s;";
210                 $query = sprintf($query, sql_table('skin_desc'), DB::quoteValue($name));
211                 return (DB::getValue($query) > 0);
212         }
213         
214         /**
215          * Skin::existsID()
216          * Checks if a skin with a given ID exists
217          * 
218          * @static
219          * @param       string  $id     Skin ID
220          * @return      integer number of skins with the given ID
221          */
222         static public function existsID($id)
223         {
224                 $query = "SELECT COUNT(*) AS result FROM %s WHERE sdnumber=%d;";
225                 $query = sprintf($query, sql_table('skin_desc'), (integer) $id);
226                 return (DB::getValue($query) > 0);
227         }
228         
229         /**
230          * Skin::createFromName()
231          * Returns a skin given its shortname
232          * 
233          * @static
234          * @param       string  $name   Skin shortname
235          * @return      object instance of Skin class
236          */
237         static public function createFromName($name)
238         {
239                 return new SKIN(SKIN::getIdFromName($name));
240         }
241         
242         /**
243          * Skin::getIdFromName()
244          * Returns a skin ID given its shortname
245          * 
246          * @static
247          * @param       string  $name   Skin shortname
248          * @return      integer Skin ID
249          */
250         static public function getIdFromName($name)
251         {
252                 $query = "SELECT sdnumber FROM %s WHERE sdname=%s;";
253                 $query = sprintf($query, sql_table('skin_desc'), DB::quoteValue($name));
254                 return DB::getValue($query);
255         }
256         
257         /**
258          * Skin::getNameFromId()
259          * Returns a skin shortname given its ID
260          * 
261          * @static
262          * @param       string  $name
263          * @return      string  Skin short name
264          */
265         static public function getNameFromId($id)
266         {
267                 $query = "SELECT sdname AS result FROM %s WHERE sdnumber=%d;";
268                 $query = sprintf($query, sql_table('skin_desc'), (integer) $id);
269                 return DB::getValue($query);
270         }
271         
272         /**
273          * SKIN::createNew()
274          * Creates a new skin, with the given characteristics.
275          *
276          * @static
277          * @param       String  $name   value for nucleus_skin.sdname
278          * @param       String  $desc   value for nucleus_skin.sddesc
279          * @param       String  $type   value for nucleus_skin.sdtype
280          * @param       String  $includeMode    value for nucleus_skin.sdinclude
281          * @param       String  $includePrefix  value for nucleus_skin.sdincpref
282          * @return      Integer ID for just inserted record
283          */
284         public function createNew($name, $desc, $type = 'text/html', $includeMode = 'normal', $includePrefix = '')
285         {
286                 global $manager;
287                 
288                 $data = array(
289                         'name'                  => &$name,
290                         'description'   => &$desc,
291                         'type'                  => &$type,
292                         'includeMode'   => &$includeMode,
293                         'includePrefix' => &$includePrefix
294                 );
295                 $manager->notify('PreAddSkin', $data);
296                 
297                 $query = "INSERT INTO %s (sdname, sddesc, sdtype, sdincmode, sdincpref) VALUES (%s, %s, %s, %s, %s);";
298                 $sdname         = DB::quoteValue($name);
299                 $sddesc         = DB::quoteValue($desc);
300                 $sdtype         = DB::quoteValue($type);
301                 $sdincmode      = DB::quoteValue($includeMode);
302                 $sdincpref      = DB::quoteValue($includePrefix);
303                 $query = sprintf($query, sql_table('skin_desc'), $sdname, $sddesc, $sdtype, $sdincmode, $sdincpref);
304                 DB::execute($query);
305                 $newid = DB::getInsertId();
306                 
307                 $data = array(
308                         'skinid'                => $newid,
309                         'name'                  => $name,
310                         'description'   => $desc,
311                         'type'                  => $type,
312                         'includeMode'   => $includeMode,
313                         'includePrefix' => $includePrefix
314                 );
315                 $manager->notify('PostAddSkin', $data);
316                 
317                 return $newid;
318         }
319         
320         /**
321          * Skin::parse()
322          * Parse a SKIN
323          * 
324          * @param       string  $type
325          * @param       string  $path   path to file if using fileparser
326          * @return      void
327          */
328         public function parse($type, $path='')
329         {
330                 global $currentSkinName, $manager, $CONF, $DIR_NUCLEUS;
331                 
332                 $data = array(
333                         'skin' => &$this,
334                         'type' => $type
335                 );
336                 $manager->notify("Init{$this->event_identifier}Parse", $data);
337                 
338                 // include skin locale file for <%text%> tag if useable
339                 $this->includeTranslation();
340                 
341                 // set output type
342                 sendContentType($this->getContentType(), 'skin');
343                 
344                 /* FIX: should be obsoleted */
345                 $currentSkinName = $this->getName();
346                 
347                 // retrieve contents
348                 $contents = FALSE;
349 <<<<<<< HEAD
350                 if ( $type != 'fileparse' )
351                 {
352                         $contents = $this->getContentFromDB($type);
353                 }
354                 else if ( $path !== ''  && i18n::strpos(realpath($path), realpath("$DIR_NUCLEUS/../")) == 0 )
355                 {
356                         $contents = $this->getContentFromFile($path);
357 =======
358                 if ( $type == 'pluginadmin' )
359                 {
360                         $contents = $path;
361                 }
362                 else
363                 {
364                         if ( $type != 'fileparse' && $type != 'importAdmin')
365                         {
366                                 $contents = $this->getContentFromDB($type);
367                         }
368                         else if ( $path !== ''  && i18n::strpos(realpath($path), realpath("$DIR_NUCLEUS/../")) == 0 )
369                         {
370                                 $contents = $this->getContentFromFile($path);
371                         }
372 >>>>>>> skinnable-master
373                 }
374                 // use base skin if this skin does not have contents
375                 if ( $contents === FALSE )
376                 {
377                         $defskin = new SKIN($CONF['BaseSkin']);
378                         $contents = $defskin->getContentFromDB($type);
379                         if ( !$contents )
380                         {
381                                 echo _ERROR_SKIN;
382                                 return;
383                         }
384                 }
385                 
386                 $data = array(
387                         'skin'          => &$this,
388                         'type'          => $type,
389                         'contents'      => &$contents
390                 );
391                 $manager->notify("Pre{$this->event_identifier}Parse", $data);
392                 
393                 // set IncludeMode properties of parser
394                 Parser::setProperty('IncludeMode', $this->getIncludeMode());
395                 Parser::setProperty('IncludePrefix', $this->getIncludePrefix());
396                 
397                 // call action handler
398                 $action_class = $this->action_class;
399                 $handler = new $action_class($type);
400                 
401                 // register action handler to parser
402                 $parser = new Parser($handler);
403                 $parser->setSkin($this);
404                 $parser->parse($contents);
405                 
406                 $data = array(
407                         'skin' => &$this,
408                         'type' => $type
409                 );
410                 $manager->notify("Post{$this->event_identifier}Parse", $data);
411                 
412                 return;
413         }
414         
415         /**
416          * Skin::getContentFromDB()
417          * 
418          * @param       string  $skintype       skin type
419          * @return      string  content for the skin type
420          */
421         public function getContentFromDB($skintype)
422         {
423                 $query = "SELECT scontent FROM %s WHERE sdesc=%d and stype=%s;";
424                 $query = sprintf($query, sql_table('skin'), (integer) $this->id, DB::quoteValue($skintype));
425                 $res = DB::getValue($query);
426                 
427                 return $res ? $res : '';
428         }
429         
430         /**
431          * Skin::getContentFromFile()
432          * 
433          * @param       string  $fullpath       fullpath to the file to parse
434          * @return      mixed   file contents or FALSE
435          */
436         public function getContentFromFile($fullpath)
437         {
438                 $fsize = filesize($fullpath);
439                 if ( $fsize <= 0 )
440                 {
441                         return;
442                 }
443                 
444                 $fd = fopen ($fullpath, 'r');
445                 if ( $fd === FALSE )
446                 {
447                         return FALSE;
448                 }
449                 
450                 $contents = fread ($fd, $fsize);
451                 if ( $contents === FALSE )
452                 {
453                         return FALSE;
454                 }
455                 
456                 fclose ($fd);
457                 return $contents;
458         }
459         
460         /**
461          * SKIN::update()
462          * Updates the contents for one part of the skin in the database
463          * 
464          * @param       string  $type type of the skin part (e.g. index, item, search ...) 
465          * @param       string  $content new content for this skin part
466          * @return      void
467          * 
468          */
469         public function update($type, $content)
470         {
471                 global $manager;
472                 
473                 $query = "SELECT sdesc FROM %s WHERE stype=%s and sdesc=%d;";
474                 $query = sprintf($query, sql_table('skin'), DB::quoteValue($type), (integer) $this->id);
475                 $res = DB::getValue($query);
476                 
477                 $skintypeexists = !empty($res);
478 <<<<<<< HEAD
479                 $skintypevalue = ($content == true);
480 =======
481                 $skintypevalue = !empty($content);
482 >>>>>>> skinnable-master
483                 
484                 if( $skintypevalue && $skintypeexists )
485                 {
486                         $data = array(
487                                 'skinid'        =>  $this->id,
488                                 'type'          =>  $type,
489                                 'content'       => &$content
490                         );
491 <<<<<<< HEAD
492                         
493                         // PreUpdateSkinPart event
494                         $manager->notify("PreUpdate{{$this->event_identifier}}Part", $data);
495                 }
496                 else if( $skintypevalue && !$skintypeexists )
497                 {
498                         $data = array(
499                                 'skinid'        => $this->id,
500                                 'type'          => $type,
501                                 'content'       => &$content
502                         );
503                         
504                         $manager->notify("PreAdd{$this->event_identifier}Part", $data);
505                 }
506                 else if( !$skintypevalue && $skintypeexists )
507 =======
508                         $manager->notify("PreUpdate{$this->event_identifier}Part", $data);
509                 }
510                 else if( $skintypevalue )
511                 {
512                         $data = array(
513                                 'skinid'        =>  $this->id,
514                                 'type'          =>  $type,
515                                 'content'       => &$content
516                         );
517                         $manager->notify("PreAdd{$this->event_identifier}Part", $data);
518                 }
519                 else if( $skintypeexists )
520 >>>>>>> skinnable-master
521                 {
522                         $data = array(
523                                 'skinid'        => $this->id,
524                                 'type'          => $type
525                         );
526 <<<<<<< HEAD
527                         
528 =======
529 >>>>>>> skinnable-master
530                         $manager->notify("PreDelete{$this->event_identifier}Part", $data);
531                 }
532                 
533                 // delete old thingie
534 <<<<<<< HEAD
535                 $query = "DELETE FROM %s WHERE stype=%s and sdesc=%d";
536 =======
537                 $query = "DELETE FROM %s WHERE stype=%s and sdesc=%d;";
538 >>>>>>> skinnable-master
539                 $query = sprintf($query, sql_table('skin'), DB::quoteValue($type), (integer) $this->id);
540                 DB::execute($query);
541                 
542                 // write new thingie
543                 if ( $content )
544                 {
545 <<<<<<< HEAD
546                         $query = "INSERT INTO %s (scontent, stype, sdesc) VALUE (%s, %s, %d)";
547 =======
548                         $query = "INSERT INTO %s (scontent, stype, sdesc) VALUES (%s, %s, %d);";
549 >>>>>>> skinnable-master
550                         $query = sprintf($query, sql_table('skin'), DB::quoteValue($content), DB::quoteValue($type), (integer) $this->id);
551                         DB::execute($query);
552                 }
553                 
554                 if( $skintypevalue && $skintypeexists )
555                 {
556                         $data = array(
557 <<<<<<< HEAD
558                                 'skinid'        => $this->id,
559                                 'type'          => $type,
560                                 'content'       => &$content
561                         );
562                         
563                         // PostUpdateSkinPart event
564                         $manager->notify("PostUpdate{$this->event_identifier}Part", $data);
565                 }
566                 else if( $skintypevalue && (!$skintypeexists) )
567                 {
568                         $data = array(
569                                 'skinid'        => $this->id,
570                                 'type'          => $type,
571                                 'content'       => &$content
572                         );
573                         
574                         // PostAddSkinPart event
575                         $manager->notify("PostAdd{$this->event_identifier}Part", $data);
576                 }
577                 else if( (!$skintypevalue) && $skintypeexists )
578 =======
579                                 'skinid'        =>  $this->id,
580                                 'type'          =>  $type,
581                                 'content'       => &$content
582                         );
583                         $manager->notify("PostUpdate{$this->event_identifier}Part", $data);
584                 }
585                 else if( $skintypevalue )
586                 {
587                         $data = array(
588                                 'skinid'        =>  $this->id,
589                                 'type'          =>  $type,
590                                 'content'       => &$content
591                         );
592                         $manager->notify("PostAdd{$this->event_identifier}Part", $data);
593                 }
594                 else if( $skintypeexists )
595 >>>>>>> skinnable-master
596                 {
597                         $data = array(
598                                 'skinid'        => $this->id,
599                                 'type'          => $type
600                         );
601 <<<<<<< HEAD
602                         
603 =======
604 >>>>>>> skinnable-master
605                         $manager->notify("PostDelete{$this->event_identifier}Part", $data);
606                 }
607                 return;
608         }
609         
610         /**
611          * Skin::deleteAllParts()
612          * Deletes all skin parts from the database
613          * 
614          * @param       void
615          * @return      void
616          */
617         public function deleteAllParts()
618         {
619                 $query = "DELETE FROM %s WHERE sdesc=%d;";
620                 $query = sprintf($query, sql_table('skin'), (integer) $this->id);
621                 DB::execute($query);
622         }
623         
624         /**
625          * Skin::updateGeneralInfo()
626          * Updates the general information about the skin
627          * 
628          * @param       string  $name                   name of the skin
629          * @param       string  $desc                   description of the skin
630          * @param       string  $type                   type of the skin
631          * @param       string  $includeMode    include mode of the skin
632          * @param       string  $includePrefix  include prefix of the skin
633          * @return      void
634          */
635         public function updateGeneralInfo($name, $desc, $type = 'text/html', $includeMode = 'normal', $includePrefix = '')
636         {
637                 $name                   = DB::quoteValue($name);
638                 $desc                   = DB::quoteValue($desc);
639                 $type                   = DB::quoteValue($type);
640                 $includeMode    = DB::quoteValue($includeMode);
641                 $includePrefix  = DB::quoteValue($includePrefix);
642                 
643                 $query ="UPDATE %s SET sdname=%s, sddesc=%s, sdtype=%s, sdincmode=%s, sdincpref=%s WHERE sdnumber=%d";
644                 $query = sprintf($query, sql_table('skin_desc'), $name, $desc, $type, $includeMode, $includePrefix, (integer) $this->id);
645                 
646                 DB::execute($query);
647                 return;
648         }
649         
650         /**
651          * Skin::includeTranslation()
652          * 
653          * @param       void
654          * @return      void
655          */
656         private function includeTranslation()
657         {
658                 global $DIR_SKINS;
659                 
660                 $locale = i18n::get_current_locale() . '.' . i18n::get_current_charset();
661                 
662                 if( $this->includeMode == "normal" )
663                 {
664                         $filename = "./locales/{$locale}.php";
665                 }
666                 else if( $this->includeMode == "skindir" )
667                 {
668                         if ( $this->includePrefix == '' )
669                         {
670                                 $filename = "{$DIR_SKINS}locales/{$locale}.php";
671                         }
672                         else
673                         {
674                                 $filename = "{$DIR_SKINS}{$this->includePrefix}locales/{$locale}.php";
675                         }
676                 }
677                 else
678                 {
679                         return;
680                 }
681                 
682                 if ( !file_exists($filename) )
683                 {
684                         return;
685                 }
686                 
687                 include_once($filename);
688                 
689                 return;
690         }
691         
692         /**
693 <<<<<<< HEAD
694          * Skin::getDefaultTypes()
695 =======
696          * Skin::getNormalTypes()
697 >>>>>>> skinnable-master
698          * 
699          * @param       string  void
700          * @return      array   default skin types
701          */
702 <<<<<<< HEAD
703         public function getDefaultTypes()
704         {
705                 return call_user_func(array($this->action_class, 'getAvailableSkinTypes'));
706 =======
707         public function getNormalTypes()
708         {
709                 return call_user_func(array($this->action_class, 'getNormalSkinTypes'));
710 >>>>>>> skinnable-master
711         }
712         
713         /**
714          * Skin::getAvailableTypes()
715          * 
716          * @param       string  void
717          * @return      array   registered skin types
718          */
719         public function getAvailableTypes()
720         {
721 <<<<<<< HEAD
722                 $default_skintypes = $this->getDefaultTypes();
723 =======
724                 $default_skintypes = $this->getNormalTypes();
725 >>>>>>> skinnable-master
726                 $query = "SELECT stype FROM %s WHERE sdesc=%d;";
727                 $query = sprintf($query, sql_table('skin'), (integer) $this->id);
728                 
729                 /* NOTE: force to put default types in the beginning */
730                 $in_default = array();
731                 $no_default = array();
732                 
733                 $res = DB::getResult($query);
734                 foreach ( $res as $row )
735                 {
736                         if ( !array_key_exists($row['stype'], $default_skintypes) )
737                         {
738                                 $no_default[$row['stype']] = FALSE;
739                         }
740                         else
741                         {
742                                 $in_default[$row['stype']] = $default_skintypes[$row['stype']];
743                         }
744                 }
745                 
746                 return array_merge($in_default, $no_default);
747         }
748         
749         /**
750          * Skin::getAllowedActionsForType()
751          * Get the allowed actions for a skin type
752          * returns an array with the allowed actions
753 <<<<<<< HEAD
754          * 
755 =======
756          * @return      array   allowed action types
757 >>>>>>> skinnable-master
758          * @param       string  $skintype       type of the skin
759          * @return      array   allowed action types
760          */
761         public function getAllowedActionsForType($skintype)
762         {
763                 $handler = new $this->action_class($skintype);
764                 return $handler->getAvailableActions();
765         }
766         
767 }