Skip to content

Commit b5f47ae

Browse files
authored
Merge pull request #103 from ggoffy/master
- added clone feature
2 parents a107010 + c5c65ab commit b5f47ae

8 files changed

Lines changed: 227 additions & 1 deletion

File tree

class/Files/Admin/AdminMenu.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ private function getAdminMenuList($module, $language, $langAbout, $menu)
167167
$ret .= $this->getAdminMenuArray($param2, true);
168168
}
169169
++$menu;
170+
$param3 = ['title' => "{$language}{$menu}", 'link' => "'admin/clone.php'", 'icon' => "\$sysPathIcon32.'/page_copy.png'"];
171+
$ret .= $this->getAdminMenuArray($param3, true);
172+
++$menu;
170173
$param3 = ['title' => "{$language}{$menu}", 'link' => "'admin/feedback.php'", 'icon' => "\$sysPathIcon32.'/mail_foward.png'"];
171174
$ret .= $this->getAdminMenuArray($param3, true);
172175
unset($menu);

class/Files/Language/LanguageAdmin.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ public function getLanguageAdminClass($language, $tables)
268268
$ret .= $this->ld->getDefine($language, 'LIST_2', 'Sample List Value 2');
269269
$ret .= $this->ld->getDefine($language, 'LIST_3', 'Sample List Value 3');
270270
}
271+
$ret .= $this->ld->getAboveDefines('Clone feature');
272+
$ret .= $this->ld->getDefine($language, 'CLONE', 'Clone');
273+
$ret .= $this->ld->getDefine($language, 'CLONE_DSC', 'Cloning a module has never been this easy! Just type in the name you want for it and hit submit button!');
274+
$ret .= $this->ld->getDefine($language, 'CLONE_TITLE', 'Clone %s');
275+
$ret .= $this->ld->getDefine($language, 'CLONE_NAME', 'Choose a name for the new module');
276+
$ret .= $this->ld->getDefine($language, 'CLONE_NAME_DSC', 'Do not use special characters! <br>Do not choose an existing module dirname or database table name!');
277+
$ret .= $this->ld->getDefine($language, 'CLONE_INVALIDNAME', 'ERROR: Invalid module name, please try another one!');
278+
$ret .= $this->ld->getDefine($language, 'CLONE_EXISTS', 'ERROR: Module name already taken, please try another one!');
279+
$ret .= $this->ld->getDefine($language, 'CLONE_CONGRAT', 'Congratulations! %s was sucessfully created!<br>You may want to make changes in language files.');
280+
$ret .= $this->ld->getDefine($language, 'CLONE_IMAGEFAIL', 'Attention, we failed creating the new module logo. Please consider modifying assets/images/logo_module.png manually!');
281+
$ret .= $this->ld->getDefine($language, 'CLONE_FAIL', 'Sorry, we failed in creating the new clone. Maybe you need to temporally set write permissions (CHMOD 777) to modules folder and try again.');
271282

272283
return $ret;
273284
}

class/Files/Language/LanguageModinfo.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ private function getLanguageMenu($module, $language)
137137
$ret .= $this->ld->getDefine($language, "ADMENU{$menu}", 'Permissions');
138138
}
139139
++$menu;
140+
$ret .= $this->ld->getDefine($language, "ADMENU{$menu}", 'Clone');
141+
++$menu;
140142
$ret .= $this->ld->getDefine($language, "ADMENU{$menu}", 'Feedback');
141143
$ret .= $this->ld->getDefine($language, 'ABOUT', 'About');
142144
unset($menu, $tablePermissions);

class/Files/User/UserXoopsVersion.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ private function getXoopsVersionTemplatesAdminUser($moduleDirname, $tables, $adm
310310
if (\in_array(1, $tablePermissions)) {
311311
$item[] = $this->getXoopsVersionTemplatesLine($moduleDirname, 'permissions', '', true);
312312
}
313+
$item[] = $this->getXoopsVersionTemplatesLine($moduleDirname, 'clone', '', true);
313314
$item[] = $this->getXoopsVersionTemplatesLine($moduleDirname, 'footer', '', true);
314315
}
315316

docs/changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- fixed bug in permissionHandler (goffy)
2727
- fixed bug with ..._LIST (mjoel/goffy)
2828
- fixed bug in test data (mjoel/goffy)
29+
- added clone feature (mjoel/goffy)
2930

3031
<h5>3.04 Final [2020-11-11]</h5> Dev: XOOPS 2.5.11, PHP 7.4.5
3132
<hr>

