From 4ade3452ee65734d59d83c0244821fb6d77e67f0 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 23 Feb 2020 16:39:55 +0000
Subject: [PATCH] dedupe getSubclassesOf

---
 core/extension.php  | 29 +++++++++++++++++------------
 core/polyfills.php  | 11 +++++++++++
 core/send_event.php | 38 ++++++++++++++++----------------------
 ext/et/main.php     |  7 ++-----
 4 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/core/extension.php b/core/extension.php
index f302403e..bfeaf900 100644
--- a/core/extension.php
+++ b/core/extension.php
@@ -304,19 +304,16 @@ abstract class ExtensionInfo
 
     public static function load_all_extension_info()
     {
-        foreach (get_declared_classes() as $class) {
-            $rclass = new ReflectionClass($class);
-            if (!$rclass->isAbstract() && is_subclass_of($class, "ExtensionInfo")) {
-                $extension_info = new $class();
-                if (array_key_exists($extension_info->key, self::$all_info_by_key)) {
-                    throw new ScoreException("Extension Info $class with key $extension_info->key has already been loaded");
-                }
+        foreach (getSubclassesOf("ExtensionInfo") as $class) {
+            $extension_info = new $class();
+            if (array_key_exists($extension_info->key, self::$all_info_by_key)) {
+                throw new ScoreException("Extension Info $class with key $extension_info->key has already been loaded");
+            }
 
-                self::$all_info_by_key[$extension_info->key] = $extension_info;
-                self::$all_info_by_class[$class] = $extension_info;
-                if ($extension_info->core===true) {
-                    self::$core_extensions[] = $extension_info->key;
-                }
+            self::$all_info_by_key[$extension_info->key] = $extension_info;
+            self::$all_info_by_class[$class] = $extension_info;
+            if ($extension_info->core===true) {
+                self::$core_extensions[] = $extension_info->key;
             }
         }
     }
@@ -462,4 +459,12 @@ abstract class DataHandlerExtension extends Extension
     abstract protected function check_contents(string $tmpname): bool;
     abstract protected function create_image_from_data(string $filename, array $metadata);
     abstract protected function create_thumb(string $hash, string $type): bool;
+
+    public static function get_all_supported_exts(): array {
+        $arr = [];
+        foreach(getSubclassesOf("DataHandlerExtension") as $handler) {
+            $arr = array_merge($arr, $handler->SUPPORTED_EXT);
+        }
+        return $arr;
+    }
 }
diff --git a/core/polyfills.php b/core/polyfills.php
index eb5fdc0d..930f7b78 100644
--- a/core/polyfills.php
+++ b/core/polyfills.php
@@ -341,6 +341,17 @@ function get_extension(?string $mime_type): ?string
     return ($ext ? $ext : null);
 }
 
+function getSubclassesOf(string $parent) {
+    $result = [];
+    foreach (get_declared_classes() as $class) {
+        $rclass = new ReflectionClass($class);
+        if (!$rclass->isAbstract() && is_subclass_of($class, $parent)) {
+            $result[] = $class;
+        }
+    }
+    return $result;
+}
+
 /**
  * Like glob, with support for matching very long patterns with braces.
  */
diff --git a/core/send_event.php b/core/send_event.php
index 892304ae..98a48462 100644
--- a/core/send_event.php
+++ b/core/send_event.php
@@ -35,26 +35,23 @@ function _set_event_listeners(): void
     global $_shm_event_listeners;
     $_shm_event_listeners = [];
 
-    foreach (get_declared_classes() as $class) {
-        $rclass = new ReflectionClass($class);
-        if (!$rclass->isAbstract() && is_subclass_of($class, "Extension")) {
-            /** @var Extension $extension */
-            $extension = new $class();
+    foreach (getSubclassesOf("Extension") as $class) {
+        /** @var Extension $extension */
+        $extension = new $class();
 
-            // skip extensions which don't support our current database
-            if (!$extension->info->is_supported()) {
-                continue;
-            }
+        // skip extensions which don't support our current database
+        if (!$extension->info->is_supported()) {
+            continue;
+        }
 
-            foreach (get_class_methods($extension) as $method) {
-                if (substr($method, 0, 2) == "on") {
-                    $event = substr($method, 2) . "Event";
-                    $pos = $extension->get_priority() * 100;
-                    while (isset($_shm_event_listeners[$event][$pos])) {
-                        $pos += 1;
-                    }
-                    $_shm_event_listeners[$event][$pos] = $extension;
+        foreach (get_class_methods($extension) as $method) {
+            if (substr($method, 0, 2) == "on") {
+                $event = substr($method, 2) . "Event";
+                $pos = $extension->get_priority() * 100;
+                while (isset($_shm_event_listeners[$event][$pos])) {
+                    $pos += 1;
                 }
+                $_shm_event_listeners[$event][$pos] = $extension;
             }
         }
     }
@@ -64,11 +61,8 @@ function _dump_event_listeners(array $event_listeners, string $path): void
 {
     $p = "<"."?php\n";
 
-    foreach (get_declared_classes() as $class) {
-        $rclass = new ReflectionClass($class);
-        if (!$rclass->isAbstract() && is_subclass_of($class, "Extension")) {
-            $p .= "\$$class = new $class(); ";
-        }
+    foreach (getSubclassesOf("Extension") as $class) {
+        $p .= "\$$class = new $class(); ";
     }
 
     $p .= "\$_shm_event_listeners = array(\n";
diff --git a/ext/et/main.php b/ext/et/main.php
index e19c3380..0bfb23f8 100644
--- a/ext/et/main.php
+++ b/ext/et/main.php
@@ -72,11 +72,8 @@ class ET extends Extension
         $info['stat_image_tags'] = $database->get_one("SELECT COUNT(*) FROM image_tags");
 
         $els = [];
-        foreach (get_declared_classes() as $class) {
-            $rclass = new ReflectionClass($class);
-            if (!$rclass->isAbstract() && is_subclass_of($class, "Extension")) {
-                $els[] = $class;
-            }
+        foreach (getSubclassesOf("Extension") as $class) {
+            $els[] = $class;
         }
         $info['sys_extensions'] = join(', ', $els);