2021-08-19 19:42:44 +00:00
|
|
|
<?php
|
2021-09-02 21:12:57 +00:00
|
|
|
/**
|
|
|
|
* @brief tinyPacker, a plugin for Dotclear 2
|
2022-11-20 21:06:36 +00:00
|
|
|
*
|
2021-09-02 21:12:57 +00:00
|
|
|
* @package Dotclear
|
|
|
|
* @subpackage Plugin
|
2022-11-20 21:06:36 +00:00
|
|
|
*
|
2021-09-02 21:12:57 +00:00
|
|
|
* @author Jean-Christian Denis
|
2022-11-20 21:06:36 +00:00
|
|
|
*
|
2021-09-02 21:12:57 +00:00
|
|
|
* @copyright Jean-Christian Denis
|
|
|
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
|
|
*/
|
2021-08-19 19:42:44 +00:00
|
|
|
if (!defined('DC_CONTEXT_ADMIN')) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-11-13 22:43:30 +00:00
|
|
|
if (!tinyPacker::repositoryDir()) {
|
2021-08-19 19:42:44 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-11-13 22:43:30 +00:00
|
|
|
dcCore::app()->addBehavior(
|
2021-08-19 19:42:44 +00:00
|
|
|
'adminModulesListGetActions',
|
|
|
|
['tinyPacker', 'adminModulesGetActions']
|
|
|
|
);
|
2022-11-13 22:43:30 +00:00
|
|
|
dcCore::app()->addBehavior(
|
2021-08-19 19:42:44 +00:00
|
|
|
'adminModulesListDoActions',
|
|
|
|
['tinyPacker', 'adminModulesDoActions']
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ingroup DC_PLUGIN_TINYPACKER
|
|
|
|
* @brief Quick create packages of modules from admin to public dir.
|
|
|
|
* @since 2.6
|
|
|
|
*/
|
|
|
|
class tinyPacker
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Blog's public sub-directory where to put packages
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public static $sub_dir = 'packages';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add button to create package to modules lists
|
|
|
|
* @param object $list adminModulesList instance
|
|
|
|
* @param string $id Module id
|
|
|
|
* @param arrray $_ Module properties
|
|
|
|
* @return string HTML submit button
|
|
|
|
*/
|
|
|
|
public static function adminModulesGetActions($list, $id, $_)
|
|
|
|
{
|
2022-11-20 21:06:36 +00:00
|
|
|
if ($list->getList() != 'plugin-activate'
|
2021-08-19 19:42:44 +00:00
|
|
|
&& $list->getList() != 'theme-activate') {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-11-20 21:06:36 +00:00
|
|
|
return
|
2021-08-19 19:42:44 +00:00
|
|
|
'<input type="submit" name="tinypacker[' .
|
|
|
|
html::escapeHTML($id) . ']" value="Pack" />';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create package on modules lists action
|
|
|
|
* @param object $list adminModulesList instance
|
|
|
|
* @param array $modules Selected modules ids
|
|
|
|
* @param string $type List type (plugins|themes)
|
|
|
|
* @throws Exception If no public dir or module
|
|
|
|
* @return null Null
|
|
|
|
*/
|
|
|
|
public static function adminModulesDoActions($list, $modules, $type)
|
|
|
|
{
|
|
|
|
# Pack action
|
2022-11-20 21:06:36 +00:00
|
|
|
if (empty($_POST['tinypacker'])
|
2021-08-19 19:42:44 +00:00
|
|
|
|| !is_array($_POST['tinypacker'])) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$modules = array_keys($_POST['tinypacker']);
|
2022-11-20 21:06:36 +00:00
|
|
|
$id = $modules[0];
|
2021-08-19 19:42:44 +00:00
|
|
|
|
|
|
|
# Repository directory
|
2022-11-20 21:06:36 +00:00
|
|
|
if (($root = self::repositoryDir()) === false) {
|
2021-08-19 19:42:44 +00:00
|
|
|
throw new Exception(
|
2022-11-20 21:06:36 +00:00
|
|
|
__(
|
|
|
|
'Destination directory is not writable.'
|
|
|
|
)
|
|
|
|
);
|
2021-08-19 19:42:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Module to pack
|
|
|
|
if (!$list->modules->moduleExists($id)) {
|
|
|
|
throw new Exception(__('No such module.'));
|
|
|
|
}
|
|
|
|
$module = $list->modules->getModules($id);
|
|
|
|
|
|
|
|
# Excluded files and dirs
|
2022-11-20 21:06:36 +00:00
|
|
|
$exclude = [
|
2021-08-19 19:42:44 +00:00
|
|
|
'\.',
|
|
|
|
'\.\.',
|
|
|
|
'__MACOSX',
|
|
|
|
'\.svn',
|
|
|
|
'\.hg.*?',
|
|
|
|
'\.git.*?',
|
|
|
|
'CVS',
|
|
|
|
'\.directory',
|
|
|
|
'\.DS_Store',
|
2022-11-20 21:06:36 +00:00
|
|
|
'Thumbs\.db',
|
|
|
|
];
|
2021-08-19 19:42:44 +00:00
|
|
|
|
|
|
|
# Packages names
|
2022-11-20 21:06:36 +00:00
|
|
|
$files = [
|
2021-08-19 19:42:44 +00:00
|
|
|
$type . '-' . $id . '.zip',
|
2022-11-20 21:06:36 +00:00
|
|
|
$type . '-' . $id . '-' . $module['version'] . '.zip',
|
|
|
|
];
|
2021-08-19 19:42:44 +00:00
|
|
|
|
|
|
|
# Create zip
|
2022-11-20 21:06:36 +00:00
|
|
|
foreach ($files as $f) {
|
2021-08-19 19:42:44 +00:00
|
|
|
@set_time_limit(300);
|
|
|
|
$fp = fopen($root . '/' . $f, 'wb');
|
|
|
|
|
|
|
|
$zip = new fileZip($fp);
|
|
|
|
|
2022-11-20 21:06:36 +00:00
|
|
|
foreach ($exclude as $e) {
|
2021-08-19 19:42:44 +00:00
|
|
|
$zip->addExclusion(sprintf(
|
2022-11-20 21:06:36 +00:00
|
|
|
'#(^|/)(%s)(/|$)#',
|
2021-08-19 19:42:44 +00:00
|
|
|
$e
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
$zip->addDirectory($module['root'], $id, true);
|
|
|
|
$zip->write();
|
|
|
|
$zip->close();
|
|
|
|
unset($zip);
|
|
|
|
}
|
|
|
|
|
|
|
|
dcPage::addSuccessNotice(
|
|
|
|
__('Task successfully executed.')
|
|
|
|
);
|
|
|
|
http::redirect($list->getURL());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check and create directories used by packer
|
|
|
|
* @return string|boolean Cleaned path or false on error
|
|
|
|
*/
|
2022-11-13 22:43:30 +00:00
|
|
|
public static function repositoryDir()
|
2021-08-19 19:42:44 +00:00
|
|
|
{
|
|
|
|
$dir = path::real(
|
2022-11-20 21:06:36 +00:00
|
|
|
dcCore::app()->blog->public_path . '/' . tinyPacker::$sub_dir,
|
2021-08-19 19:42:44 +00:00
|
|
|
false
|
|
|
|
);
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (!is_dir($dir)) {
|
|
|
|
files::makeDir($dir, true);
|
|
|
|
}
|
|
|
|
if (is_writable($dir)) {
|
|
|
|
return $dir;
|
|
|
|
}
|
2022-11-20 21:06:36 +00:00
|
|
|
} catch(Exception $e) {
|
2021-08-19 19:42:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2022-11-20 21:06:36 +00:00
|
|
|
}
|