From fa6e5e4d754fec3acee019ed1edaa68357f0c2d0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 28 Jun 2018 16:43:22 -0700 Subject: plugins -> addons --- Zotlabs/Module/Admin.php | 2 +- Zotlabs/Module/Admin/Addons.php | 479 +++++++++++++++++++++++++++++++++++++++ Zotlabs/Module/Admin/Plugins.php | 479 --------------------------------------- Zotlabs/Widget/Admin.php | 6 +- 4 files changed, 483 insertions(+), 483 deletions(-) create mode 100644 Zotlabs/Module/Admin/Addons.php delete mode 100644 Zotlabs/Module/Admin/Plugins.php (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 934312efe..2df8dc25d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -144,7 +144,7 @@ class Admin extends \Zotlabs\Web\Controller { '$accounts' => array( t('Registered accounts'), $accounts), '$pending' => array( t('Pending registrations'), $pending), '$channels' => array( t('Registered channels'), $channels), - '$plugins' => array( t('Active plugins'), $plugins ), + '$plugins' => array( t('Active addons'), $plugins ), '$version' => array( t('Version'), STD_VERSION), '$vmaster' => array( t('Repository version (master)'), $vmaster), '$vdev' => array( t('Repository version (dev)'), $vdev), diff --git a/Zotlabs/Module/Admin/Addons.php b/Zotlabs/Module/Admin/Addons.php new file mode 100644 index 000000000..b35922aef --- /dev/null +++ b/Zotlabs/Module/Admin/Addons.php @@ -0,0 +1,479 @@ + 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) { + @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); + if(function_exists(argv(2).'_plugin_admin_post')) { + $func = argv(2) . '_plugin_admin_post'; + $func($a); + } + + goaway(z_root() . '/admin/addons/' . argv(2) ); + } + elseif(argc() > 2) { + switch(argv(2)) { + case 'updaterepo': + if (array_key_exists('repoName', $_REQUEST)) { + $repoName = $_REQUEST['repoName']; + } + else { + json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); + } + $extendDir = 'store/[data]/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } + else { + if (!symlink(realpath('extend/addon'), $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; + if (!is_dir($repoDir)) { + logger('Repo directory does not exist: ' . $repoDir); + json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); + } + if (!is_writable($repoDir)) { + logger('Repo directory not writable to web server: ' . $repoDir); + json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); + } + $git = new GitRepo('sys', null, false, $repoName, $repoDir); + try { + if ($git->pull()) { + $files = array_diff(scandir($repoDir), array('.', '..')); + foreach ($files as $file) { + if (is_dir($repoDir . '/' . $file) && $file !== '.git') { + $source = '../extend/addon/' . $repoName . '/' . $file; + $target = realpath('addon/') . '/' . $file; + unlink($target); + if (!symlink($source, $target)) { + logger('Error linking addons to /addon'); + json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); + } + } + } + json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); + } + } catch (\PHPGit\Exception\GitException $e) { + json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); + } + case 'removerepo': + if (array_key_exists('repoName', $_REQUEST)) { + $repoName = $_REQUEST['repoName']; + } else { + json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); + } + $extendDir = 'store/[data]/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if (!symlink(realpath('extend/addon'), $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; + if (!is_dir($repoDir)) { + logger('Repo directory does not exist: ' . $repoDir); + json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); + } + if (!is_writable($repoDir)) { + logger('Repo directory not writable to web server: ' . $repoDir); + json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); + } + /// @TODO remove directory and unlink /addon/files + if (rrmdir($repoDir)) { + json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); + } + case 'installrepo': + if (array_key_exists('repoURL', $_REQUEST)) { + require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies + $repoURL = $_REQUEST['repoURL']; + $extendDir = 'store/[data]/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if (!symlink(realpath('extend/addon'), $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + if (!is_writable($extendDir)) { + logger('Directory not writable to web server: ' . $extendDir); + json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); + } + $repoName = null; + if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { + $repoName = $_REQUEST['repoName']; + } else { + $repoName = GitRepo::getRepoNameFromURL($repoURL); + } + if (!$repoName) { + logger('Invalid git repo'); + json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); + } + $repoDir = $addonDir . '/' . $repoName; + $tempRepoBaseDir = 'store/[data]/git/sys/temp/'; + $tempAddonDir = $tempRepoBaseDir . $repoName; + + if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { + logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); + } + rename($tempAddonDir, $repoDir); + + if (!is_writable(realpath('addon/'))) { + logger('/addon directory not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); + } + $files = array_diff(scandir($repoDir), array('.', '..')); + foreach ($files as $file) { + if (is_dir($repoDir . '/' . $file) && $file !== '.git') { + $source = '../extend/addon/' . $repoName . '/' . $file; + $target = realpath('addon/') . '/' . $file; + unlink($target); + if (!symlink($source, $target)) { + logger('Error linking addons to /addon'); + json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); + } + } + } + $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); + $repo = $git->probeRepo(); + json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); + } + case 'addrepo': + if (array_key_exists('repoURL', $_REQUEST)) { + require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies + $repoURL = $_REQUEST['repoURL']; + $extendDir = 'store/[data]/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + $tempAddonDir = realpath('store/[data]') . '/git/sys/temp'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if (!symlink(realpath('extend/addon'), $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + if (!is_dir($tempAddonDir)) { + if (!mkdir($tempAddonDir, 0770, true)) { + logger('Error creating temp plugin repo folder: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false)); + } + } + $repoName = null; + if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { + $repoName = $_REQUEST['repoName']; + } else { + $repoName = GitRepo::getRepoNameFromURL($repoURL); + } + if (!$repoName) { + logger('Invalid git repo'); + json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); + } + $repoDir = $tempAddonDir . '/' . $repoName; + if (!is_writable($tempAddonDir)) { + logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); + } + // clone the repo if new automatically + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + + $remotes = $git->git->remote(); + $fetchURL = $remotes['origin']['fetch']; + if ($fetchURL !== $git->url) { + if (rrmdir($repoDir)) { + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + } else { + json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); + } + } + $repo = $git->probeRepo(); + $repo['readme'] = $repo['manifest'] = null; + foreach ($git->git->tree('master') as $object) { + if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { + $repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash'])); + } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { + $repo['manifest'] = $git->git->cat->blob($object['hash']); + } + } + json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); + } else { + json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); + } + break; + default: + break; + } + } + } + + /** + * @brief Addons admin page. + * + * @return string with parsed HTML + */ + function get() { + + /* + * Single plugin + */ + + if (\App::$argc == 3){ + $plugin = \App::$argv[2]; + if (!is_file("addon/$plugin/$plugin.php")){ + notice( t("Item not found.") ); + return ''; + } + + $enabled = in_array($plugin,\App::$plugins); + $info = get_plugin_info($plugin); + $x = check_plugin_versions($info); + + // disable plugins which are installed but incompatible versions + + if($enabled && ! $x) { + $enabled = false; + $idz = array_search($plugin, \App::$plugins); + if ($idz !== false) { + unset(\App::$plugins[$idz]); + uninstall_plugin($plugin); + set_config("system","addon", implode(", ",\App::$plugins)); + } + } + $info['disabled'] = 1-intval($x); + + if (x($_GET,"a") && $_GET['a']=="t"){ + check_form_security_token_redirectOnErr('/admin/addons', 'admin_addons', 't'); + $pinstalled = false; + // Toggle plugin status + $idx = array_search($plugin, \App::$plugins); + if ($idx !== false){ + unset(\App::$plugins[$idx]); + uninstall_plugin($plugin); + $pinstalled = false; + info( sprintf( t("Plugin %s disabled."), $plugin ) ); + } else { + \App::$plugins[] = $plugin; + install_plugin($plugin); + $pinstalled = true; + info( sprintf( t("Plugin %s enabled."), $plugin ) ); + } + set_config("system","addon", implode(", ",\App::$plugins)); + + if($pinstalled) { + @require_once("addon/$plugin/$plugin.php"); + if(function_exists($plugin.'_plugin_admin')) + goaway(z_root() . '/admin/addons/' . $plugin); + } + goaway(z_root() . '/admin/addons' ); + } + + // display plugin details + + if (in_array($plugin, \App::$plugins)){ + $status = 'on'; + $action = t('Disable'); + } else { + $status = 'off'; + $action = t('Enable'); + } + + $readme = null; + if (is_file("addon/$plugin/README.md")){ + $readme = file_get_contents("addon/$plugin/README.md"); + $readme = MarkdownExtra::defaultTransform($readme); + } else if (is_file("addon/$plugin/README")){ + $readme = "
". file_get_contents("addon/$plugin/README") ."
"; + } + + $admin_form = ''; + + $r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1", + dbesc($plugin) + ); + + if($r) { + @require_once("addon/$plugin/$plugin.php"); + if(function_exists($plugin.'_plugin_admin')) { + $func = $plugin.'_plugin_admin'; + $func($a, $admin_form); + } + } + + + $t = get_markup_template('admin_plugins_details.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Addons'), + '$toggle' => t('Toggle'), + '$settings' => t('Settings'), + '$baseurl' => z_root(), + + '$plugin' => $plugin, + '$status' => $status, + '$action' => $action, + '$info' => $info, + '$str_author' => t('Author: '), + '$str_maintainer' => t('Maintainer: '), + '$str_minversion' => t('Minimum project version: '), + '$str_maxversion' => t('Maximum project version: '), + '$str_minphpversion' => t('Minimum PHP version: '), + '$str_serverroles' => t('Compatible Server Roles: '), + '$str_requires' => t('Requires: '), + '$disabled' => t('Disabled - version incompatibility'), + + '$admin_form' => $admin_form, + '$function' => 'addons', + '$screenshot' => '', + '$readme' => $readme, + + '$form_security_token' => get_form_security_token('admin_addons'), + )); + } + + + /* + * List plugins + */ + $plugins = array(); + $files = glob('addon/*/'); + if($files) { + foreach($files as $file) { + if (is_dir($file)){ + list($tmp, $id) = array_map('trim', explode('/', $file)); + $info = get_plugin_info($id); + $enabled = in_array($id,\App::$plugins); + $x = check_plugin_versions($info); + + // disable plugins which are installed but incompatible versions + + if($enabled && ! $x) { + $enabled = false; + $idz = array_search($id, \App::$plugins); + if ($idz !== false) { + unset(\App::$plugins[$idz]); + uninstall_plugin($id); + set_config("system","addon", implode(", ",\App::$plugins)); + } + } + $info['disabled'] = 1-intval($x); + + $plugins[] = array( $id, (($enabled)?"on":"off") , $info); + } + } + } + + usort($plugins,'self::plugin_sort'); + + $allowManageRepos = false; + if(is_writable('extend/addon') && is_writable('store/[data]')) { + $allowManageRepos = true; + } + + $admin_plugins_add_repo_form= replace_macros( + get_markup_template('admin_plugins_addrepo.tpl'), array( + '$post' => 'admin/addons/addrepo', + '$desc' => t('Enter the public git repository URL of the addon repo.'), + '$repoURL' => array('repoURL', t('Addon repo git URL'), '', ''), + '$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')), + '$submit' => t('Download Addon Repo') + ) + ); + $newRepoModalID = random_string(3); + $newRepoModal = replace_macros( + get_markup_template('generic_modal.tpl'), array( + '$id' => $newRepoModalID, + '$title' => t('Install new repo'), + '$ok' => t('Install'), + '$cancel' => t('Cancel') + ) + ); + + $reponames = $this->listAddonRepos(); + $addonrepos = []; + foreach($reponames as $repo) { + $addonrepos[] = array('name' => $repo, 'description' => ''); + /// @TODO Parse repo info to provide more information about repos + } + + $t = get_markup_template('admin_plugins.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Addons'), + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$function' => 'addons', + '$plugins' => $plugins, + '$disabled' => t('Disabled - version incompatibility'), + '$form_security_token' => get_form_security_token('admin_addons'), + '$allowManageRepos' => $allowManageRepos, + '$managerepos' => t('Manage Repos'), + '$installedtitle' => t('Installed Addon Repositories'), + '$addnewrepotitle' => t('Install a New Addon Repository'), + '$expandform' => false, + '$form' => $admin_plugins_add_repo_form, + '$newRepoModal' => $newRepoModal, + '$newRepoModalID' => $newRepoModalID, + '$addonrepos' => $addonrepos, + '$repoUpdateButton' => t('Update'), + '$repoBranchButton' => t('Switch branch'), + '$repoRemoveButton' => t('Remove') + )); + } + + function listAddonRepos() { + $addonrepos = []; + $addonDir = 'extend/addon/'; + if(is_dir($addonDir)) { + if ($handle = opendir($addonDir)) { + while (false !== ($entry = readdir($handle))) { + if ($entry != "." && $entry != "..") { + $addonrepos[] = $entry; + } + } + closedir($handle); + } + } + return $addonrepos; + } + + static public function plugin_sort($a,$b) { + return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name']))); + } + +} \ No newline at end of file diff --git a/Zotlabs/Module/Admin/Plugins.php b/Zotlabs/Module/Admin/Plugins.php deleted file mode 100644 index feb29e9d6..000000000 --- a/Zotlabs/Module/Admin/Plugins.php +++ /dev/null @@ -1,479 +0,0 @@ - 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) { - @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); - if(function_exists(argv(2).'_plugin_admin_post')) { - $func = argv(2) . '_plugin_admin_post'; - $func($a); - } - - goaway(z_root() . '/admin/plugins/' . argv(2) ); - } - elseif(argc() > 2) { - switch(argv(2)) { - case 'updaterepo': - if (array_key_exists('repoName', $_REQUEST)) { - $repoName = $_REQUEST['repoName']; - } - else { - json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); - } - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } - else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; - if (!is_dir($repoDir)) { - logger('Repo directory does not exist: ' . $repoDir); - json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); - } - if (!is_writable($repoDir)) { - logger('Repo directory not writable to web server: ' . $repoDir); - json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); - } - $git = new GitRepo('sys', null, false, $repoName, $repoDir); - try { - if ($git->pull()) { - $files = array_diff(scandir($repoDir), array('.', '..')); - foreach ($files as $file) { - if (is_dir($repoDir . '/' . $file) && $file !== '.git') { - $source = '../extend/addon/' . $repoName . '/' . $file; - $target = realpath('addon/') . '/' . $file; - unlink($target); - if (!symlink($source, $target)) { - logger('Error linking addons to /addon'); - json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); - } - } - } - json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); - } else { - json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); - } - } catch (\PHPGit\Exception\GitException $e) { - json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); - } - case 'removerepo': - if (array_key_exists('repoName', $_REQUEST)) { - $repoName = $_REQUEST['repoName']; - } else { - json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); - } - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; - if (!is_dir($repoDir)) { - logger('Repo directory does not exist: ' . $repoDir); - json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); - } - if (!is_writable($repoDir)) { - logger('Repo directory not writable to web server: ' . $repoDir); - json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); - } - /// @TODO remove directory and unlink /addon/files - if (rrmdir($repoDir)) { - json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); - } else { - json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); - } - case 'installrepo': - if (array_key_exists('repoURL', $_REQUEST)) { - require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies - $repoURL = $_REQUEST['repoURL']; - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - if (!is_writable($extendDir)) { - logger('Directory not writable to web server: ' . $extendDir); - json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); - } - $repoName = null; - if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; - } else { - $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if (!$repoName) { - logger('Invalid git repo'); - json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); - } - $repoDir = $addonDir . '/' . $repoName; - $tempRepoBaseDir = 'store/[data]/git/sys/temp/'; - $tempAddonDir = $tempRepoBaseDir . $repoName; - - if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { - logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); - } - rename($tempAddonDir, $repoDir); - - if (!is_writable(realpath('addon/'))) { - logger('/addon directory not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); - } - $files = array_diff(scandir($repoDir), array('.', '..')); - foreach ($files as $file) { - if (is_dir($repoDir . '/' . $file) && $file !== '.git') { - $source = '../extend/addon/' . $repoName . '/' . $file; - $target = realpath('addon/') . '/' . $file; - unlink($target); - if (!symlink($source, $target)) { - logger('Error linking addons to /addon'); - json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); - } - } - } - $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); - $repo = $git->probeRepo(); - json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); - } - case 'addrepo': - if (array_key_exists('repoURL', $_REQUEST)) { - require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies - $repoURL = $_REQUEST['repoURL']; - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - $tempAddonDir = realpath('store/[data]') . '/git/sys/temp'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - if (!is_dir($tempAddonDir)) { - if (!mkdir($tempAddonDir, 0770, true)) { - logger('Error creating temp plugin repo folder: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false)); - } - } - $repoName = null; - if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; - } else { - $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if (!$repoName) { - logger('Invalid git repo'); - json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); - } - $repoDir = $tempAddonDir . '/' . $repoName; - if (!is_writable($tempAddonDir)) { - logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); - } - // clone the repo if new automatically - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - - $remotes = $git->git->remote(); - $fetchURL = $remotes['origin']['fetch']; - if ($fetchURL !== $git->url) { - if (rrmdir($repoDir)) { - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - } else { - json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); - } - } - $repo = $git->probeRepo(); - $repo['readme'] = $repo['manifest'] = null; - foreach ($git->git->tree('master') as $object) { - if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { - $repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash'])); - } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { - $repo['manifest'] = $git->git->cat->blob($object['hash']); - } - } - json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); - } else { - json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); - } - break; - default: - break; - } - } - } - - /** - * @brief Plugins admin page. - * - * @return string with parsed HTML - */ - function get() { - - /* - * Single plugin - */ - - if (\App::$argc == 3){ - $plugin = \App::$argv[2]; - if (!is_file("addon/$plugin/$plugin.php")){ - notice( t("Item not found.") ); - return ''; - } - - $enabled = in_array($plugin,\App::$plugins); - $info = get_plugin_info($plugin); - $x = check_plugin_versions($info); - - // disable plugins which are installed but incompatible versions - - if($enabled && ! $x) { - $enabled = false; - $idz = array_search($plugin, \App::$plugins); - if ($idz !== false) { - unset(\App::$plugins[$idz]); - uninstall_plugin($plugin); - set_config("system","addon", implode(", ",\App::$plugins)); - } - } - $info['disabled'] = 1-intval($x); - - if (x($_GET,"a") && $_GET['a']=="t"){ - check_form_security_token_redirectOnErr('/admin/plugins', 'admin_plugins', 't'); - $pinstalled = false; - // Toggle plugin status - $idx = array_search($plugin, \App::$plugins); - if ($idx !== false){ - unset(\App::$plugins[$idx]); - uninstall_plugin($plugin); - $pinstalled = false; - info( sprintf( t("Plugin %s disabled."), $plugin ) ); - } else { - \App::$plugins[] = $plugin; - install_plugin($plugin); - $pinstalled = true; - info( sprintf( t("Plugin %s enabled."), $plugin ) ); - } - set_config("system","addon", implode(", ",\App::$plugins)); - - if($pinstalled) { - @require_once("addon/$plugin/$plugin.php"); - if(function_exists($plugin.'_plugin_admin')) - goaway(z_root() . '/admin/plugins/' . $plugin); - } - goaway(z_root() . '/admin/plugins' ); - } - - // display plugin details - - if (in_array($plugin, \App::$plugins)){ - $status = 'on'; - $action = t('Disable'); - } else { - $status = 'off'; - $action = t('Enable'); - } - - $readme = null; - if (is_file("addon/$plugin/README.md")){ - $readme = file_get_contents("addon/$plugin/README.md"); - $readme = MarkdownExtra::defaultTransform($readme); - } else if (is_file("addon/$plugin/README")){ - $readme = "
". file_get_contents("addon/$plugin/README") ."
"; - } - - $admin_form = ''; - - $r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1", - dbesc($plugin) - ); - - if($r) { - @require_once("addon/$plugin/$plugin.php"); - if(function_exists($plugin.'_plugin_admin')) { - $func = $plugin.'_plugin_admin'; - $func($a, $admin_form); - } - } - - - $t = get_markup_template('admin_plugins_details.tpl'); - return replace_macros($t, array( - '$title' => t('Administration'), - '$page' => t('Plugins'), - '$toggle' => t('Toggle'), - '$settings' => t('Settings'), - '$baseurl' => z_root(), - - '$plugin' => $plugin, - '$status' => $status, - '$action' => $action, - '$info' => $info, - '$str_author' => t('Author: '), - '$str_maintainer' => t('Maintainer: '), - '$str_minversion' => t('Minimum project version: '), - '$str_maxversion' => t('Maximum project version: '), - '$str_minphpversion' => t('Minimum PHP version: '), - '$str_serverroles' => t('Compatible Server Roles: '), - '$str_requires' => t('Requires: '), - '$disabled' => t('Disabled - version incompatibility'), - - '$admin_form' => $admin_form, - '$function' => 'plugins', - '$screenshot' => '', - '$readme' => $readme, - - '$form_security_token' => get_form_security_token('admin_plugins'), - )); - } - - - /* - * List plugins - */ - $plugins = array(); - $files = glob('addon/*/'); - if($files) { - foreach($files as $file) { - if (is_dir($file)){ - list($tmp, $id) = array_map('trim', explode('/', $file)); - $info = get_plugin_info($id); - $enabled = in_array($id,\App::$plugins); - $x = check_plugin_versions($info); - - // disable plugins which are installed but incompatible versions - - if($enabled && ! $x) { - $enabled = false; - $idz = array_search($id, \App::$plugins); - if ($idz !== false) { - unset(\App::$plugins[$idz]); - uninstall_plugin($id); - set_config("system","addon", implode(", ",\App::$plugins)); - } - } - $info['disabled'] = 1-intval($x); - - $plugins[] = array( $id, (($enabled)?"on":"off") , $info); - } - } - } - - usort($plugins,'self::plugin_sort'); - - $allowManageRepos = false; - if(is_writable('extend/addon') && is_writable('store/[data]')) { - $allowManageRepos = true; - } - - $admin_plugins_add_repo_form= replace_macros( - get_markup_template('admin_plugins_addrepo.tpl'), array( - '$post' => 'admin/plugins/addrepo', - '$desc' => t('Enter the public git repository URL of the plugin repo.'), - '$repoURL' => array('repoURL', t('Plugin repo git URL'), '', ''), - '$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')), - '$submit' => t('Download Plugin Repo') - ) - ); - $newRepoModalID = random_string(3); - $newRepoModal = replace_macros( - get_markup_template('generic_modal.tpl'), array( - '$id' => $newRepoModalID, - '$title' => t('Install new repo'), - '$ok' => t('Install'), - '$cancel' => t('Cancel') - ) - ); - - $reponames = $this->listAddonRepos(); - $addonrepos = []; - foreach($reponames as $repo) { - $addonrepos[] = array('name' => $repo, 'description' => ''); - /// @TODO Parse repo info to provide more information about repos - } - - $t = get_markup_template('admin_plugins.tpl'); - return replace_macros($t, array( - '$title' => t('Administration'), - '$page' => t('Plugins'), - '$submit' => t('Submit'), - '$baseurl' => z_root(), - '$function' => 'plugins', - '$plugins' => $plugins, - '$disabled' => t('Disabled - version incompatibility'), - '$form_security_token' => get_form_security_token('admin_plugins'), - '$allowManageRepos' => $allowManageRepos, - '$managerepos' => t('Manage Repos'), - '$installedtitle' => t('Installed Plugin Repositories'), - '$addnewrepotitle' => t('Install a New Plugin Repository'), - '$expandform' => false, - '$form' => $admin_plugins_add_repo_form, - '$newRepoModal' => $newRepoModal, - '$newRepoModalID' => $newRepoModalID, - '$addonrepos' => $addonrepos, - '$repoUpdateButton' => t('Update'), - '$repoBranchButton' => t('Switch branch'), - '$repoRemoveButton' => t('Remove') - )); - } - - function listAddonRepos() { - $addonrepos = []; - $addonDir = 'extend/addon/'; - if(is_dir($addonDir)) { - if ($handle = opendir($addonDir)) { - while (false !== ($entry = readdir($handle))) { - if ($entry != "." && $entry != "..") { - $addonrepos[] = $entry; - } - } - closedir($handle); - } - } - return $addonrepos; - } - - static public function plugin_sort($a,$b) { - return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name']))); - } - -} \ No newline at end of file diff --git a/Zotlabs/Widget/Admin.php b/Zotlabs/Widget/Admin.php index a761eebe3..f349377a0 100644 --- a/Zotlabs/Widget/Admin.php +++ b/Zotlabs/Widget/Admin.php @@ -24,7 +24,7 @@ class Admin { 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'), 'security' => array(z_root() . '/admin/security/', t('Security'), 'security'), 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'), - 'plugins' => array(z_root() . '/admin/plugins/', t('Plugins'), 'plugins'), + 'addons' => array(z_root() . '/admin/addons/', t('Addons'), 'addons'), 'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'), 'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'), 'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'), @@ -39,7 +39,7 @@ class Admin { if($r) { foreach ($r as $h){ $plugin = $h['aname']; - $plugins[] = array(z_root() . '/admin/plugins/' . $plugin, $plugin, 'plugin'); + $plugins[] = array(z_root() . '/admin/addons/' . $plugin, $plugin, 'plugin'); // temp plugins with admin \App::$plugins_admin[] = $plugin; } @@ -53,7 +53,7 @@ class Admin { $o .= replace_macros(get_markup_template('admin_aside.tpl'), array( '$admin' => $aside, '$admtxt' => t('Admin'), - '$plugadmtxt' => t('Plugin Features'), + '$plugadmtxt' => t('Addon Features'), '$plugins' => $plugins, '$logtxt' => t('Logs'), '$logs' => $logs, -- cgit v1.2.3