files/commonfiles/admin/clone.php

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
<?php
2+
/*
3+
You may not change or alter any portion of this comment or credits
4+
of supporting developers from this source code or any supporting source code
5+
which is considered copyrighted (c) material of the original comment or credit authors.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10+
*/
11+
12+
/**
13+
* Modulebuilder module for xoops
14+
*
15+
* @copyright module for xoops
16+
* @license GPL 2.0 or later
17+
* @package modulebuilder
18+
* @since 1.0
19+
* @min_xoops 2.5.11
20+
* @author Wedega - Email:<webmaster@wedega.com> - Website:<https://wedega.com>
21+
* @version $Id: 1.0 images.php 1 Mon 2018-03-19 10:04:51Z XOOPS Project (www.xoops.org) $
22+
*/
23+
24+
use Xmf\Request;
25+
26+
require __DIR__ . '/header.php';
27+
// It recovered the value of argument op in URL$
28+
$op = Request::getString('op', 'list');
29+
30+
$templateMain = 'modulebuilder_admin_clone.tpl';
31+
32+
switch ($op) {
33+
case 'list':
34+
default:
35+
$GLOBALS['xoopsTpl']->assign('navigation', $adminObject->displayNavigation('clone.php'));
36+
require_once $GLOBALS['xoops']->path('class/xoopsformloader.php');
37+
$form = new \XoopsThemeForm(\sprintf(\_AM_MODULEBUILDER_CLONE_TITLE, $helper->getModule()->getVar('name', 'E')), 'clone', 'clone.php', 'post', true);
38+
$clone = new \XoopsFormText(\_AM_MODULEBUILDER_CLONE_NAME, 'clone', 20, 20, '');
39+
$clone->setDescription(\_AM_MODULEBUILDER_CLONE_NAME_DSC);
40+
$form->addElement($clone, true);
41+
$form->addElement(new \XoopsFormHidden('op', 'submit'));
42+
$form->addElement(new \XoopsFormButton('', '', \_SUBMIT, 'submit'));
43+
$GLOBALS['xoopsTpl']->assign('form', $form->render());
44+
45+
break;
46+
case 'submit':
47+
// Security Check
48+
if (!$GLOBALS['xoopsSecurity']->check()) {
49+
\redirect_header('clone.php', 3, \implode(',', $GLOBALS['xoopsSecurity']->getErrors()));
50+
}
51+
$clone = Request::getString('clone', '', 'POST');
52+
//check if name is valid
53+
if (empty($clone) || \preg_match('/[^a-zA-Z0-9\_\-]/', $clone)) {
54+
\redirect_header('clone.php', 3, \sprintf(\_AM_MODULEBUILDER_CLONE_INVALIDNAME, $clone));
55+
}
56+
57+
// Check wether the cloned module exists or not
58+
$dirClone = $GLOBALS['xoops']->path('modules/' . $clone);
59+
if ($clone && \is_dir($dirClone)) {
60+
\redirect_header('clone.php', 3, \sprintf(\_AM_MODULEBUILDER_CLONE_EXISTS, $clone));
61+
}
62+
63+
$patterns = [
64+
\mb_strtolower(\MODULEBUILDER_DIRNAME) => \mb_strtolower($clone),
65+
\mb_strtoupper(\MODULEBUILDER_DIRNAME) => \mb_strtoupper($clone),
66+
\ucfirst(\mb_strtolower(\MODULEBUILDER_DIRNAME)) => \ucfirst(\mb_strtolower($clone)),
67+
];
68+
69+
$patKeys = \array_keys($patterns);
70+
$patValues = \array_values($patterns);
71+
cloneFileFolder(\MODULEBUILDER_PATH);
72+
$logocreated = createLogo(\mb_strtolower($clone));
73+
74+
//change module name in modinfo.php
75+
// file, read it
76+
$content = file_get_contents($dirClone . '/language/english/modinfo.php');
77+
$content = \str_replace('Modulebuilder', \mb_strtolower($clone), $content);
78+
file_put_contents($dirClone . '/language/english/modinfo.php', $content);
79+
80+
$msg = '';
81+
if (\is_dir($GLOBALS['xoops']->path('modules/' . \mb_strtolower($clone)))) {
82+
$msg .= \sprintf(\_AM_MODULEBUILDER_CLONE_CONGRAT, "<a href='" . \XOOPS_URL . "/modules/system/admin.php?fct=modulesadmin&op=installlist'>" . \ucfirst(\mb_strtolower($clone)) . '</a>') . "<br>\n";
83+
if (!$logocreated) {
84+
$msg .= \_AM_MODULEBUILDER_CLONE_IMAGEFAIL;
85+
}
86+
} else {
87+
$msg .= \_AM_MODULEBUILDER_CLONE_FAIL;
88+
}
89+
$GLOBALS['xoopsTpl']->assign('result', $msg);
90+
break;
91+
}
92+
require __DIR__ . '/footer.php';
93+
94+
// recursive cloning script
95+
/**
96+
* @param $path
97+
*/
98+
function cloneFileFolder($path)
99+
{
100+
global $patKeys;
101+
global $patValues;
102+
103+
//remove \XOOPS_ROOT_PATH and add after replace, otherwise there can be a bug if \XOOPS_ROOT_PATH contains same pattern
104+
$newPath = \XOOPS_ROOT_PATH . \str_replace($patKeys[0], $patValues[0], \substr($path, \strlen(\XOOPS_ROOT_PATH)));
105+
106+
if (\is_dir($path)) {
107+
// create new dir
108+
if (!\mkdir($newPath) && !\is_dir($newPath)) {
109+
throw new \RuntimeException(\sprintf('Directory "%s" was not created', $newPath));
110+
}
111+
112+
// check all files in dir, and process it
113+
$handle = \opendir($path);
114+
if ($handle) {
115+
while (false !== ($file = \readdir($handle))) {
116+
if (0 !== mb_strpos($file, '.')) {
117+
cloneFileFolder("{$path}/{$file}");
118+
}
119+
}
120+
\closedir($handle);
121+
}
122+
} else {
123+
$noChangeExtensions = ['jpeg', 'jpg', 'gif', 'png', 'zip', 'ttf'];
124+
if (\in_array(\mb_strtolower(\pathinfo($path, \PATHINFO_EXTENSION)), $noChangeExtensions, true)) {
125+
// image
126+
\copy($path, $newPath);
127+
} else {
128+
// file, read it
129+
$content = file_get_contents($path);
130+
$content = \str_replace($patKeys, $patValues, $content);
131+
file_put_contents($newPath, $content);
132+
}
133+
}
134+
}
135+
136+
/**
137+
* @param $dirname
138+
*
139+
* @return bool
140+
*/
141+
function createLogo($dirname)
142+
{
143+
if (!\extension_loaded('gd')) {
144+
return false;
145+
}
146+
$requiredFunctions = [
147+
'imagecreatefrompng',
148+
'imagecolorallocate',
149+
'imagefilledrectangle',
150+
'imagepng',
151+
'imagedestroy',
152+
'imagefttext',
153+
'imagealphablending',
154+
'imagesavealpha',
155+
];
156+
foreach ($requiredFunctions as $func) {
157+
if (!\function_exists($func)) {
158+
return false;
159+
}
160+
}
161+
// unset($func);
162+
163+
if (!\file_exists($imageBase = $GLOBALS['xoops']->path('modules/' . $dirname . '/assets/images/logoModule.png'))
164+
|| !\file_exists($font = $GLOBALS['xoops']->path('modules/' . $dirname . '/assets/images/VeraBd.ttf'))) {
165+
return false;
166+
}
167+
168+
$imageModule = \imagecreatefrompng($imageBase);
169+
// save existing alpha channel
170+
imagealphablending($imageModule, false);
171+
imagesavealpha($imageModule, true);
172+
173+
//Erase old text
174+
$greyColor = \imagecolorallocate($imageModule, 237, 237, 237);
175+
\imagefilledrectangle($imageModule, 5, 35, 85, 46, $greyColor);
176+
177+
// Write text
178+
$textColor = \imagecolorallocate($imageModule, 0, 0, 0);
179+
$spaceToBorder = (int)((80 - mb_strlen($dirname) * 6.5) / 2);
180+
\imagefttext($imageModule, 8.5, 0, $spaceToBorder, 45, $textColor, $font, \ucfirst($dirname), []);
181+
182+
// Set transparency color
183+
//$white = imagecolorallocatealpha($imageModule, 255, 255, 255, 127);
184+
//imagefill($imageModule, 0, 0, $white);
185+
//imagecolortransparent($imageModule, $white);
186+
187+
\imagepng($imageModule, $GLOBALS['xoops']->path('modules/' . $dirname . '/assets/images/logoModule.png'));
188+
\imagedestroy($imageModule);
189+
190+
return true;
191+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!-- Header -->
2+
<{include file='db:modulebuilder_admin_header.tpl' }>
3+
4+
<{if $form|default:''}>
5+
<{$form|default:false}>
6+
<{/if}>
7+
<{if $result|default:''}>
8+
<{$result|default:false}>
9+
<{/if}>
10+
<{if $error|default:''}>
11+
<div class="errorMsg"><strong><{$error|default:false}></strong></div>
12+
<{/if}>
13+
14+
<!-- Footer -->
15+
<{include file='db:modulebuilder_admin_footer.tpl' }>

include/update.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,9 @@ function clean_index_files()
728728
$files[] = XOOPS_ROOT_PATH . '/modules/modulebuilder/files/ratingfiles/templates/index.php';
729729

730730
foreach($files as $file) {
731-
unlink($file);
731+
if (\file_exists($file)) {
732+
\unlink($file);
733+
}
732734
}
733735

734736
return true;

0 commit comments

Comments
 (0)