Proposed extension info change to allow getting info for unloaded extensions
This commit is contained in:
		
							parent
							
								
									e6411c32aa
								
							
						
					
					
						commit
						3d1b964812
					
				| @ -26,6 +26,7 @@ $_tracer->begin("Opening files"); | |||||||
| $_shm_files = array_merge( | $_shm_files = array_merge( | ||||||
|     zglob("core/*.php"), |     zglob("core/*.php"), | ||||||
|     zglob("core/{".ENABLED_MODS."}/*.php"), |     zglob("core/{".ENABLED_MODS."}/*.php"), | ||||||
|  |     zglob("ext/{".ENABLED_EXTS."}/info.php"), | ||||||
|     zglob("ext/{".ENABLED_EXTS."}/main.php") |     zglob("ext/{".ENABLED_EXTS."}/main.php") | ||||||
| ); | ); | ||||||
| foreach ($_shm_files as $_shm_filename) { | foreach ($_shm_files as $_shm_filename) { | ||||||
|  | |||||||
| @ -89,19 +89,27 @@ abstract class Extension | |||||||
|     /** @var Themelet this theme's Themelet object */ |     /** @var Themelet this theme's Themelet object */ | ||||||
|     public $theme; |     public $theme; | ||||||
| 
 | 
 | ||||||
|  |     public $info; | ||||||
|  | 
 | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
|         $this->theme = $this->get_theme_object(get_called_class()); |         $class = get_called_class(); | ||||||
|  |         $this->theme = $this->get_theme_object($class); | ||||||
|  |         $this->info = ExtensionInfo::get_for_extension($class); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function is_live(): bool |     public function is_supported(): bool | ||||||
|     { |     { | ||||||
|  |         if($this->info!=null) { | ||||||
|  |             return $this->info->supported; | ||||||
|  |         } else { | ||||||
|             global $database; |             global $database; | ||||||
|             return ( |             return ( | ||||||
|                 empty($this->db_support) || |                 empty($this->db_support) || | ||||||
|                 in_array($database->get_driver_name(), $this->db_support) |                 in_array($database->get_driver_name(), $this->db_support) | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Find the theme object for a given extension. |      * Find the theme object for a given extension. | ||||||
| @ -130,6 +138,45 @@ abstract class Extension | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | abstract class ExtensionInfo | ||||||
|  | { | ||||||
|  |     public $name; | ||||||
|  |     public $authors; | ||||||
|  |     public $link; | ||||||
|  |     public $license; | ||||||
|  |     public $version; | ||||||
|  |     public $visibility; | ||||||
|  |     public $description; | ||||||
|  |     public $documentation; | ||||||
|  |     public $supported; | ||||||
|  |     public $db_support; | ||||||
|  | 
 | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         $this->supported = $this->is_supported(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function is_supported(): bool | ||||||
|  |     { | ||||||
|  |         global $database; | ||||||
|  |         return ( | ||||||
|  |             empty($this->db_support) || | ||||||
|  |             in_array($database->get_driver_name(), $this->db_support) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static function get_for_extension(string $base): ?ExtensionInfo | ||||||
|  |     { | ||||||
|  |         $normal = $base.'Info'; | ||||||
|  | 
 | ||||||
|  |         if (class_exists($normal)) { | ||||||
|  |             return new $normal(); | ||||||
|  |         } else { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Class FormatterExtension |  * Class FormatterExtension | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -802,3 +802,30 @@ function iterator_map_to_array(callable $callback, iterator $iter): array | |||||||
| { | { | ||||||
|     return iterator_to_array(iterator_map($callback, $iter)); |     return iterator_to_array(iterator_map($callback, $iter)); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | function get_class_from_file(string $file): string | ||||||
|  | { | ||||||
|  |     $fp = fopen($file, 'r'); | ||||||
|  |     $class = $buffer = ''; | ||||||
|  |     $i = 0; | ||||||
|  |     while (!$class) { | ||||||
|  |         if (feof($fp)) break; | ||||||
|  | 
 | ||||||
|  |         $buffer .= fread($fp, 512); | ||||||
|  |         $tokens = token_get_all($buffer); | ||||||
|  | 
 | ||||||
|  |         if (strpos($buffer, '{') === false) continue; | ||||||
|  | 
 | ||||||
|  |         for (;$i<count($tokens);$i++) { | ||||||
|  |             if ($tokens[$i][0] === T_CLASS) { | ||||||
|  |                 for ($j=$i+1;$j<count($tokens);$j++) { | ||||||
|  |                     if ($tokens[$j] === '{') { | ||||||
|  |                         $class = $tokens[$i+2][1]; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return $class; | ||||||
|  | } | ||||||
| @ -44,7 +44,7 @@ function _set_event_listeners(): void | |||||||
|             $extension = new $class(); |             $extension = new $class(); | ||||||
| 
 | 
 | ||||||
|             // skip extensions which don't support our current database
 |             // skip extensions which don't support our current database
 | ||||||
|             if (!$extension->is_live()) { |             if (!$extension->is_supported()) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -93,7 +93,7 @@ function ext_is_live(string $ext_name): bool | |||||||
|     if (class_exists($ext_name)) { |     if (class_exists($ext_name)) { | ||||||
|         /** @var Extension $ext */ |         /** @var Extension $ext */ | ||||||
|         $ext = new $ext_name(); |         $ext = new $ext_name(); | ||||||
|         return $ext->is_live(); |         return $ext->is_supported(); | ||||||
|     } |     } | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
|  | |||||||
| @ -12,12 +12,12 @@ | |||||||
|  *   extensions and read their documentation |  *   extensions and read their documentation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| function __extman_extcmp(ExtensionInfo $a, ExtensionInfo $b): int | function __extman_extcmp(ExtensionManagerInfo $a, ExtensionManagerInfo $b): int | ||||||
| { | { | ||||||
|     return strcmp($a->name, $b->name); |     return strcmp($a->name, $b->name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class ExtensionInfo | class ExtensionManagerInfo | ||||||
| { | { | ||||||
|     public $ext_name; |     public $ext_name; | ||||||
|     public $name; |     public $name; | ||||||
| @ -28,20 +28,42 @@ class ExtensionInfo | |||||||
|     public $version; |     public $version; | ||||||
|     public $visibility; |     public $visibility; | ||||||
|     public $enabled; |     public $enabled; | ||||||
|  |     public $supported; | ||||||
| 
 | 
 | ||||||
|     public function __construct($main) |     public function __construct($main) | ||||||
|     { |     { | ||||||
|         $matches = []; |         $matches = []; | ||||||
|         $lines = file($main); |  | ||||||
|         $number_of_lines = count($lines); |  | ||||||
|         preg_match("#ext/(.*)/main.php#", $main, $matches); |         preg_match("#ext/(.*)/main.php#", $main, $matches); | ||||||
|         $this->ext_name = $matches[1]; |         $this->ext_name = $matches[1]; | ||||||
|         $this->name = $this->ext_name; |         $this->name = $this->ext_name; | ||||||
|         $this->enabled = $this->is_enabled($this->ext_name); |         $this->enabled = $this->is_enabled($this->ext_name); | ||||||
|  | 
 | ||||||
|  |         if(file_exists("ext/{$this->ext_name}/info.php")) { | ||||||
|  |             include_once "ext/{$this->ext_name}/info.php"; | ||||||
|  |             $class = get_class_from_file("ext/{$this->ext_name}/info.php"); | ||||||
|  |             $info = new $class(); | ||||||
|  | 
 | ||||||
|  |             $this->name = $info->name; | ||||||
|  |             $this->link = $info->link; | ||||||
|  |             foreach ($info->authors as $key=>$value){ | ||||||
|  |                 $this->authors[] = new ExtensionAuthor($key, $value); | ||||||
|  |             } | ||||||
|  |             $this->description = $info->description; | ||||||
|  |             $this->documentation = $info->documentation; | ||||||
|  |             $this->version = $info->version; | ||||||
|  |             $this->visibility = $info->visibility; | ||||||
|  |             $this->supported = $info->supported; | ||||||
|  |         } else { | ||||||
|             $this->authors = []; |             $this->authors = []; | ||||||
| 
 | 
 | ||||||
|         for ($i = 0; $i < $number_of_lines; $i++) { |             $handle = fopen($main, "r"); | ||||||
|             $line = $lines[$i]; |             if ($handle === null) { | ||||||
|  |                 throw new Exception("Could not open extension file $main"); | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 $line = fgets($handle); | ||||||
|  | 
 | ||||||
|  |                 while ($line !== false) { | ||||||
|                     if (preg_match("/Name: (.*)/", $line, $matches)) { |                     if (preg_match("/Name: (.*)/", $line, $matches)) { | ||||||
|                         $this->name = $matches[1]; |                         $this->name = $matches[1]; | ||||||
|                     } elseif (preg_match("/Visibility: (.*)/", $line, $matches)) { |                     } elseif (preg_match("/Visibility: (.*)/", $line, $matches)) { | ||||||
| @ -66,22 +88,29 @@ class ExtensionInfo | |||||||
|                         $this->description = $matches[2]; |                         $this->description = $matches[2]; | ||||||
|                         $start = $matches[1] . " "; |                         $start = $matches[1] . " "; | ||||||
|                         $start_len = strlen($start); |                         $start_len = strlen($start); | ||||||
|                 while (substr($lines[$i + 1], 0, $start_len) == $start) { |                         while (($line = fgets($handle)) !== false && | ||||||
|                     $this->description .= " " . substr($lines[$i + 1], $start_len); |                             substr($line, 0, $start_len) == $start) { | ||||||
|                     $i++; |                             $this->description .= " " . substr($line, $start_len); | ||||||
|                         } |                         } | ||||||
|  |                         continue; | ||||||
|                     } elseif (preg_match("/(.*)Documentation: ?(.*)/", $line, $matches)) { |                     } elseif (preg_match("/(.*)Documentation: ?(.*)/", $line, $matches)) { | ||||||
|                         $this->documentation = $matches[2]; |                         $this->documentation = $matches[2]; | ||||||
|                         $start = $matches[1] . " "; |                         $start = $matches[1] . " "; | ||||||
|                         $start_len = strlen($start); |                         $start_len = strlen($start); | ||||||
|                 while (substr($lines[$i + 1], 0, $start_len) == $start) { |                         while (($line = fgets($handle)) !== false && | ||||||
|                     $this->documentation .= " " . substr($lines[$i + 1], $start_len); |                             substr($line, 0, $start_len) == $start) { | ||||||
|                     $i++; |                             $this->documentation .= " " . substr($line, $start_len); | ||||||
|                         } |                         } | ||||||
|                         $this->documentation = str_replace('$site', make_http(get_base_href()), $this->documentation); |                         $this->documentation = str_replace('$site', make_http(get_base_href()), $this->documentation); | ||||||
|  |                         continue; | ||||||
|                     } elseif (preg_match("/\*\//", $line, $matches)) { |                     } elseif (preg_match("/\*\//", $line, $matches)) { | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
|  |                     $line = fgets($handle); | ||||||
|  |                 } | ||||||
|  |             } finally { | ||||||
|  |                 fclose($handle); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -142,8 +171,8 @@ class ExtManager extends Extension | |||||||
| 
 | 
 | ||||||
|         if ($event->page_matches("ext_doc")) { |         if ($event->page_matches("ext_doc")) { | ||||||
|             $ext = $event->get_arg(0); |             $ext = $event->get_arg(0); | ||||||
|             if (file_exists("ext/$ext/main.php")) { |             if (file_exists("ext/$ext/info.php")) { | ||||||
|                 $info = new ExtensionInfo("ext/$ext/main.php"); |                 $info = new ExtensionManagerInfo("ext/$ext/main.php"); | ||||||
|                 $this->theme->display_doc($page, $info); |                 $this->theme->display_doc($page, $info); | ||||||
|             } else { |             } else { | ||||||
|                 $this->theme->display_table($page, $this->get_extensions(false), false); |                 $this->theme->display_table($page, $this->get_extensions(false), false); | ||||||
| @ -196,7 +225,7 @@ class ExtManager extends Extension | |||||||
|             $exts = zglob("ext/{" . ENABLED_EXTS . "}/main.php"); |             $exts = zglob("ext/{" . ENABLED_EXTS . "}/main.php"); | ||||||
|         } |         } | ||||||
|         foreach ($exts as $main) { |         foreach ($exts as $main) { | ||||||
|             $extensions[] = new ExtensionInfo($main); |             $extensions[] = new ExtensionManagerInfo($main); | ||||||
|         } |         } | ||||||
|         usort($extensions, "__extman_extcmp"); |         usort($extensions, "__extman_extcmp"); | ||||||
|         return $extensions; |         return $extensions; | ||||||
|  | |||||||
| @ -29,8 +29,13 @@ class ExtManagerTheme extends Themelet | |||||||
|             $h_name = html_escape(empty($extension->name) ? $extension->ext_name : $extension->name); |             $h_name = html_escape(empty($extension->name) ? $extension->ext_name : $extension->name); | ||||||
|             $h_description = html_escape($extension->description); |             $h_description = html_escape($extension->description); | ||||||
|             $h_link = make_link("ext_doc/" . url_escape($extension->ext_name)); |             $h_link = make_link("ext_doc/" . url_escape($extension->ext_name)); | ||||||
|             $h_enabled = ($extension->enabled === true ? " checked='checked'" : ($extension->enabled === false ? "" : " disabled checked='checked'")); | 
 | ||||||
|             $h_enabled_box = $editable ? "<td><input type='checkbox' name='ext_" . html_escape($extension->ext_name) . "' id='ext_" . html_escape($extension->ext_name) . "'$h_enabled></td>" : ""; |             $h_enabled = ($extension->enabled === true ? " checked='checked'" : ($extension->enabled === false ? "" : " checked='checked'")); | ||||||
|  |             $h_disabled = ($extension->supported===false || $extension->enabled===null? " disabled ": " " ); | ||||||
|  | 
 | ||||||
|  |             //baseline_open_in_new_black_18dp.png
 | ||||||
|  | 
 | ||||||
|  |             $h_enabled_box = $editable ? "<td><input type='checkbox' name='ext_" . html_escape($extension->ext_name) . "' id='ext_" . html_escape($extension->ext_name) . "'$h_disabled $h_enabled></td>" : ""; | ||||||
|             $h_docs = ($extension->documentation ? "<a href='$h_link'>■</a>" : ""); //TODO: A proper "docs" symbol would be preferred here.
 |             $h_docs = ($extension->documentation ? "<a href='$h_link'>■</a>" : ""); //TODO: A proper "docs" symbol would be preferred here.
 | ||||||
| 
 | 
 | ||||||
|             $html .= " |             $html .= " | ||||||
| @ -38,7 +43,7 @@ class ExtManagerTheme extends Themelet | |||||||
| 					{$h_enabled_box} | 					{$h_enabled_box} | ||||||
| 					<td><label for='ext_" . html_escape($extension->ext_name) . "'>{$h_name}</label></td> | 					<td><label for='ext_" . html_escape($extension->ext_name) . "'>{$h_name}</label></td> | ||||||
| 					<td>{$h_docs}</td> | 					<td>{$h_docs}</td> | ||||||
| 					<td style='text-align: left;'>{$h_description}</td> | 					<td style='text-align: left;'>{$h_description} " .($extension->supported===false ? "<b style='color:red'>Database not supported</b>" : ""). "</td> | ||||||
| 				</tr>";
 | 				</tr>";
 | ||||||
|         } |         } | ||||||
|         $h_set = $editable ? "<tfoot><tr><td colspan='5'><input type='submit' value='Set Extensions'></td></tr></tfoot>" : ""; |         $h_set = $editable ? "<tfoot><tr><td colspan='5'><input type='submit' value='Set Extensions'></td></tr></tfoot>" : ""; | ||||||
| @ -113,7 +118,7 @@ class ExtManagerTheme extends Themelet | |||||||
|     } |     } | ||||||
|     */ |     */ | ||||||
| 
 | 
 | ||||||
|     public function display_doc(Page $page, ExtensionInfo $info) |     public function display_doc(Page $page, ExtensionManagerInfo $info) | ||||||
|     { |     { | ||||||
|         $author = ""; |         $author = ""; | ||||||
|         if (count($info->authors) > 0) { |         if (count($info->authors) > 0) { | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								ext/tips/info.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ext/tips/info.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Name: Random Tip | ||||||
|  |  * Author: Sein Kraft <mail@seinkraft.info> | ||||||
|  |  * License: GPLv2 | ||||||
|  |  * Description: Show a random line of text in the subheader space | ||||||
|  |  * Documentation: | ||||||
|  |  *  Formatting is done with HTML | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TipsInfo extends ExtensionInfo | ||||||
|  | { | ||||||
|  |     public $key = "tips"; | ||||||
|  |     public $name = "Random Tip"; | ||||||
|  |     public $authors = ["Sein Kraft"=>"mail@seinkraft.info"]; | ||||||
|  |     public $license = "GPLv2"; | ||||||
|  |     public $description = "Show a random line of text in the subheader space"; | ||||||
|  |     public $documentation = "Formatting is done with HTML"; | ||||||
|  |     public $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::SQLITE]; | ||||||
|  | } | ||||||
| @ -1,12 +1,4 @@ | |||||||
| <?php | <?php | ||||||
| /** |  | ||||||
|  * Name: Random Tip |  | ||||||
|  * Author: Sein Kraft <mail@seinkraft.info> |  | ||||||
|  * License: GPLv2 |  | ||||||
|  * Description: Show a random line of text in the subheader space |  | ||||||
|  * Documentation: |  | ||||||
|  *  Formatting is done with HTML |  | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| class Tips extends Extension | class Tips extends Extension | ||||||
| { | { | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ class CustomExtManagerTheme extends ExtManagerTheme | |||||||
|         parent::display_table($page, $extensions, $editable); |         parent::display_table($page, $extensions, $editable); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function display_doc(Page $page, ExtensionInfo $info) |     public function display_doc(Page $page, ExtensionManagerInfo $info) | ||||||
|     { |     { | ||||||
|         $page->disable_left(); |         $page->disable_left(); | ||||||
|         parent::display_doc($page, $info); |         parent::display_doc($page, $info); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user