mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
605 lines
14 KiB
PHP
605 lines
14 KiB
PHP
<?php
|
|
|
|
namespace Zotlabs\Module;
|
|
|
|
use App;
|
|
use Zotlabs\Web\Controller;
|
|
use Zotlabs\Render\Comanche;
|
|
use Zotlabs\Lib\Libsync;
|
|
use Zotlabs\Lib\Apps;
|
|
|
|
class Pdledit_gui extends Controller {
|
|
|
|
function post() {
|
|
|
|
if (!local_channel()) {
|
|
return;
|
|
}
|
|
|
|
if (!$_REQUEST['module']) {
|
|
return;
|
|
}
|
|
|
|
$module = $_REQUEST['module'];
|
|
|
|
$ret = [
|
|
'success' => false,
|
|
'module' => $module
|
|
];
|
|
|
|
if ($_REQUEST['reset']) {
|
|
del_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl');
|
|
Libsync::build_sync_packet();
|
|
$ret['success'] = true;
|
|
json_return_and_die($ret);
|
|
}
|
|
|
|
if ($_REQUEST['save']) {
|
|
if (!$_REQUEST['data']) {
|
|
return $ret;
|
|
}
|
|
|
|
$data = json_decode($_REQUEST['data'],true);
|
|
$stored_pdl_result = self::get_pdl($module);
|
|
$pdl = $stored_pdl_result['pdl'];
|
|
|
|
foreach ($data as $region => $entries) {
|
|
$region_pdl = '';
|
|
foreach ($entries as $entry) {
|
|
$region_pdl .= base64_decode($entry) . "\r\n";
|
|
}
|
|
$pdl = preg_replace('/\[region=' . $region . '\](.*?)\[\/region\]/ism', '[region=' . $region . ']' . "\r\n" . $region_pdl . "\r\n" . '[/region]', $pdl);
|
|
}
|
|
|
|
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
|
|
Libsync::build_sync_packet();
|
|
|
|
$ret['success'] = true;
|
|
json_return_and_die($ret);
|
|
}
|
|
|
|
if ($_REQUEST['save_src']) {
|
|
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($_REQUEST['src']));
|
|
Libsync::build_sync_packet();
|
|
|
|
$ret['success'] = true;
|
|
json_return_and_die($ret);
|
|
}
|
|
|
|
if ($_REQUEST['save_template']) {
|
|
if (!$_REQUEST['data']) {
|
|
return $ret;
|
|
}
|
|
|
|
$template = $_REQUEST['data'][0]['value'];
|
|
$pdl_result = self::get_pdl($module);
|
|
$stored_template = self::get_template($pdl_result['pdl']);
|
|
|
|
if ($template === $stored_template) {
|
|
$ret['success'] = true;
|
|
return $ret;
|
|
}
|
|
|
|
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl_result['pdl'], $matches);
|
|
if ($cnt) {
|
|
$pdl = str_replace('[template]' . $stored_template . '[/template]', '[template]' . $template . '[/template]', $pdl_result['pdl']);
|
|
}
|
|
else {
|
|
$pdl = '[template]' . $template . '[/template]' . "\r\n";
|
|
$pdl .= $pdl_result['pdl'];
|
|
}
|
|
|
|
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
|
|
Libsync::build_sync_packet();
|
|
|
|
$ret['success'] = true;
|
|
json_return_and_die($ret);
|
|
}
|
|
|
|
}
|
|
|
|
function get() {
|
|
|
|
if(! local_channel()) {
|
|
return EMPTY_STR;
|
|
}
|
|
|
|
$module = argv(1);
|
|
|
|
if (!$module) {
|
|
goaway(z_root() . '/pdledit_gui/hq');
|
|
}
|
|
|
|
$pdl_result = self::get_pdl($module);
|
|
|
|
$pdl = $pdl_result['pdl'];
|
|
$modified = $pdl_result['modified'];
|
|
|
|
if(!$pdl) {
|
|
return t('Layout not found');
|
|
}
|
|
|
|
$template = self::get_template($pdl);
|
|
|
|
$template_info = self::get_template_info($template);
|
|
|
|
if(empty($template_info['contentregion'])) {
|
|
return t('This template does not support pdledi_gui (no content regions defined)');
|
|
}
|
|
|
|
App::$page['template'] = $template;
|
|
|
|
$regions = self::get_regions($pdl);
|
|
|
|
foreach ($regions as $k => $v) {
|
|
$region_str = '';
|
|
if (is_array($v)) {
|
|
ksort($v);
|
|
foreach ($v as $entry) {
|
|
// Get the info from the file and replace entry if we get anything useful
|
|
$widget_info = get_widget_info($entry['name']);
|
|
$entry['name'] = (($widget_info['name']) ? $widget_info['name'] : $entry['name']);
|
|
$entry['desc'] = (($widget_info['description']) ? $widget_info['description'] : $entry['desc']);
|
|
|
|
$region_str .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
|
'$entry' => $entry
|
|
]);
|
|
}
|
|
}
|
|
App::$layout['region_' . $k] = $region_str;
|
|
}
|
|
|
|
$templates = self::get_templates();
|
|
$templates_html = replace_macros(get_markup_template('pdledit_gui_templates.tpl'), [
|
|
'$templates' => $templates,
|
|
'$active' => $template
|
|
]);
|
|
|
|
$items_html = '';
|
|
|
|
//$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
|
//'$entry' => [
|
|
//'type' => 'content',
|
|
//'name' => t('Main page content'),
|
|
//'src' => base64_encode('$content')
|
|
//],
|
|
//'$disable_controls' => true
|
|
//]);
|
|
|
|
foreach (self::get_widgets($module) as $entry) {
|
|
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
|
'$entry' => $entry,
|
|
'$disable_controls' => true
|
|
]);
|
|
}
|
|
|
|
foreach (self::get_menus() as $entry) {
|
|
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
|
'$entry' => $entry,
|
|
'$disable_controls' => true
|
|
]);
|
|
}
|
|
|
|
foreach (self::get_blocks() as $entry) {
|
|
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
|
'$entry' => $entry,
|
|
'$disable_controls' => true
|
|
]);
|
|
}
|
|
|
|
App::$layout['region_content'] .= replace_macros(get_markup_template('pdledit_gui.tpl'), [
|
|
'$content_regions' => $template_info['contentregion'],
|
|
'$page_src' => base64_encode($pdl),
|
|
'$templates' => base64_encode($templates_html),
|
|
'$modules' => base64_encode(self::get_modules()),
|
|
'$items' => base64_encode($items_html),
|
|
'$module_modified' => $modified,
|
|
'$module' => $module
|
|
]);
|
|
|
|
}
|
|
|
|
function get_templates() {
|
|
$ret = [];
|
|
|
|
$files = glob('view/php/*.php');
|
|
if($files) {
|
|
foreach($files as $f) {
|
|
$name = basename($f, '.php');
|
|
$x = get_template_info($name);
|
|
if(!empty($x['contentregion'])) {
|
|
$ret[] = [
|
|
'name' => $name,
|
|
'desc' => $x['description']
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function get_modules() {
|
|
$ret = '';
|
|
$arr = [];
|
|
|
|
$files = glob('Zotlabs/Module/*.php');
|
|
if($files) {
|
|
foreach($files as $f) {
|
|
$name = lcfirst(basename($f,'.php'));
|
|
|
|
if ($name === 'admin' && !is_site_admin()) {
|
|
continue;
|
|
}
|
|
|
|
$x = theme_include('mod_' . $name . '.pdl');
|
|
if($x) {
|
|
$arr[] = $name;
|
|
}
|
|
}
|
|
}
|
|
|
|
$addons = plugins_installed_list();
|
|
if ($addons) {
|
|
foreach ($addons as $name) {
|
|
if (!Apps::addon_app_installed(local_channel(), $name)) {
|
|
continue;
|
|
}
|
|
|
|
$path = 'addon/' . $name . '/mod_' . $name . '.pdl';
|
|
if (file_exists($path)) {
|
|
$arr[] = $name;
|
|
}
|
|
}
|
|
}
|
|
|
|
sort($arr);
|
|
|
|
foreach ($arr as $name) {
|
|
$ret .= '<div class="mb-2"><a href="pdledit_gui/' . $name . '">' . $name . '</a></div>';
|
|
}
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
function get_widgets($module) {
|
|
$ret = [];
|
|
|
|
|
|
$checkpaths = [
|
|
'Zotlabs/Widget/*.php'
|
|
];
|
|
|
|
$addons = plugins_installed_list();
|
|
|
|
if ($addons) {
|
|
foreach ($addons as $name) {
|
|
if (!Apps::addon_app_installed(local_channel(), $name)) {
|
|
continue;
|
|
}
|
|
|
|
$path = 'addon/' . $name . '/Widget';
|
|
if (is_dir($path)) {
|
|
$checkpaths[] = $path . '/*.php';
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($checkpaths as $path) {
|
|
$files = glob($path);
|
|
|
|
if($files) {
|
|
foreach($files as $f) {
|
|
$name = lcfirst(basename($f, '.php'));
|
|
|
|
$widget_info = get_widget_info($name);
|
|
if ($widget_info['requires'] && strpos($widget_info['requires'], 'admin') !== false && !is_site_admin()) {
|
|
continue;
|
|
}
|
|
|
|
if ($widget_info['requires'] && strpos($widget_info['requires'], $module) === false) {
|
|
continue;
|
|
}
|
|
|
|
$ret[] = [
|
|
'type' => 'widget',
|
|
'name' => $widget_info['name'] ?? $name,
|
|
'desc' => $widget_info['description'] ?? '',
|
|
'src' => base64_encode('[widget=' . $name . '][/widget]')
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
usort($ret, fn($a, $b) => $a['name'] <=> $b['name']);
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function get_menus() {
|
|
$ret = [];
|
|
|
|
$r = q("select * from menu where menu_channel_id = %d and menu_flags = 0",
|
|
intval(local_channel())
|
|
);
|
|
|
|
foreach ($r as $rr) {
|
|
$name = $rr['menu_name'];
|
|
$desc = $rr['menu_desc'];
|
|
$ret[] = [
|
|
'type' => 'menu',
|
|
'name' => $name,
|
|
'desc' => $desc,
|
|
'src' => base64_encode('[menu]' . $name . '[/menu]')
|
|
];
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function get_blocks() {
|
|
$ret = [];
|
|
|
|
$r = q("select v, title, summary from item join iconfig on iconfig.iid = item.id and item.uid = %d
|
|
and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'",
|
|
intval(local_channel())
|
|
);
|
|
|
|
foreach ($r as $rr) {
|
|
$name = $rr['v'];
|
|
$desc = (($rr['title']) ? $rr['title'] : $rr['summary']);
|
|
$ret[] = [
|
|
'type' => 'block',
|
|
'name' => $name,
|
|
'desc' => $desc,
|
|
'src' => base64_encode('[block]' . $name . '[/block]')
|
|
];
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function get_template($pdl) {
|
|
$ret = 'default';
|
|
|
|
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl, $matches);
|
|
if($cnt && isset($matches[1])) {
|
|
$ret = trim($matches[1]);
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function get_regions($pdl) {
|
|
$ret = [];
|
|
$supported_regions = ['aside', 'content', 'right_aside'];
|
|
|
|
$cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $pdl, $matches, PREG_SET_ORDER);
|
|
if($cnt) {
|
|
foreach($matches as $mtch) {
|
|
if (!in_array($mtch[1], $supported_regions)) {
|
|
continue;
|
|
}
|
|
$ret[$mtch[1]] = self::parse_region($mtch[2]);
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function parse_region($pdl) {
|
|
$ret = [];
|
|
|
|
$cnt = preg_match_all('/\$content\b/ism', $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
|
if($cnt) {
|
|
foreach($matches as $mtch) {
|
|
$offset = intval($mtch[0][1]);
|
|
$name = trim($mtch[0][0]);
|
|
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
|
$src = base64_encode($mtch[0][0]);
|
|
$ret[$offset] = [
|
|
'type' => 'content',
|
|
'name' => t('Main page content'),
|
|
'desc' => t('The main page content can not be edited!'),
|
|
'src' => $src
|
|
];
|
|
}
|
|
}
|
|
|
|
$cnt = preg_match_all("/\[menu\](.*?)\[\/menu\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
|
if($cnt) {
|
|
foreach($matches as $mtch) {
|
|
$offset = intval($mtch[1][1]);
|
|
$name = trim($mtch[1][0]);
|
|
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
|
$src = base64_encode($mtch[0][0]);
|
|
|
|
$ret[$offset] = [
|
|
'type' => 'menu',
|
|
'name' => $name,
|
|
'desc' => '',
|
|
'src' => $src
|
|
];
|
|
}
|
|
}
|
|
|
|
// menu class e.g. [menu=horizontal]my_menu[/menu] or [menu=tabbed]my_menu[/menu]
|
|
// allows different menu renderings to be applied
|
|
|
|
//$cnt = preg_match_all("/\[menu=(.*?)\](.*?)\[\/menu\]/ism", $s, $matches, PREG_SET_ORDER);
|
|
//if($cnt) {
|
|
//foreach($matches as $mtch) {
|
|
//$s = str_replace($mtch[0],$this->menu(trim($mtch[2]),$mtch[1]),$s);
|
|
//}
|
|
//}
|
|
|
|
|
|
$cnt = preg_match_all("/\[block\](.*?)\[\/block\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
|
if($cnt) {
|
|
foreach($matches as $mtch) {
|
|
$offset = intval($mtch[1][1]);
|
|
$name = trim($mtch[1][0]);
|
|
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
|
$src = base64_encode($mtch[0][0]);
|
|
$ret[$offset] = [
|
|
'type' => 'block',
|
|
'name' => $name,
|
|
'desc' => '',
|
|
'src' => $src
|
|
];
|
|
}
|
|
}
|
|
|
|
//$cnt = preg_match_all("/\[block=(.*?)\](.*?)\[\/block\]/ism", $s, $matches, PREG_SET_ORDER);
|
|
//if($cnt) {
|
|
//foreach($matches as $mtch) {
|
|
//$s = str_replace($mtch[0],$this->block(trim($mtch[2]),trim($mtch[1])),$s);
|
|
//}
|
|
//}
|
|
|
|
//$cnt = preg_match_all("/\[js\](.*?)\[\/js\]/ism", $s, $matches, PREG_SET_ORDER);
|
|
//if($cnt) {
|
|
//foreach($matches as $mtch) {
|
|
//$s = str_replace($mtch[0],$this->js(trim($mtch[1])),$s);
|
|
//}
|
|
//}
|
|
|
|
//$cnt = preg_match_all("/\[css\](.*?)\[\/css\]/ism", $s, $matches, PREG_SET_ORDER);
|
|
//if($cnt) {
|
|
//foreach($matches as $mtch) {
|
|
//$s = str_replace($mtch[0],$this->css(trim($mtch[1])),$s);
|
|
//}
|
|
//}
|
|
|
|
// need to modify this to accept parameters
|
|
|
|
$cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
|
|
|
if($cnt) {
|
|
foreach($matches as $mtch) {
|
|
$offset = intval($mtch[1][1]);
|
|
$name = trim($mtch[1][0]);
|
|
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
|
$src = base64_encode($mtch[0][0]);
|
|
$ret[$offset] = [
|
|
'type' => 'widget',
|
|
'name' => $name,
|
|
'desc' => '',
|
|
'src' => $src
|
|
];
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Parse template comment in search of template info.
|
|
*
|
|
* like
|
|
* \code
|
|
* * Name: MyWidget
|
|
* * Description: A widget
|
|
* * Version: 1.2.3
|
|
* * Author: John <profile url>
|
|
* * Author: Jane <email>
|
|
* * ContentRegionID: some_id
|
|
* * ContentRegionID: some_other_id
|
|
* *
|
|
*\endcode
|
|
* @param string $template the name of the template
|
|
* @return array with the information
|
|
*/
|
|
function get_template_info($template){
|
|
$m = [];
|
|
$info = [
|
|
'name' => $template,
|
|
'description' => '',
|
|
'author' => [],
|
|
'maintainer' => [],
|
|
'version' => '',
|
|
'contentregion' => []
|
|
];
|
|
|
|
$checkpaths = [
|
|
'view/php/' . $template . '.php',
|
|
];
|
|
|
|
$template_found = false;
|
|
|
|
foreach ($checkpaths as $path) {
|
|
if (is_file($path)) {
|
|
$template_found = true;
|
|
$f = file_get_contents($path);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!($template_found && $f))
|
|
return $info;
|
|
|
|
$f = escape_tags($f);
|
|
$r = preg_match('|/\*.*\*/|msU', $f, $m);
|
|
|
|
if ($r) {
|
|
$ll = explode("\n", $m[0]);
|
|
foreach($ll as $l) {
|
|
$l = trim($l, "\t\n\r */");
|
|
if ($l != ''){
|
|
list($k, $v) = array_map('trim', explode(':', $l, 2));
|
|
$k = strtolower($k);
|
|
if (in_array($k, ['author', 'maintainer'])){
|
|
$r = preg_match('|([^<]+)<([^>]+)>|', $v, $m);
|
|
if ($r) {
|
|
$info[$k][] = array('name' => $m[1], 'link' => $m[2]);
|
|
} else {
|
|
$info[$k][] = array('name' => $v);
|
|
}
|
|
}
|
|
elseif (in_array($k, ['contentregion'])){
|
|
$info[$k][] = array_map('trim', explode(',', $v));
|
|
}
|
|
else {
|
|
$info[$k] = $v;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
function get_pdl($module) {
|
|
$ret = [
|
|
'pdl' => null,
|
|
'modified' => true
|
|
];
|
|
|
|
$pdl = 'mod_' . $module . '.pdl';
|
|
$pdl_path = '';
|
|
|
|
$ret['pdl'] = get_pconfig(local_channel(), 'system', $pdl);
|
|
|
|
if(!$ret['pdl']) {
|
|
$pdl_path = theme_include($pdl);
|
|
|
|
if (!$pdl_path) {
|
|
$addon_path = 'addon/' . $module . '/' . $pdl;
|
|
if (file_exists($addon_path)) {
|
|
$pdl_path = $addon_path;
|
|
}
|
|
}
|
|
|
|
if ($pdl_path) {
|
|
$ret['pdl'] = file_get_contents($pdl_path);
|
|
$ret['modified'] = false;
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
}
|