<?php
/**
 *
 * @package    mahara
 * @subpackage admin
 * @author     Catalyst IT Limited <mahara@catalyst.net.nz>
 * @license    https://www.gnu.org/licenses/gpl-3.0.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
 *
 */

define('INTERNAL', 1);
define('ADMIN', 1);
define('MENUITEM', 'configextensions/pluginadmin');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
define('TITLE', get_string('pluginadmin', 'admin'));
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'plugins');
require('upgrade.php');

// @TODO when artefact plugins get installed, move the not installed blocktypes
// that get installed into the list of installed blocktype plugins

$plugins = array();
$plugins['blocktype'] = array();

foreach (plugin_types()  as $plugin) {
    // this has to happen first because of broken artefact/blocktype ordering
    $plugins[$plugin] = array();
    $plugins[$plugin]['installed'] = array();
    $plugins[$plugin]['notinstalled'] = array();
}
foreach (array_keys($plugins) as $plugin) {
    if (table_exists(new XMLDBTable($plugin . '_installed'))) {
        if ($installed = plugins_installed($plugin, true)) {
            foreach ($installed as $i) {
                $key = $i->name;
                if ($plugin == 'blocktype') {
                    $key = blocktype_single_to_namespaced($i->name, $i->artefactplugin);
                }
                if (!safe_require_plugin($plugin, $key)) {
                    continue;
                }

                $classname = generate_class_name($plugin, $key);
                $plugins[$plugin]['installed'][$key] = array(
                    'active' => $i->active,
                    'disableable' => $classname::can_be_disabled(),
                    'deprecated' => $classname::is_deprecated(),
                    'name' => $classname::get_plugin_display_name(),
                    'dependencies' => $classname::has_plugin_dependencies(),
                    'enableable' => $classname::is_usable(),
                    'version' => $i->version
                );
                if (
                    ($i->active && $plugins[$plugin]['installed'][$key]['disableable'])
                    || (!$i->active && $plugins[$plugin]['installed'][$key]['enableable'])
                ){
                    $plugins[$plugin]['installed'][$key]['activateform'] = activate_plugin_form($plugin, $i);
                }
                if ($plugin == 'artefact') {
                    $plugins[$plugin]['installed'][$key]['types'] = array();
                    safe_require('artefact', $key);
                    $artefactclassname = generate_class_name('artefact', $i->name);
                    if ($types = $artefactclassname::get_artefact_types()) {
                        $hasconfigbuttons = 0;
                        $hasconfigbuttonscollapsed = 0;
                        foreach ($types as $t) {
                            $classname = generate_artefact_class_name($t);
                            if ($collapseto = $classname::collapse_config()) {
                                $plugins[$plugin]['installed'][$key]['types'][$collapseto]['config'] = true;
                                $hasconfigbuttonscollapsed = 1;
                            }
                            else {
                                $hasconfig = $classname::has_config();
                                $plugins[$plugin]['installed'][$key]['types'][$t]['config'] = $hasconfig;
                                if ($hasconfig) {
                                    $hasconfigbuttons ++;
                                }
                            }
                            if ($collapseto = $classname::collapse_config_info()) {
                                $plugins[$plugin]['installed'][$key]['types'][$collapseto]['info'] = true;
                                $hasconfigbuttonscollapsed = 1;
                            }
                            else {
                                $hasinfo = $classname::has_config_info();
                                $plugins[$plugin]['installed'][$key]['types'][$t]['info'] = $hasinfo;
                                if ($hasinfo) {
                                    $hasconfigbuttons ++;
                                }
                            }
                        }
                        $plugins[$plugin]['installed'][$key]['typeswithconfig'] = $hasconfigbuttons + $hasconfigbuttonscollapsed;
                    }
                }
                else {
                    $classname = generate_class_name($plugin, $i->name);
                    safe_require($plugin, $key);
                    if ($classname::has_config()) {
                        $plugins[$plugin]['installed'][$key]['config'] = true;
                    }
                    if ($classname::has_config_info()) {
                        $plugins[$plugin]['installed'][$key]['info'] = true;
                    }
                }
            }
        }

        $dirhandle = opendir(get_config('docroot') . $plugin);
        while (false !== ($dir = readdir($dirhandle))) {
            $installed = false; // reinitialise
            if (strpos($dir, '.') === 0) {
                continue;
            }
            if (!is_dir(get_config('docroot') . $plugin . '/' . $dir)) {
                continue;
            }
            if (array_key_exists($dir, $plugins[$plugin]['installed'])) {
                $installed = true;
            }
            // if we're already installed keep going
            // if we're an artefact plugin, we have to check for blocktypes.
            if ($plugin != 'artefact' && !empty($installed)) {
                continue;
            }
            if (empty($installed)) {
                $plugins[$plugin]['notinstalled'][$dir] = array();
                try {
                    validate_plugin($plugin, $dir);
                    $classname = generate_class_name($plugin, $dir);
                    $classname::sanity_check();
                    $plugins[$plugin]['notinstalled'][$dir]['name'] = $classname::get_plugin_display_name();
                    $plugins[$plugin]['notinstalled'][$dir]['dependencies'] = $classname::has_plugin_dependencies();
                }
                catch (InstallationException $e) {
                    $plugins[$plugin]['notinstalled'][$dir]['notinstallable'] = $e->GetMessage();
                }
                // If there are 'required' dependencies then we mark the plugin notinstallable
                if (isset($plugins[$plugin]['notinstalled'][$dir]['dependencies']['requires'])) {
                    if (isset($plugins[$plugin]['notinstalled'][$dir]['notinstallable'])) {
                        $plugins[$plugin]['notinstalled'][$dir]['notinstallable'] .= $plugins[$plugin]['notinstalled'][$dir]['dependencies']['requires'];
                    }
                    else {
                        $plugins[$plugin]['notinstalled'][$dir]['notinstallable'] = $plugins[$plugin]['notinstalled'][$dir]['dependencies']['requires'];
                    }
                }
            }
            if ($plugin == 'artefact' && table_exists(new XMLDBTable('blocktype_installed'))) { // go check it for blocks as well
                $btlocation = get_config('docroot') . $plugin . '/' . $dir . '/blocktype';
                if (!is_dir($btlocation)) {
                    continue;
                }

                $btdirhandle = opendir($btlocation);
                while (false !== ($btdir = readdir($btdirhandle))) {
                    if (strpos($btdir, '.') === 0) {
                        continue;
                    }
                    if (!is_dir(get_config('docroot') . $plugin . '/' . $dir . '/blocktype/' . $btdir)) {
                        continue;
                    }
                    if (!array_key_exists($dir . '/' . $btdir, $plugins['blocktype']['installed'])) {
                        try {
                            if (!array_key_exists($dir, $plugins['artefact']['installed'])) {
                                throw new InstallationException(get_string('blocktypeprovidedbyartefactnotinstallable', 'error', $dir));
                            }
                            validate_plugin('blocktype', $dir . '/' . $btdir,
                                get_config('docroot') . 'artefact/' . $dir . '/blocktype/' . $btdir);
                            $plugins['blocktype']['notinstalled'][$dir . '/' . $btdir] = array();
                        }
                        catch (InstallationException $_e) {
                            $plugins['blocktype']['notinstalled'][$dir . '/' . $btdir]['notinstallable'] = $_e->getMessage();
                        }
                    }
                }
            }
        }
    }
}

