<?php
 class vB_Products { use vB_Trait_NoSerialize; private $options; private $products = []; private $packages = []; private $productObjects = []; private $packagesDir = ""; const DEFAULT_VBULLETIN_PRODUCTS = [ 'nativo', 'viglink', 'googlelogin', 'wordpresslogin', 'shopify', 'vbfilescan', ]; public function __construct($products, $packagesDir, $autoinstall) { $this->products = $products; $this->packages = $this->getPackagesInternal($packagesDir); $this->options = vB::getDatastore()->getValue('options'); $this->packagesDir = $packagesDir; if ($autoinstall) { $this->autoinstall($this->packages, $products, $packagesDir); } foreach ($this->products AS $name => $enabled) { if ($name == 'vbulletin') { continue; } if ($enabled) { $class = $name . '_Product'; if (class_exists($class)) { $object = new $class; if ($this->isCompatible($object)) { $this->productObjects[$name] = $object; } } } } } private function isCompatible($object) { $currentVersion = $this->options['templateversion']; if (empty($object->vbMinVersion)) { $minOk = true; } else { $minOk = vB_Library_Functions::isNewerVersion($currentVersion, $object->vbMinVersion, true); } if (empty($object->vbMaxVersion)) { $maxOk = true; } else { $maxOk = vB_Library_Functions::isNewerVersion($object->vbMaxVersion, $currentVersion, true); } return ($minOk AND $maxOk); } private function autoinstall($packages, $products, $packagesDir) { foreach ($packages AS $package) { if (!isset($products[$package])) { $xmlDir = "$packagesDir/$package/xml"; $class = $package . '_Product'; if (class_exists($class) AND property_exists($class, 'AutoInstall') AND $class::$AutoInstall) { $info = vB_Library_Functions::installProduct($package, $xmlDir); if ($info !== false) { $this->products[$package] = $info['active']; } } } } } public function getHookClasses() { $hookClasses = []; foreach ($this->productObjects AS $name => $object) { if (isset($object->hookClasses) AND is_array($object->hookClasses)) { foreach ($object->hookClasses AS $hookClass) { $hookClasses[] = $hookClass; } } } return $hookClasses; } public function getApiClassesByProduct() { $list = []; foreach ($this->packages AS $package) { $apiDir = $this->packagesDir . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR . 'api' ; $res = $this->loadClassList($apiDir, $package); if ($res) { $list[$package] = $res; } } return $list; } private function loadClassList($eDir, $package) { $results = []; $this->loadExtensionListFolder($eDir, $package, $results); return $results; } private function loadExtensionListFolder($eDir, $package, &$results, $prefix = '') { if (is_dir($eDir)) { foreach (new DirectoryIterator($eDir) AS $file) { if (!$file->isDot()) { if ($file->isDir()) { self::loadExtensionListFolder( $file->getPathname(), $package, $results, $prefix . $file->getBasename() . '_' ); } else if (strcasecmp($file->getExtension(), 'php') === 0) { $controller = $package . ':'. $prefix . ucfirst(pathinfo($file->getFilename(), PATHINFO_FILENAME)); $class = vB_Api::getApiClassName($controller); $isApiClass = ($class AND class_exists($class, false) AND is_subclass_of($class, 'vB_Api') AND !is_subclass_of($class, 'vB_Api_Extensions') ); if ($isApiClass) { $results[] = ['classname' => $class]; } } } } } } private static function loadExtensionList($eDir, $package, $options, $products) { $folders = []; self::loadExtensionListFolder($eDir, $package, $options, $products, $folders); return $folders; } public function getProducts() { return $this->products; } public function getPackages() { return $this->packages; } public function getProductObjects() { return $this->productObjects; } public function getDisabledProductObjects() { $disabled = []; foreach ($this->products AS $name => $enabled) { if ($name == 'vbulletin') { continue; } $class = $name . '_Product'; if (class_exists($class)) { $object = new $class; if (!$this->isCompatible($object) OR !$enabled) { $disabled[$name] = $object; } } } return $disabled; } private function getPackagesInternal($packagesDir) { $folders = []; if (is_dir($packagesDir)) { foreach (new DirectoryIterator($packagesDir) AS $file) { if (!$file->isDot() AND $file->isDir()) { $folders[] = $file->getFilename(); } } } return $folders; } } 