91511b4d5fbc91790430c43169c387936a396fa5
[friendica.git/.git] / src / Core / Theme.php
1 <?php
2
3 /**
4  * @file src/Core/Theme.php
5  */
6
7 namespace Friendica\Core;
8
9 use Friendica\Core\Logger;
10 use Friendica\Core\System;
11
12 /**
13  * Some functions to handle themes
14  */
15 class Theme
16 {
17         /**
18          * @brief Parse theme comment in search of theme infos.
19          *
20          * like
21          * \code
22          * ..* Name: My Theme
23          *   * Description: My Cool Theme
24          * . * Version: 1.2.3
25          *   * Author: John <profile url>
26          *   * Maintainer: Jane <profile url>
27          *   *
28          * \endcode
29          * @param string $theme the name of the theme
30          * @return array
31          */
32         public static function getInfo($theme)
33         {
34                 $info = [
35                         'name' => $theme,
36                         'description' => "",
37                         'author' => [],
38                         'maintainer' => [],
39                         'version' => "",
40                         'credits' => "",
41                         'experimental' => file_exists("view/theme/$theme/experimental"),
42                         'unsupported' => file_exists("view/theme/$theme/unsupported")
43                 ];
44
45                 if (!is_file("view/theme/$theme/theme.php")) {
46                         return $info;
47                 }
48
49                 $a = \get_app();
50                 $stamp1 = microtime(true);
51                 $theme_file = file_get_contents("view/theme/$theme/theme.php");
52                 $a->saveTimestamp($stamp1, "file");
53
54                 $result = preg_match("|/\*.*\*/|msU", $theme_file, $matches);
55
56                 if ($result) {
57                         $comment_lines = explode("\n", $matches[0]);
58                         foreach ($comment_lines as $comment_line) {
59                                 $comment_line = trim($comment_line, "\t\n\r */");
60                                 if ($comment_line != "") {
61                                         list($key, $value) = array_map("trim", explode(":", $comment_line, 2));
62                                         $key = strtolower($key);
63                                         if ($key == "author") {
64                                                 $result = preg_match("|([^<]+)<([^>]+)>|", $value, $matches);
65                                                 if ($result) {
66                                                         $info['author'][] = ['name' => $matches[1], 'link' => $matches[2]];
67                                                 } else {
68                                                         $info['author'][] = ['name' => $value];
69                                                 }
70                                         } elseif ($key == "maintainer") {
71                                                 $result = preg_match("|([^<]+)<([^>]+)>|", $value, $matches);
72                                                 if ($result) {
73                                                         $info['maintainer'][] = ['name' => $matches[1], 'link' => $matches[2]];
74                                                 } else {
75                                                         $info['maintainer'][] = ['name' => $value];
76                                                 }
77                                         } elseif (array_key_exists($key, $info)) {
78                                                 $info[$key] = $value;
79                                         }
80                                 }
81                         }
82                 }
83                 return $info;
84         }
85
86         /**
87          * @brief Returns the theme's screenshot.
88          *
89          * The screenshot is expected as view/theme/$theme/screenshot.[png|jpg].
90          *
91          * @param sring $theme The name of the theme
92          * @return string
93          */
94         public static function getScreenshot($theme)
95         {
96                 $exts = ['.png', '.jpg'];
97                 foreach ($exts as $ext) {
98                         if (file_exists('view/theme/' . $theme . '/screenshot' . $ext)) {
99                                 return(System::baseUrl() . '/view/theme/' . $theme . '/screenshot' . $ext);
100                         }
101                 }
102                 return(System::baseUrl() . '/images/blank.png');
103         }
104
105         // install and uninstall theme
106         public static function uninstall($theme)
107         {
108                 Logger::log("Addons: uninstalling theme " . $theme);
109
110                 include_once "view/theme/$theme/theme.php";
111                 if (function_exists("{$theme}_uninstall")) {
112                         $func = "{$theme}_uninstall";
113                         $func();
114                 }
115         }
116
117         public static function install($theme)
118         {
119                 // silently fail if theme was removed
120
121                 if (!file_exists("view/theme/$theme/theme.php")) {
122                         return false;
123                 }
124
125                 Logger::log("Addons: installing theme $theme");
126
127                 include_once "view/theme/$theme/theme.php";
128
129                 if (function_exists("{$theme}_install")) {
130                         $func = "{$theme}_install";
131                         $func();
132                         return true;
133                 } else {
134                         Logger::log("Addons: FAILED installing theme $theme");
135                         return false;
136                 }
137         }
138
139         /**
140          * @brief Get the full path to relevant theme files by filename
141          *
142          * This function search in the theme directory (and if not present in global theme directory)
143          * if there is a directory with the file extension and  for a file with the given
144          * filename.
145          *
146          * @param string $file Filename
147          * @param string $root Full root path
148          * @return string Path to the file or empty string if the file isn't found
149          */
150         public static function getPathForFile($file, $root = '')
151         {
152                 $file = basename($file);
153
154                 // Make sure $root ends with a slash / if it's not blank
155                 if ($root !== '' && $root[strlen($root) - 1] !== '/') {
156                         $root = $root . '/';
157                 }
158                 $theme_info = \get_app()->theme_info;
159                 if (is_array($theme_info) && array_key_exists('extends', $theme_info)) {
160                         $parent = $theme_info['extends'];
161                 } else {
162                         $parent = 'NOPATH';
163                 }
164                 $theme = \get_app()->getCurrentTheme();
165                 $thname = $theme;
166                 $ext = substr($file, strrpos($file, '.') + 1);
167                 $paths = [
168                         "{$root}view/theme/$thname/$ext/$file",
169                         "{$root}view/theme/$parent/$ext/$file",
170                         "{$root}view/$ext/$file",
171                 ];
172                 foreach ($paths as $p) {
173                         // strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php)
174                         if (strpos($p, 'NOPATH') !== false) {
175                                 continue;
176                         } elseif (file_exists($p)) {
177                                 return $p;
178                         }
179                 }
180                 return '';
181         }
182
183         /**
184          * @brief Return relative path to theme stylesheet file
185          *
186          * Provide a sane default if nothing is chosen or the specified theme does not exist.
187          *
188          * @param string $theme Theme name
189          *
190          * @return string
191          */
192         public static function getStylesheetPath($theme)
193         {
194                 $a = get_app();
195
196                 $opts = (($a->profile_uid) ? '?f=&puid=' . $a->profile_uid : '');
197                 if (file_exists('view/theme/' . $theme . '/style.php')) {
198                         return 'view/theme/' . $theme . '/style.pcss' . $opts;
199                 }
200
201                 return 'view/theme/' . $theme . '/style.css';
202         }
203 }