[], 1 => [], ]; /** * Add a module link in the frontend * * @param string $title * @param string $url * @param string $icon * @param bool $logged_in */ public function addFrontendLink(string $title, string $url, string $icon = 'pe-7s-users', $logged_in = true) { self::$frontendLinks[$logged_in][] = [ 'title' => $title, 'url' => $url, 'icon' => $icon, ]; } /** * Get all of the frontend links * * @param mixed $logged_in * * @return array */ public function getFrontendLinks($logged_in): array { return self::$frontendLinks[$logged_in]; } /** * Add a module link in the admin panel * * @param string $title * @param string $url * @param string $icon */ public function addAdminLink(string $title, string $url, string $icon = 'pe-7s-users') { self::$adminLinks[] = [ 'title' => $title, 'url' => $url, 'icon' => $icon, ]; } /** * Get all of the module links in the admin panel * * @return array */ public function getAdminLinks(): array { return self::$adminLinks; } /** * Get all of the modules from database but make sure they also exist on disk * * @return object */ public function getAllModules(): array { $modules = []; $moduleList = Module::all(); /** @var Module $module */ foreach ($moduleList as $module) { /** @var \Nwidart\Modules\Module $moduleInstance */ $moduleInstance = \Nwidart\Modules\Facades\Module::find($module->name); if (empty($moduleInstance)) { continue; } if (file_exists($moduleInstance->getPath())) { $modules[] = $module; } } return $modules; } /** * Determine if a module is active - also checks that the module exists properly * * @param string $name * * @return bool */ public function isModuleActive(string $name): bool { $module = Module::where('name', $name)->first(); if (empty($module)) { return false; } /** @var \Nwidart\Modules\Module $moduleInstance */ $moduleInstance = \Nwidart\Modules\Facades\Module::find($module->name); if (empty($moduleInstance)) { return false; } if (!file_exists($moduleInstance->getPath())) { return false; } return $moduleInstance->isEnabled(); } /** * Get Module Information from Database. * * @param $id * * @return Module */ public function getModule($id): Module { return Module::find($id); } /** * Adding installed module to the database * * @param $module_name * * @return bool */ public function addModule($module_name): bool { /*Check if module already exists*/ $module = Module::where('name', $module_name); if (!$module->exists()) { Module::create([ 'name' => $module_name, 'enabled' => 1, ]); try { Artisan::call('module:migrate '.$module_name, ['--force' => true]); } catch (Exception $e) { Log::error('Error running migration for '.$module_name.'; error='.$e); } return true; } return false; } /** * User's uploaded file is passed into this method * to install module in the Storage. * * @param UploadedFile $file * * @return FlashNotifier */ public function installModule(UploadedFile $file): FlashNotifier { $file_ext = strtolower($file->getClientOriginalExtension()); $allowed_extensions = ['zip', 'tar', 'gz']; if (!in_array($file_ext, $allowed_extensions, true)) { throw new ModuleInvalidFileType(); } $new_dir = rand(); File::makeDirectory( storage_path('app/tmp/modules/'.$new_dir), 0777, true ); $temp_ext_folder = storage_path('app/tmp/modules/'.$new_dir); $temp = storage_path('app/tmp/modules/'.$new_dir); $zipper = null; if ($file_ext === 'tar' || $file_ext === 'gz') { $zipper = new PharData($file); $zipper->decompress(); } if ($file_ext === 'zip') { $madZipper = new Madzipper(); try { $zipper = $madZipper->make($file); } catch (Exception $e) { throw new ModuleInstallationError(); } } try { $zipper->extractTo($temp); } catch (Exception $e) { throw new ModuleInstallationError(); } if (!File::exists($temp.'/module.json')) { $directories = Storage::directories('tmp/modules/'.$new_dir); $temp = storage_path('app/'.$directories[0]); } $json_file = $temp.'/module.json'; if (File::exists($json_file)) { $json = json_decode(file_get_contents($json_file), true); $module = $json['name']; } else { File::deleteDirectory($temp_ext_folder); return flash()->error('Module Structure Not Correct!'); } if (!$module) { File::deleteDirectory($temp_ext_folder); return flash()->error('Not a Valid Module File.'); } $toCopy = base_path().'/modules/'.$module; if (File::exists($toCopy)) { File::deleteDirectory($temp_ext_folder); throw new ModuleExistsException($module); } File::moveDirectory($temp, $toCopy); File::deleteDirectory($temp_ext_folder); try { $this->addModule($module); } catch (Exception $e) { throw new ModuleExistsException($module); } Artisan::call('config:cache'); Artisan::call('module:migrate '.$module, ['--force' => true]); return flash()->success('Module Installed'); } /** * Update module with the status passed by user. * * @param $id * @param $status * * @return bool */ public function updateModule($id, $status): bool { $module = Module::find($id); $module->update([ 'enabled' => $status, ]); if ($status === true) { Artisan::call('module:migrate '.$module->name, ['--force' => true]); } return true; } /** * Delete Module from the Storage & Database. * * @param $id * @param $data * * @return bool */ public function deleteModule($id, $data): bool { $module = Module::find($id); if ($data['verify'] === strtoupper($module->name)) { try { $module->delete(); } catch (Exception $e) { Log::emergency('Cannot Delete Module!'); } $moduleDir = base_path().'/modules/'.$module->name; try { File::deleteDirectory($moduleDir); } catch (Exception $e) { Log::info('Folder Deleted Manually for Module : '.$module->name); return true; } return true; } return false; } /** * Get & scan all modules. * * @return array */ public function scan() { $modules_path = base_path('modules/*'); $path = Str::endsWith($modules_path, '/*') ? $modules_path : Str::finish($modules_path, '/*'); $modules = []; $manifests = (new Filesystem())->glob("{$path}/module.json"); is_array($manifests) || $manifests = []; foreach ($manifests as $manifest) { $name = Json::make($manifest)->get('name'); $module = Module::where('name', $name); if (!$module->exists()) { array_push($modules, $name); } } return $modules; } }