OSDN Git Service

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