global $THEME;

$loadingicon = 'icon icon-spinner icon-pulse';
$successicon = 'icon icon-check text-success';
$failureicon = 'icon icon-exclaimation-triangle';

$loadingstring = json_encode(get_string('upgradeloading', 'admin'));
$successstring = json_encode(get_string('upgradesuccesstoversion', 'admin'));
$failurestring = json_encode(get_string('upgradefailure', 'admin'));

$javascript = <<<JAVASCRIPT

var installplugin = (function($) {
  return function (name) {
      $('[id="' + name + '.message"]').html('<span class="{$loadingicon}" title=' + {$loadingstring} + '" role="presentation" aria-hidden="true"></span>');

      sendjsonrequest('../upgrade.json.php', { 'name': name }, 'GET', function (data) {
          if (!data.error) {
              var message = {$successstring} + data.newversion;
              $('[id="' + name + '.message"]').html('<span class="{$successicon}" title=":)" role="presentation" aria-hidden="true"></span>' + message);
              $('[id="' + name + '.install"]').html('');
              $('[id="' + name + '"]').removeClass('list-group-item-danger').addClass('list-group-item-success');
              // move the whole thing into the list of installed plugins
              // new parent node
              var bits = name.split('\.');
              $("ul[id='" + bits[0] + ".installed'] li").eq(0).after($('[id="' + name + '"]'));
              var oldlist = $("ul[id='" + bits[0] + ".notinstalled']").find('li:not(:has(h3))');
              if (oldlist.length == 0) {
                  $("ul[id='" + bits[0] + ".notinstalled']").hide();
              }
          }
          else {
              var message = '';
              if (data.errormessage) {
                  message = data.errormessage;
              }
              else {
                  message = {$failurestring};
              }
              $('[id="' + name + '"]').html('<span class="{$failureicon}" title=":(" role="presentation" aria-hidden="true"></span>' + message);
          }
      },
      function () {
          message = {$failurestring};
          $('[id="' + name + '"]').html(message);
      },
      true);
  }
}(jQuery));
JAVASCRIPT;

$plugins['blocktype']['configure'] = true;
$plugintypes = array();
foreach ($plugins as $plugin => $info) {
    $plugintypes[$plugin] = get_string('plugin' . $plugin, 'admin');
}
$smarty = smarty();
setpageicon($smarty, 'icon-plug');

$smarty->assign('INLINEJAVASCRIPT', $javascript);
$smarty->assign('plugins', $plugins);
$smarty->assign('plugintypes', $plugintypes);
$smarty->assign('installlink', 'installplugin');
$smarty->display('admin/extensions/plugins.tpl');
