Overview
Comment:Refactor plugin admin page, a bit
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 74806bd766271a220fc11625a6ff01db663f59618eac1862a4070b9afcf04f09
User & Date: bohwaz on 2022-09-02 20:40:56
Other Links: branch diff | manifest | tags
Context
2022-09-02
23:08
Improve documents list (a bit), use new public layout for ask_share_password check-in: b8703450c6 user: bohwaz tags: dev
20:40
Refactor plugin admin page, a bit check-in: 74806bd766 user: bohwaz tags: dev
20:16
Merge with trunk check-in: e5ad3de6e3 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Plugin.php from [cdc93fe561] to [d3e8f17634].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

namespace Garradin;

use Garradin\Users\Session;

class Plugin
{
	const PLUGIN_ID_SYNTAX = '[a-z]+(?:_[a-z]+)*';

	protected $id = null;
	protected $plugin = null;
	protected $config_changed = false;

	/**
	 * Set to false to disable signal firing








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

namespace Garradin;

use Garradin\Users\Session;

class Plugin
{
	const PLUGIN_ID_REGEXP = '[a-z]+(?:_[a-z]+)*';

	protected $id = null;
	protected $plugin = null;
	protected $config_changed = false;

	/**
	 * Set to false to disable signal firing
300
301
302
303
304
305
306
307




308
309
310
311
312
313
314
315
316
317
318
		if (file_exists($this->path() . '/upgrade.php'))
		{
			$plugin = $this;
			include $this->path() . '/upgrade.php';
		}

		$infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false);





		$data = [
			'name'		=>	$infos->name ?? $infos->nom,
			'description'=>	$infos->description,
			'author'	=>	$infos->author ?? $infos->auteur,
			'url'		=>	$infos->url,
			'version'	=>	$infos->version,
			'menu'		=>	(int)(bool)$infos->menu,
		];

		if ($infos->menu && !empty($infos->menu_condition))
		{








>
>
>
>

|

|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
		if (file_exists($this->path() . '/upgrade.php'))
		{
			$plugin = $this;
			include $this->path() . '/upgrade.php';
		}

		$infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false);

		if (!isset($infos->name)) {
			return;
		}

		$data = [
			'name'		=>	$infos->name,
			'description'=>	$infos->description,
			'author'	=>	$infos->author,
			'url'		=>	$infos->url,
			'version'	=>	$infos->version,
			'menu'		=>	(int)(bool)$infos->menu,
		];

		if ($infos->menu && !empty($infos->menu_condition))
		{
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463







464
465
466
467
468
469
470
		$dir = dir(PLUGINS_ROOT);

		while ($file = $dir->read())
		{
			if (substr($file, 0, 1) == '.')
				continue;

			if (preg_match('!^(' . self::PLUGIN_ID_SYNTAX . ')\.tar\.gz$!', $file, $match))
			{
				// Sélectionner les archives PHAR
				$file = $match[1];
			}
			elseif (is_dir(PLUGINS_ROOT . '/' . $file)
				&& preg_match('!^' . self::PLUGIN_ID_SYNTAX . '$!', $file)
				&& is_file(sprintf('%s/%s/garradin_plugin.ini', PLUGINS_ROOT, $file)))
			{
				// Rien à faire, le nom valide du plugin est déjà dans "$file"
			}
			else
			{
				// ignorer tout ce qui n'est pas un répertoire ou une archive PHAR valides
				continue;
			}

			if (array_key_exists($file, $installed))
			{
				// Ignorer les plugins déjà installés
				continue;
			}

			$list[$file] = (object) parse_ini_file(self::getPath($file) . '/garradin_plugin.ini', false);







		}

		$dir->close();

		return $list;
	}








|





|
















|
>
>
>
>
>
>
>







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
		$dir = dir(PLUGINS_ROOT);

		while ($file = $dir->read())
		{
			if (substr($file, 0, 1) == '.')
				continue;

			if (preg_match('!^(' . self::PLUGIN_ID_REGEXP . ')\.tar\.gz$!', $file, $match))
			{
				// Sélectionner les archives PHAR
				$file = $match[1];
			}
			elseif (is_dir(PLUGINS_ROOT . '/' . $file)
				&& preg_match('!^' . self::PLUGIN_ID_REGEXP . '$!', $file)
				&& is_file(sprintf('%s/%s/garradin_plugin.ini', PLUGINS_ROOT, $file)))
			{
				// Rien à faire, le nom valide du plugin est déjà dans "$file"
			}
			else
			{
				// ignorer tout ce qui n'est pas un répertoire ou une archive PHAR valides
				continue;
			}

			if (array_key_exists($file, $installed))
			{
				// Ignorer les plugins déjà installés
				continue;
			}

			$data = (object) parse_ini_file(self::getPath($file) . '/garradin_plugin.ini', false);;

			if (!isset($data->name)) {
				// Ignore old plugins
				continue;
			}

			$list[$file] = $data;
		}

		$dir->close();

		return $list;
	}

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
			}

			$config = json_encode($config);
		}

		$data = [
			'id' 		=> 	$id,
			'officiel' 	=> 	(int)(bool)$official,
			'name'		=>	$infos->name,
			'description'=>	$infos->description,
			'author'	=>	$infos->author,
			'url'		=>	$infos->url,
			'version'	=>	$infos->version,
			'menu'		=>	(int)(bool)$infos->menu,
			'config'	=>	$config,







|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
			}

			$config = json_encode($config);
		}

		$data = [
			'id' 		=> 	$id,
			'official' 	=> 	(int)(bool)$official,
			'name'		=>	$infos->name,
			'description'=>	$infos->description,
			'author'	=>	$infos->author,
			'url'		=>	$infos->url,
			'version'	=>	$infos->version,
			'menu'		=>	(int)(bool)$infos->menu,
			'config'	=>	$config,

Modified src/templates/config/plugins.tpl from [62fbe9d0a2] to [348aea127d].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
{include file="_head.tpl" title="Extensions" current="config"}

{include file="config/_menu.tpl" current="plugins"}

{form_errors}

{if !empty($delete)}
    <form method="post" action="{$self_url}">

        <fieldset>
            <legend>Désinstaller une extension</legend>
            <h3 class="warning">
                Êtes-vous sûr de vouloir supprimer l'extension «&nbsp;{$plugin.nom}&nbsp;» ?
            </h3>
            <p class="block alert">
                <strong>Attention</strong> : cette action est irréversible et effacera toutes les
                données associées à l'extension.
            </p>
        </fieldset>

        <p class="submit">
            {csrf_field key="delete_plugin_%s"|args:$plugin.id}
            {button type="submit" name="delete" label="Désinstaller" shape="delete" class="main"}
        </p>
    </form>
{else}
    {if !empty($liste_installes)}
        <table class="list">
            <thead>
                <tr>
                    <th>Extension</th>
                    <td></td>
                    <td>Version installée</td>
                    <td></td>
                </tr>
            </thead>
            <tbody>
                {foreach from=$liste_installes item="plugin"}
                <tr{if $plugin.disabled} class="disabled"{/if}>
                    <th>
                        <h4>{$plugin.nom}</h4>
                        <small>{$plugin.description}</small>
                    </th>
                    {if $plugin.disabled}
                    <td colspan="3">
                        <span class="alert">Code source du plugin non trouvé dans le répertoire <em>plugins</em>&nbsp;!</span><br />
                        Ce plugin ne peut fonctionner ou être désinstallé.
                    </td>
                    {else}
                    <td>
                        <a href="{$plugin.url}" onclick="return !window.open(this.href);">{$plugin.auteur}</a>
                    </td>
                    <td>
                        {$plugin.version}
                    </td>
                    <td class="actions">
                        {if !empty($plugin.config)}
                            {linkbutton shape="settings" label="Configurer" href="!plugin/%s/config.php"|args:$plugin.id}
                        {/if}
                        {linkbutton shape="delete" href="!config/plugins.php?delete=%s"|args:$plugin.id label="Désinstaller"}
                    </td>
                    {/if}
                </tr>
                {/foreach}
            </tbody>
        </table>
    {else}
        <p class="help">
            Aucune extension n'est installée.
            Vous pouvez consulter <a href="{$garradin_website}">le site de Garradin</a> pour obtenir
            des extensions à télécharger.
        </p>
    {/if}

    {if !empty($liste_telecharges)}
    <form method="post" action="{$self_url}">

        <fieldset>
            <legend>Extensions à installer</legend>
            <dl>
                {foreach from=$liste_telecharges item="plugin" key="id"}
                <dt>
                    <input type="radio" name="plugin" value="{$id}" id="f_{$id}" />
                    <label for="f_{$id}">
                        {$plugin.nom}
                    </label>
                    <small>(version {$plugin.version})</small>
                </dt>
                <dd>[<a href="{$plugin.url}" onclick="return !window.open(this.href);">{$plugin.auteur}</a>] {$plugin.description}</dd>
                {/foreach}
            </dl>
        </fieldset>

        <p class="help">
            Attention : installer une extension non officielle peut présenter des risques de sécurité
            et de stabilité.
        </p>

        <p class="submit">
            {csrf_field key="install_plugin"}
            {button type="submit" name="install" label="Installer" shape="right" class="main"}
        </p>
    </form>
    {/if}
{/if}

{include file="_foot.tpl"}







|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|
<
|
<
<
<
<
<
|
|
|
|

|
|
|
|

|
|
|
|
|
|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82





83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
{include file="_head.tpl" title="Extensions" current="config"}

{include file="config/_menu.tpl" current="plugins"}

{form_errors}

{if !empty($delete)}
	<form method="post" action="{$self_url}">

		<fieldset>
			<legend>Désinstaller une extension</legend>
			<h3 class="warning">
				Êtes-vous sûr de vouloir supprimer l'extension «&nbsp;{$plugin.name}&nbsp;» ?
			</h3>
			<p class="block alert">
				<strong>Attention</strong> : cette action est irréversible et effacera toutes les
				données associées à l'extension.
			</p>
		</fieldset>

		<p class="submit">
			{csrf_field key=$csrf_key}
			{button type="submit" name="delete" label="Désinstaller" shape="delete" class="main"}
		</p>
	</form>
{else}
	{if !empty($list_installed)}
		<table class="list">
			<thead>
				<tr>
					<th>Extension</th>
					<td></td>
					<td>Version installée</td>
					<td></td>
				</tr>
			</thead>
			<tbody>
				{foreach from=$list_installed item="plugin"}
				<tr{if $plugin.disabled} class="disabled"{/if}>
					<th>
						<h4>{$plugin.name}</h4>
						<small>{$plugin.description}</small>
					</th>
					{if $plugin.disabled}
					<td colspan="3">
						<span class="alert">Code source du plugin non trouvé dans le répertoire <em>plugins</em>&nbsp;!</span><br />
						Ce plugin ne peut fonctionner ou être désinstallé.
					</td>
					{else}
					<td>
						<a href="{$plugin.url}" onclick="return !window.open(this.href);">{$plugin.auteur}</a>
					</td>
					<td>
						{$plugin.version}
					</td>
					<td class="actions">
						{if !empty($plugin.config)}
							{linkbutton shape="settings" label="Configurer" href="!plugin/%s/config.php"|args:$plugin.id}
						{/if}
						{linkbutton shape="delete" href="!config/plugins.php?delete=%s"|args:$plugin.id label="Désinstaller"}
					</td>
					{/if}
				</tr>
				{/foreach}
			</tbody>
		</table>
	{else}
		<p class="help">
			Aucune extension n'est installée.
			Vous pouvez consulter <a href="{$garradin_website}">le site de Garradin</a> pour obtenir
			des extensions à télécharger.
		</p>
	{/if}

	{if !empty($list_available)}
	<form method="post" action="{$self_url}">

		<fieldset>
			<legend>Extensions à installer</legend>
			<dl>
				{foreach from=$list_available item="plugin" key="id"}

				{input type="radio" name="plugin" value=$id label=$plugin.name help="version %s"|args:$plugin.version}





				<dd>[<a href="{$plugin.url}" onclick="return !window.open(this.href);">{$plugin.author}</a>] {$plugin.description}</dd>
				{/foreach}
			</dl>
		</fieldset>

		<p class="help">
			Attention : installer une extension non officielle peut présenter des risques de sécurité
			et de stabilité.
		</p>

		<p class="submit">
			{csrf_field key=$csrf_key}
			{button type="submit" name="install" label="Installer" shape="right" class="main"}
		</p>
	</form>
	{/if}
{/if}

{include file="_foot.tpl"}

Modified src/www/admin/config/plugins.php from [6290d0cd75] to [17a06e1803].

1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
<?php

namespace Garradin;



require_once __DIR__ . '/_inc.php';

if (f('install'))
{
    $form->check('install_plugin', [
        'plugin' => 'required',
    ]);

    if (!$form->hasErrors())
    {
        try {
            Plugin::install(f('plugin'), false);
            $session->set('plugins_menu', null);
            Utils::redirect(ADMIN_URL . 'config/plugins.php');
        }
        catch (UserException $e)
        {
            $form->addError($e->getMessage());
        }
    }
}

if (f('delete'))
{
    $form->check('delete_plugin_' . qg('delete'));

    if (!$form->hasErrors())
    {
        try {
            $plugin = new Plugin(qg('delete'));
            $plugin->uninstall();
            $session->set('plugins_menu', null);

            Utils::redirect(ADMIN_URL . 'config/plugins.php');
        }
        catch (UserException $e)
        {
            $form->addError($e->getMessage());
        }
    }
}

if (qg('delete'))
{
    $plugin = new Plugin(qg('delete'));
    $tpl->assign('plugin', $plugin->getInfos());
    $tpl->assign('delete', true);
}
else
{
    $tpl->assign('liste_telecharges', Plugin::listDownloaded());
    $tpl->assign('liste_installes', Plugin::listInstalled());
}

$tpl->assign('garradin_website', WEBSITE);


$tpl->display('config/plugins.tpl');

Plugin::upgradeAllIfRequired();



>
>



|
<
<
|
<

|
<
<
|
|
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
|
|
<
<
<
<
<
<
<
|
<
|
|
|

|
<
|
|



>




1
2
3
4
5
6
7
8
9


10

11
12


13
14
15
16






17







18
19
20

21
22







23

24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
<?php

namespace Garradin;

use Garradin\Users\Session;

require_once __DIR__ . '/_inc.php';

$session = Session::getInstance();


$csrf_key = 'plugins';


$form->runIf('install', function ()  use ($session) {


	Plugin::install(f('plugin'), false);
	$session->set('plugins_menu', null);
}, $csrf_key, '!config/plugins.php');







$form->runIf('delete', function () use ($session) {







	$plugin = new Plugin(qg('delete'));
	$plugin->uninstall();
	$session->set('plugins_menu', null);

}, $csrf_key, '!config/plugins.php');








if (qg('delete')) {

	$plugin = new Plugin(qg('delete'));
	$tpl->assign('plugin', $plugin->getInfos());
	$tpl->assign('delete', true);
}
else {

	$tpl->assign('list_available', Plugin::listDownloaded());
	$tpl->assign('list_installed', Plugin::listInstalled());
}

$tpl->assign('garradin_website', WEBSITE);
$tpl->assign(compact('csrf_key'));

$tpl->display('config/plugins.tpl');

Plugin::upgradeAllIfRequired();