admin/mytplsadmin.php
<?php
/*
* You may not change or alter any portion of this comment or credits
* of supporting developers from this source code or any supporting source code
* which is considered copyrighted (c) material of the original comment or credit authors.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* @copyright {@link http://xoops.org/ XOOPS Project}
* @license {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
* @package
* @since
* @author XOOPS Development Team,
* @author GIJ=CHECKMATE (PEAK Corp. http://www.peak.ne.jp/)
*/
require_once __DIR__ . '/../../../include/cp_header.php';
require_once __DIR__ . '/../include/gtickets.php';
require_once XOOPS_ROOT_PATH . '/class/template.php';
// initials
$xoops_system_path = XOOPS_ROOT_PATH . '/modules/system';
$db = XoopsDatabaseFactory::getDatabaseConnection();
$myts = MyTextSanitizer::getInstance();
// determine language
$language = $xoopsConfig['language'];
if (!file_exists("$xoops_system_path/language/$language/admin/tplsets.php")) {
$language = 'english';
}
// load language constants
// to prevent from notice that constants already defined
$error_reporting_level = error_reporting(0);
require_once "$xoops_system_path/constants.php";
require_once "$xoops_system_path/language/$language/admin.php";
require_once "$xoops_system_path/language/$language/admin/tplsets.php";
error_reporting($error_reporting_level);
// check $xoopsModule
if (!is_object($xoopsModule)) {
redirect_header(XOOPS_URL . '/user.php', 1, _NOPERM);
}
// set target_module if specified by $_GET['dirname']
/** @var XoopsModuleHandler $moduleHandler */
$moduleHandler = xoops_getHandler('module');
if (!empty($_GET['dirname'])) {
$target_module = $moduleHandler->getByDirname($_GET['dirname']);
}
if (!empty($target_module) && is_object($target_module)) {
// specified by dirname (for tplsadmin as an independent module)
$target_mid = $target_module->getVar('mid');
$target_dirname = $target_module->getVar('dirname');
$target_dirname4sql = addslashes($target_dirname);
$target_mname = $target_module->getVar('name') . ' ' . sprintf('(%2.2f)', $target_module->getVar('version') / 100.0);
$query4redirect = '?dirname=' . urlencode(strip_tags($_GET['dirname']));
} else {
// not specified by dirname (for 3rd party modules as mytplsadmin)
$target_mid = $xoopsModule->getVar('mid');
$target_dirname = $xoopsModule->getVar('dirname');
$target_dirname4sql = addslashes($target_dirname);
$target_mname = $xoopsModule->getVar('name');
$query4redirect = '';
}
// check access right (needs system_admin of tplset)
$syspermHandler = xoops_getHandler('groupperm');
if (!$syspermHandler->checkRight('system_admin', XOOPS_SYSTEM_TPLSET, $xoopsUser->getGroups())) {
redirect_header(XOOPS_URL . '/user.php', 1, _NOPERM);
}
//**************//
// POST stages //
//**************//
// Newly DB template clone (all of module)
if (!empty($_POST['clone_tplset_do']) && !empty($_POST['clone_tplset_from']) && !empty($_POST['clone_tplset_to'])) {
// Ticket Check
if (!$xoopsGTicket->check()) {
redirect_header(XOOPS_URL . '/', 3, $xoopsGTicket->getErrors());
}
$tplset_from = $myts->stripSlashesGPC($_POST['clone_tplset_from']);
$tplset_to = $myts->stripSlashesGPC($_POST['clone_tplset_to']);
// check tplset_name "from" and "to"
if (!preg_match('/^[0-9A-Za-z_-]{1,16}$/', $_POST['clone_tplset_from'])) {
die('a wrong template name is specified.');
}
if (!preg_match('/^[0-9A-Za-z_-]{1,16}$/', $_POST['clone_tplset_to'])) {
die('a wrong template name is specified.');
}
list($is_exist) = $db->fetchRow($db->query('SELECT COUNT(*) FROM ' . $db->prefix('tplfile') . " WHERE tpl_tplset='" . addslashes($tplset_to) . "'"));
if ($is_exist) {
die('The template already exists.');
}
list($is_exist) = $db->fetchRow($db->query('SELECT COUNT(*) FROM ' . $db->prefix('tplset') . " WHERE tplset_name='" . addslashes($tplset_to) . "'"));
if ($is_exist) {
die('The template already exists.');
}
// insert tplset table
$db->query('INSERT INTO ' . $db->prefix('tplset') . " SET tplset_name='" . addslashes($tplset_to) . "', tplset_desc='Created by tplsadmin', tplset_created=UNIX_TIMESTAMP()");
copy_templates_db2db($tplset_from, $tplset_to, "tpl_module='$target_dirname4sql'");
redirect_header('mytplsadmin.php?dirname=' . $target_dirname, 1, _AM_APCALAM_APCALDBUPDATED);
exit;
}
// DB to DB template copy (checked templates)
if (is_array(@$_POST['copy_do'])) {
foreach ($_POST['copy_do'] as $tplset_from_tmp => $val) {
if (!empty($val)) {
// Ticket Check
if (!$xoopsGTicket->check()) {
redirect_header(XOOPS_URL . '/', 3, $xoopsGTicket->getErrors());
}
$tplset_from = $myts->stripSlashesGPC($tplset_from_tmp);
if (empty($_POST['copy_to'][$tplset_from]) || $_POST['copy_to'][$tplset_from] == $tplset_from) {
die('Specify valid tplset.');
}
if (empty($_POST["{$tplset_from}_check"])) {
die('No template is specified');
}
$tplset_to = $myts->stripSlashesGPC($_POST['copy_to'][$tplset_from]);
foreach ($_POST["{$tplset_from}_check"] as $tplfile_tmp => $val) {
if (empty($val)) {
continue;
}
$tplfile = $myts->stripSlashesGPC($tplfile_tmp);
copy_templates_db2db($tplset_from, $tplset_to, "tpl_file='" . addslashes($tplfile) . "'");
}
redirect_header('mytplsadmin.php?dirname=' . $target_dirname, 1, _AM_APCALAM_APCALDBUPDATED);
exit;
}
}
}
// File to DB template copy (checked templates)
if (!empty($_POST['copyf2db_do'])) {
// Ticket Check
if (!$xoopsGTicket->check()) {
redirect_header(XOOPS_URL . '/', 3, $xoopsGTicket->getErrors());
}
if (empty($_POST['copyf2db_to'])) {
die('Specify valid tplset.');
}
if (empty($_POST['basecheck'])) {
die('No template is specified');
}
$tplset_to = $myts->stripSlashesGPC($_POST['copyf2db_to']);
foreach ($_POST['basecheck'] as $tplfile_tmp => $val) {
if (empty($val)) {
continue;
}
$tplfile = $myts->stripSlashesGPC($tplfile_tmp);
copy_templates_f2db($tplset_to, "tpl_file='" . addslashes($tplfile) . "'");
}
redirect_header('mytplsadmin.php?dirname=' . $target_dirname, 1, _AM_APCALAM_APCALDBUPDATED);
exit;
}
// DB template remove (checked templates)
if (is_array(@$_POST['del_do'])) {
foreach ($_POST['del_do'] as $tplset_from_tmp => $val) {
if (!empty($val)) {
// Ticket Check
if (!$xoopsGTicket->check()) {
redirect_header(XOOPS_URL . '/', 3, $xoopsGTicket->getErrors());
}
$tplset_from = $myts->stripSlashesGPC($tplset_from_tmp);
if ($tplset_from === 'default') {
die("You can't remove 'default' template.");
}
$tpl = new XoopsTpl();
$tpl->force_compile = true;
foreach ($_POST["{$tplset_from}_check"] as $tplfile_tmp => $val) {
if (empty($val)) {
continue;
}
$tplfile = $myts->stripSlashesGPC($tplfile_tmp);
$result = $db->query('SELECT tpl_id FROM ' . $db->prefix('tplfile') . " WHERE tpl_tplset='" . addslashes($tplset_from) . "' AND tpl_file='" . addslashes($tplfile) . "'");
while (list($tpl_id) = $db->fetchRow($result)) {
$tpl_id = (int)$tpl_id;
$db->query('DELETE FROM ' . $db->prefix('tplfile') . " WHERE tpl_id=$tpl_id");
$db->query('DELETE FROM ' . $db->prefix('tplsource') . " WHERE tpl_id=$tpl_id");
}
// remove templates_c
$tpl->clear_cache('db:' . $tplfile);
$tpl->clear_compiled_tpl('db:' . $tplfile);
}
redirect_header('mytplsadmin.php?dirname=' . $target_dirname, 1, _AM_APCALAM_APCALDBUPDATED);
exit;
}
}
}
//************//
// GET stage //
//************//
// get tplsets
$sql = 'SELECT DISTINCT tpl_tplset FROM ' . $db->prefix('tplfile') . " ORDER BY tpl_tplset='default' DESC,tpl_tplset";
$srs = $db->query($sql);
$tplsets = array();
$tplsets_th4disp = '';
$tplset_options = "<option value=''>----</option>\n";
while (list($tplset) = $db->fetchRow($srs)) {
$tplset4disp = htmlspecialchars($tplset, ENT_QUOTES);
$tplsets[] = $tplset;
$th_style = $tplset == $xoopsConfig['template_set'] ? "style='color:yellow;'" : '';
$tplsets_th4disp .= "<th $th_style><input type='checkbox' onclick=\"with(document.MainForm){for (i=0;i<length;i++) {if(elements[i].type=='checkbox'&&elements[i].name.indexOf('{$tplset4disp}_check')>=0) {elements[i].checked=this.checked;}}}\" />DB-{$tplset4disp}</th>";
$tplset_options .= "<option value='$tplset4disp'>$tplset4disp</option>\n";
}
// get tpl_file owned by the module
$sql = 'SELECT tpl_file,tpl_desc,tpl_type,COUNT(tpl_id) FROM ' . $db->prefix('tplfile') . " WHERE tpl_module='$target_dirname4sql' GROUP BY tpl_file ORDER BY tpl_type, tpl_file";
$frs = $db->query($sql);
xoops_cp_header();
echo "<h3 style='text-align:left;'>" . _MD_APCAL_TPLSETS . " : $target_mname</h3>\n";
// beggining of table & form
echo "
<form class='apcalForm' id='MainForm' name='MainForm' action='?dirname=" . htmlspecialchars($target_dirname, ENT_QUOTES) . "' method='post'>
" . $xoopsGTicket->getTicketHtml(__LINE__) . "
<table class='outer'>
<tr>
<th>" . _MD_APCAL_FILENAME . "</th>
<th>type</th>
<th><input type='checkbox' onclick=\"with(document.MainForm){for (i=0;i<length;i++) {if(elements[i].type=='checkbox'&&elements[i].name.indexOf('basecheck')>=0) {elements[i].checked=this.checked;}}}\" />file</th>
$tplsets_th4disp
</tr>\n";
// STYLE for distinguishing fingerprints
$fingerprint_styles = array(
'',
'background-color:#00FF00',
'background-color:#00CC88',
'background-color:#00FFFF',
'background-color:#0088FF',
'background-color:#FF8800',
'background-color:#0000FF',
'background-color:#FFFFFF'
);
// template ROWS
while (list($tpl_file, $tpl_desc, $type, $count) = $db->fetchRow($frs)) {
$evenodd = @$evenodd === 'even' ? 'odd' : 'even';
$fingerprint_style_count = 0;
// information about the template
echo "
<tr>
<td class='$evenodd'>
<dl>
<dt>" . htmlspecialchars($tpl_file, ENT_QUOTES) . '</dt>
<dd>' . htmlspecialchars($tpl_desc, ENT_QUOTES) . "</dd>
</dl>
</td>
<td class='$evenodd'>" . $type . '<br>(' . $count . ")</td>\n";
// the base file template column
$basefilepath = XOOPS_ROOT_PATH . '/modules/' . $target_dirname . '/templates/' . ($type === 'block' ? 'blocks/' : '') . $tpl_file;
if (file_exists($basefilepath)) {
$fingerprint = get_fingerprint(file($basefilepath));
$fingerprints[$fingerprint] = 1;
echo "<td class='$evenodd'>"
. formatTimestamp(filemtime($basefilepath), 'm')
. '<br>'
. substr($fingerprint, 0, 16)
. "<br><input type='checkbox' name='basecheck[$tpl_file]' value='1' /></td>\n";
} else {
echo "<td class='$evenodd'><br></td>";
}
// db template columns
foreach ($tplsets as $tplset) {
$tplset4disp = htmlspecialchars($tplset, ENT_QUOTES);
// query for templates in db
$drs = $db->query('SELECT * FROM '
. $db->prefix('tplfile')
. ' f NATURAL LEFT JOIN '
. $db->prefix('tplsource')
. " s WHERE tpl_file='"
. addslashes($tpl_file)
. "' AND tpl_tplset='"
. addslashes($tplset)
. "'");
$numrows = $db->getRowsNum($drs);
$tpl = $db->fetchArray($drs);
if (empty($tpl['tpl_id'])) {
echo "<td class='$evenodd'>($numrows)</td>\n";
} else {
$fingerprint = get_fingerprint(explode("\n", $tpl['tpl_source']));
if (isset($fingerprints[$fingerprint])) {
$style = $fingerprints[$fingerprint];
} else {
++$fingerprint_style_count;
$style = $fingerprint_styles[$fingerprint_style_count];
$fingerprints[$fingerprint] = $style;
}
echo "<td class='$evenodd' style='$style;'>"
. formatTimestamp($tpl['tpl_lastmodified'], 'm')
. '<br>'
. substr($fingerprint, 0, 16)
. "<br><input type='checkbox' name='{$tplset4disp}_check[{$tpl_file}]' value='1' /> <a href='mytplsform.php?tpl_file="
. htmlspecialchars($tpl['tpl_file'], ENT_QUOTES)
. '&tpl_tplset='
. htmlspecialchars($tpl['tpl_tplset'], ENT_QUOTES)
. "'>"
. _EDIT
. "</a> ($numrows)</td>\n";
}
}
echo "</tr>\n";
}
// command submit ROW
echo "
<tr>
<td class='head'>
"
. _CLONE
. ": <br>
<select name='clone_tplset_from'>$tplset_options</select>-><input type='text' name='clone_tplset_to' size='8' /><input type='submit' name='clone_tplset_do' value='"
. _MD_APCAL_GENERATE
. "' />
</td>
<td class='head'></td>
<td class='head'>
<input name='copyf2db_do' type='submit' value='copy to->' /><br>
<select name='copyf2db_to'>$tplset_options
</td>\n";
foreach ($tplsets as $tplset) {
$tplset4disp = htmlspecialchars($tplset, ENT_QUOTES);
echo "\t\t<td class='head'>
" . ($tplset === 'default' ? '' : "<input name='del_do[{$tplset4disp}]' type='submit' value='" . _DELETE . "' onclick='return confirm(\"" . _DELETE . " OK?\");' /><br>") . "
<input name='copy_do[{$tplset4disp}]' type='submit' value='copy to->' /><br>
<select name='copy_to[{$tplset4disp}]'>$tplset_options</select>
</td>\n";
}
echo " </tr>\n";
echo '</table></form>';
// end of table & form
xoops_cp_footer();
/**
* @param $lines
* @return string
*/
function get_fingerprint($lines)
{
$str = '';
foreach ($lines as $line) {
if (trim($line)) {
$str .= md5(trim($line));
}
}
return md5($str);
}
/**
* @param $tplset_from
* @param $tplset_to
* @param string $whr_append
*/
function copy_templates_db2db($tplset_from, $tplset_to, $whr_append = '1')
{
global $db;
// get tplfile and tplsource
$result = $db->query("SELECT tpl_refid,tpl_module,'"
. addslashes($tplset_to)
. "',tpl_file,tpl_desc,tpl_lastmodified,tpl_lastimported,tpl_type,tpl_source FROM "
. $db->prefix('tplfile')
. ' NATURAL LEFT JOIN '
. $db->prefix('tplsource')
. " WHERE tpl_tplset='"
. addslashes($tplset_from)
. "' AND ($whr_append)");
while ($row = $db->fetchArray($result)) {
$tpl_source = array_pop($row);
$drs = $db->query('SELECT tpl_id FROM '
. $db->prefix('tplfile')
. " WHERE tpl_tplset='"
. addslashes($tplset_to)
. "' AND ($whr_append) AND tpl_file='"
. addslashes($row['tpl_file'])
. "' AND tpl_refid='"
. addslashes($row['tpl_refid'])
. "'");
if (!$db->getRowsNum($drs)) {
// INSERT mode
$sql = 'INSERT INTO ' . $db->prefix('tplfile') . ' (tpl_refid,tpl_module,tpl_tplset,tpl_file,tpl_desc,tpl_lastmodified,tpl_lastimported,tpl_type) VALUES (';
foreach ($row as $colval) {
$sql .= "'" . addslashes($colval) . "',";
}
$db->query(substr($sql, 0, -1) . ')');
$tpl_id = $db->getInsertId();
$db->query('INSERT INTO ' . $db->prefix('tplsource') . " SET tpl_id='$tpl_id', tpl_source='" . addslashes($tpl_source) . "'");
xoops_template_touch($tpl_id);
} else {
while (list($tpl_id) = $db->fetchRow($drs)) {
// UPDATE mode
$db->query('UPDATE '
. $db->prefix('tplfile')
. " SET tpl_refid='"
. addslashes($row['tpl_refid'])
. "',tpl_desc='"
. addslashes($row['tpl_desc'])
. "',tpl_lastmodified='"
. addslashes($row['tpl_lastmodified'])
. "',tpl_lastimported='"
. addslashes($row['tpl_lastimported'])
. "',tpl_type='"
. addslashes($row['tpl_type'])
. "' WHERE tpl_id='$tpl_id'");
$db->query('UPDATE ' . $db->prefix('tplsource') . " SET tpl_source='" . addslashes($tpl_source) . "' WHERE tpl_id='$tpl_id'");
xoops_template_touch($tpl_id);
}
}
}
}
/**
* @param $tplset_to
* @param string $whr_append
*/
function copy_templates_f2db($tplset_to, $whr_append = '1')
{
global $db;
// get tplsource
$result = $db->query('SELECT * FROM ' . $db->prefix('tplfile') . " WHERE tpl_tplset='default' AND ($whr_append)");
while ($row = $db->fetchArray($result)) {
$basefilepath = XOOPS_ROOT_PATH . '/modules/' . $row['tpl_module'] . '/templates/' . ($row['tpl_type'] === 'block' ? 'blocks/' : '') . $row['tpl_file'];
$tpl_source = rtrim(implode('', file($basefilepath)));
$lastmodified = filemtime($basefilepath);
$drs = $db->query('SELECT tpl_id FROM '
. $db->prefix('tplfile')
. " WHERE tpl_tplset='"
. addslashes($tplset_to)
. "' AND ($whr_append) AND tpl_file='"
. addslashes($row['tpl_file'])
. "' AND tpl_refid='"
. addslashes($row['tpl_refid'])
. "'");
if (!$db->getRowsNum($drs)) {
// INSERT mode
$sql = 'INSERT INTO '
. $db->prefix('tplfile')
. " SET tpl_refid='"
. addslashes($row['tpl_refid'])
. "',tpl_desc='"
. addslashes($row['tpl_desc'])
. "',tpl_lastmodified='"
. addslashes($lastmodified)
. "',tpl_type='"
. addslashes($row['tpl_type'])
. "',tpl_tplset='"
. addslashes($tplset_to)
. "',tpl_file='"
. addslashes($row['tpl_file'])
. "',tpl_module='"
. addslashes($row['tpl_module'])
. "'";
$db->query($sql);
$tpl_id = $db->getInsertId();
$db->query('INSERT INTO ' . $db->prefix('tplsource') . " SET tpl_id='$tpl_id', tpl_source='" . addslashes($tpl_source) . "'");
xoops_template_touch($tpl_id);
} else {
while (list($tpl_id) = $db->fetchRow($drs)) {
// UPDATE mode
$db->query('UPDATE ' . $db->prefix('tplfile') . " SET tpl_lastmodified='" . addslashes($lastmodified) . "' WHERE tpl_id='$tpl_id'");
$db->query('UPDATE ' . $db->prefix('tplsource') . " SET tpl_source='" . addslashes($tpl_source) . "' WHERE tpl_id='$tpl_id'");
xoops_template_touch($tpl_id);
}
}
}
}