OSDN Git Service

CHANGE: 管理画面用スキンに<%pagehead%><%pagefoot%>を追加。
[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                 \r
376                 // register action handler to parser\r
377                 $parser = new Parser($handler);\r
378                 $parser->setSkin($this);\r
379                 $parser->parse($contents);\r
380                 \r
381                 $data = array(
382                         'skin' => &$this,
383                         'type' => $type
384                 );
385                 $manager->notify("Post{$this->event_identifier}Parse", $data);
386                 
387                 return;\r
388         }\r
389         \r
390         /**\r
391          * Skin::getContentFromDB()\r
392          * \r
393          * @param       string  $skintype       skin type\r
394          * @return      string  content for the skin type\r
395          */\r
396         public function getContentFromDB($skintype)\r
397         {\r
398                 $query = "SELECT scontent FROM %s WHERE sdesc=%d and stype=%s;";\r
399                 $query = sprintf($query, sql_table('skin'), (integer) $this->id, DB::quoteValue($skintype));\r
400                 $res = DB::getValue($query);\r
401                 \r
402                 return $res ? $res : '';\r
403         }\r
404         \r
405         /**\r
406          * Skin::getContentFromFile()\r
407          * \r
408          * @param       string  $fullpath       fullpath to the file to parse\r
409          * @return      mixed   file contents or FALSE\r
410          */\r
411         public function getContentFromFile($fullpath)\r
412         {\r
413                 $fsize = filesize($fullpath);\r
414                 if ( $fsize <= 0 )\r
415                 {\r
416                         return;\r
417                 }\r
418                 \r
419                 $fd = fopen ($fullpath, 'r');\r
420                 if ( $fd === FALSE )\r
421                 {\r
422                         return FALSE;\r
423                 }\r
424                 \r
425                 $contents = fread ($fd, $fsize);\r
426                 if ( $contents === FALSE )\r
427                 {\r
428                         return FALSE;\r
429                 }\r
430                 \r
431                 fclose ($fd);\r
432                 return $contents;\r
433         }\r
434         \r
435         /**\r
436          * SKIN::update()\r
437          * Updates the contents for one part of the skin in the database\r
438          * \r
439          * @param       string  $type type of the skin part (e.g. index, item, search ...) \r
440          * @param       string  $content new content for this skin part\r
441          * @return      void\r
442          * \r
443          */\r
444         public function update($type, $content)\r
445         {\r
446                 global $manager;\r
447                 \r
448                 $query = "SELECT sdesc FROM %s WHERE stype=%s and sdesc=%d;";\r
449                 $query = sprintf($query, sql_table('skin'), DB::quoteValue($type), (integer) $this->id);\r
450                 $res = DB::getValue($query);\r
451                 \r
452                 $skintypeexists = !empty($res);\r
453                 $skintypevalue = ($content == true);\r
454                 \r
455                 if( $skintypevalue && $skintypeexists )\r
456                 {\r
457                         $data = array(\r
458                                 'skinid'        =>  $this->id,\r
459                                 'type'          =>  $type,\r
460                                 'content'       => &$content\r
461                         );\r
462                         \r
463                         // PreUpdateSkinPart event\r
464                         $manager->notify("PreUpdate{{$this->event_identifier}}Part", $data);\r
465                 }\r
466                 else if( $skintypevalue && !$skintypeexists )\r
467                 {\r
468                         $data = array(\r
469                                 'skinid'        => $this->id,\r
470                                 'type'          => $type,\r
471                                 'content'       => &$content\r
472                         );\r
473                         \r
474                         $manager->notify("PreAdd{$this->event_identifier}Part", $data);\r
475                 }\r
476                 else if( !$skintypevalue && $skintypeexists )\r
477                 {\r
478                         $data = array(\r
479                                 'skinid'        => $this->id,\r
480                                 'type'          => $type\r
481                         );\r
482                         \r
483                         $manager->notify("PreDelete{$this->event_identifier}Part", $data);\r
484                 }\r
485                 \r
486                 // delete old thingie\r
487                 $query = "DELETE FROM %s WHERE stype=%s and sdesc=%d";\r
488                 $query = sprintf($query, sql_table('skin'), DB::quoteValue($type), (integer) $this->id);\r
489                 DB::execute($query);\r
490                 \r
491                 // write new thingie\r
492                 if ( $content )\r
493                 {\r
494                         $query = "INSERT INTO %s (scontent, stype, sdesc) VALUE (%s, %s, %d)";\r
495                         $query = sprintf($query, sql_table('skin'), DB::quoteValue($content), DB::quoteValue($type), (integer) $this->id);\r
496                         DB::execute($query);\r
497                 }\r
498                 \r
499                 if( $skintypevalue && $skintypeexists )\r
500                 {\r
501                         $data = array(\r
502                                 'skinid'        => $this->id,\r
503                                 'type'          => $type,\r
504                                 'content'       => &$content\r
505                         );\r
506                         \r
507                         // PostUpdateSkinPart event\r
508                         $manager->notify("PostUpdate{$this->event_identifier}Part", $data);\r
509                 }\r
510                 else if( $skintypevalue && (!$skintypeexists) )\r
511                 {\r
512                         $data = array(\r
513                                 'skinid'        => $this->id,\r
514                                 'type'          => $type,\r
515                                 'content'       => &$content\r
516                         );\r
517                         \r
518                         // PostAddSkinPart event\r
519                         $manager->notify("PostAdd{$this->event_identifier}Part", $data);\r
520                 }\r
521                 else if( (!$skintypevalue) && $skintypeexists )\r
522                 {\r
523                         $data = array(\r
524                                 'skinid'        => $this->id,\r
525                                 'type'          => $type\r
526                         );\r
527                         \r
528                         $manager->notify("PostDelete{$this->event_identifier}Part", $data);\r
529                 }\r
530                 return;\r
531         }\r
532         \r
533         /**\r
534          * Skin::deleteAllParts()\r
535          * Deletes all skin parts from the database\r
536          * \r
537          * @param       void\r
538          * @return      void\r
539          */\r
540         public function deleteAllParts()\r
541         {\r
542                 $query = "DELETE FROM %s WHERE sdesc=%d;";\r
543                 $query = sprintf($query, sql_table('skin'), (integer) $this->id);\r
544                 DB::execute($query);\r
545         }\r
546         \r
547         /**\r
548          * Skin::updateGeneralInfo()\r
549          * Updates the general information about the skin\r
550          * \r
551          * @param       string  $name                   name of the skin\r
552          * @param       string  $desc                   description of the skin\r
553          * @param       string  $type                   type of the skin\r
554          * @param       string  $includeMode    include mode of the skin\r
555          * @param       string  $includePrefix  include prefix of the skin\r
556          * @return      void\r
557          */\r
558         public function updateGeneralInfo($name, $desc, $type = 'text/html', $includeMode = 'normal', $includePrefix = '')\r
559         {\r
560                 $name                   = DB::quoteValue($name);\r
561                 $desc                   = DB::quoteValue($desc);\r
562                 $type                   = DB::quoteValue($type);\r
563                 $includeMode    = DB::quoteValue($includeMode);\r
564                 $includePrefix  = DB::quoteValue($includePrefix);\r
565                 \r
566                 $query ="UPDATE %s SET sdname=%s, sddesc=%s, sdtype=%s, sdincmode=%s, sdincpref=%s WHERE sdnumber=%d";\r
567                 $query = sprintf($query, sql_table('skin_desc'), $name, $desc, $type, $includeMode, $includePrefix, (integer) $this->id);\r
568                 \r
569                 DB::execute($query);\r
570                 return;\r
571         }\r
572         \r
573         /**\r
574          * Skin::includeTranslation()\r
575          * \r
576          * @param       void\r
577          * @return      void\r
578          */\r
579         private function includeTranslation()\r
580         {\r
581                 global $DIR_SKINS;\r
582                 \r
583                 $locale = i18n::get_current_locale() . '.' . i18n::get_current_charset();\r
584                 \r
585                 if( $this->includeMode == "normal" )\r
586                 {\r
587                         $filename = "./locales/{$locale}.php";\r
588                 }\r
589                 else if( $this->includeMode == "skindir" )\r
590                 {\r
591                         if ( $this->includePrefix == '' )\r
592                         {\r
593                                 $filename = "{$DIR_SKINS}locales/{$locale}.php";\r
594                         }\r
595                         else\r
596                         {\r
597                                 $filename = "{$DIR_SKINS}{$this->includePrefix}locales/{$locale}.php";\r
598                         }\r
599                 }\r
600                 else\r
601                 {\r
602                         return;\r
603                 }\r
604                 \r
605                 if ( !file_exists($filename) )\r
606                 {\r
607                         return;\r
608                 }\r
609                 \r
610                 include_once($filename);\r
611                 \r
612                 return;\r
613         }\r
614         \r
615         /**\r
616          * Skin::getDefaultTypes()\r
617          * \r
618          * @param       string  void\r
619          * @return      array   default skin types\r
620          */\r
621         public function getDefaultTypes()\r
622         {\r
623                 return call_user_func(array($this->action_class, 'getAvailableSkinTypes'));\r
624         }\r
625         \r
626         /**\r
627          * Skin::getAvailableTypes()\r
628          * \r
629          * @param       string  void\r
630          * @return      array   registered skin types\r
631          */\r
632         public function getAvailableTypes()\r
633         {\r
634                 $default_skintypes = $this->getDefaultTypes();\r
635                 $query = "SELECT stype FROM %s WHERE sdesc=%d;";\r
636                 $query = sprintf($query, sql_table('skin'), (integer) $this->id);\r
637                 \r
638                 /* NOTE: force to put default types in the beginning */\r
639                 $in_default = array();\r
640                 $no_default = array();\r
641                 \r
642                 $res = DB::getResult($query);\r
643                 foreach ( $res as $row )\r
644                 {\r
645                         if ( !array_key_exists($row['stype'], $default_skintypes) )\r
646                         {\r
647                                 $no_default[$row['stype']] = FALSE;\r
648                         }\r
649                         else\r
650                         {\r
651                                 $in_default[$row['stype']] = $default_skintypes[$row['stype']];\r
652                         }\r
653                 }\r
654                 \r
655                 return array_merge($in_default, $no_default);\r
656         }\r
657         \r
658         /**\r
659          * Skin::getAllowedActionsForType()\r
660          * Get the allowed actions for a skin type\r
661          * returns an array with the allowed actions\r
662          * @return      array   allowed action types\r
663          * @param       string  $skintype       type of the skin\r
664          * @return      array   allowed action types\r
665          */\r
666         public function getAllowedActionsForType($skintype)\r
667         {\r
668                 $handler = new $this->action_class($skintype);\r
669                 return $handler->getAvailableActions();\r
670         }\r
671         \r
672 }\r