/** * default action */ function action($item) { //! create a fake page parameter $name = "layoutadd"; $_SESSION['cms_param'][sha1("layoutadd_")] = new \PHPPE\AddOn\layoutadd([], $name, $name); //! if layout not given if (empty($item)) { //! check if we have to activate a sitebuild if (!empty($_REQUEST['set'])) { DS::exec("UPDATE " . Views::$_table . " SET id=sitebuild WHERE sitebuild!='' AND id='frame'"); DS::exec("UPDATE " . Views::$_table . " SET id='frame' WHERE sitebuild=?", trim($_REQUEST['set'])); Http::redirect(); } //! load layouts and sitebuilds $this->layouts = Views::find([], "sitebuild=''", "name"); $this->sitebuilds = Views::find([], "sitebuild!=''", "name"); } else { //! load layout $this->layout = new Views($item); if (!empty($this->layout->jslib)) { foreach ($this->layout->jslib as $j) { View::jslib($j); } } if (!empty($this->layout->css)) { foreach ($this->layout->css as $c) { View::css($c); } } $this->numPages = Page::getNum($item); //! get user input $layout = Core::req2arr("layout"); //! merge the new data with the loaded layout's properties if (!empty($this->layout->sitebuild) && !empty($layout)) { Core::$core->noframe = 1; $layout['sitebuild'] = $layout['id']; } if (Core::isTry("layout")) { //! delete a layout if (!empty($layout['delete'])) { $this->layout->delete(); } else { unset($layout['delete']); //! renamed? if ($this->layout->id != $layout['id']) { DS::exec("UPDATE " . Views::$_table . " SET id=? WHERE id=?", [$layout['id'], $this->layout->id]); Core::log('A', sprintf("Layout %s renamed to %s by %s", $this->layout->id, $layout['id'], Core::$user->name), "cmsaudit"); } //! save new data foreach ($layout as $k => $v) { $this->layout->{$k} = $v; } $this->layout->save(); } Http::redirect("cms/layouts"); } } }
/** * content chooser, loaded via AJAX */ function action($item) { $list = Page::getPages(true); echo "<input type='text' style='width:98%;' placeholder='" . L("Search") . "' onkeyup='pe.wyswyg.search(this,this.nextSibling);'>"; echo "<div class='wyswyg_content wyswyg_scroll'>\n"; foreach ($list as $content) { echo "<a href='/" . ($content['id'] == "index" ? "" : $content['id']) . "'>" . $content['name'] . "</a>\n"; } die("</div>"); }
/** * default action */ function action($item) { //! page history enabled? $this->revert = Core::lib("CMS")->revert; //! delete a page with all versions if (!empty($_REQUEST['pagedel'])) { Page::delete($_REQUEST['pagedel']); unset($_SESSION['cms_url']); Http::redirect(); } //! publicate a page if (isset($_REQUEST['publish']) && $this->revert) { $this->ispublish = true; $publish = array_keys(Core::req2arr('publish')); if (!empty($publish)) { Page::publish($publish); Http::redirect("cms/pages"); } } //! load languages $this->langs[''] = "*"; foreach (!empty($_SESSION['pe_ls']) ? $_SESSION['pe_ls'] : ['en' => 1] as $l => $v) { $this->langs[$l] = $l . " " . L($l); } //! unlock old pages for this user if any Page::unLock(Core::$user->id); //! get list of pages $pages = Page::getPages(intval(@$_REQUEST['order'])); $needcleanup = false; foreach ($pages as $p) { if ($this->ispublish && ($p['publishid'] != 0 || $p['ownerid'] != 0)) { continue; } if ($this->revert && $p['publishid'] == 0) { $this->needpublish = true; } if (!$this->revert && $p['versions'] > 1) { $needcleanup = true; } $this->pages[empty($_REQUEST['order']) ? 0 : (empty($p['template']) ? $p['tid'] : $p['template'])][] = $p; } //! this is required once after page history turned off if ($needcleanup) { Page::cleanUp($pages); } }
function save($params) { Page::saveDDS("frame", $params['gdds']); return Page::saveDDS($params['pageid'], $params['dds']); }
/** * default action, loaded via AJAX */ function action($item) { //! called via AJAX, no output required Page::unLock(Core::$user->id); die("<script>top.document.location.href='" . url("cms/pages") . "';</script>"); }
/** * default action */ function action($item) { //! omit frame and panel and disable cache Core::$core->noframe = true; Core::$core->nopanel = true; Core::$core->nocache = true; //! if not called as it should, return if (empty($item) || $item != sha1("pageadd_") && (empty($_SESSION['cms_url']) || empty($_SESSION['cms_param'][$item]))) { Core::$core->template = "403"; return; } //! get height $this->height = intval(@$_REQUEST['height']); $this->adjust = intval(@$_REQUEST['adjust']); //! save current scroll position to session so that on next //! page load pe.cms.init() will use it if (isset($_REQUEST['scrx'])) { $_SESSION['cms_scroll'] = [$_REQUEST['scrx'], $_REQUEST['scry']]; } //! get available access control entries $this->ace = ClassMap::ace(); foreach ($this->ace as $k => $v) { $this->ace[$k] = "@" . $v; } $this->ace[] = "@siteadm|webadm"; $this->ace[] = "loggedin"; $this->ace[] = "csrf"; $this->ace[] = "get"; $this->ace[] = "post"; //! get the field we're editing $F = clone $_SESSION["cms_param"][$item]; $F->fld = "page_value"; if (get_class($F) == "PHPPE\\AddOn\\wyswyg") { $F->args = [0, "pe.cms.image"]; } if (method_exists($F, 'init')) { $F->init(); } $this->fieldTitle = $F->name; $this->heightClass = @$F->heightClass; $this->boxHeight = $this->height - @$F->headerHeight; //! get the page we're editing //! if parameter name starts with "frame", load frame page instead $page = new Page(substr($F->name, 0, 6) == "frame." ? "frame" : @$_SESSION['cms_url']); $this->editable = $page->lock(); View::assign("page", $page); $n = substr($F->name, 0, 6) == "frame." ? substr($F->name, 6) : (substr($F->name, 0, 4) == "app." ? substr($F->name, 4) : $F->name); if (!empty($page->data[$n])) { $F->value = $page->data[$n]; } //! load extra data if any if (method_exists($F, 'load')) { $F->load($this); } //! save page parameter $param = Core::req2arr("page"); if (!empty($param) && $this->editable) { //! if there was no validation error if (!Core::isError()) { if (method_exists($F, "save")) { //! if it's a special field with it's own save mechanism $param['pageid'] = $page->id; if (!$F->save($param)) { Core::error(L("Unable to save page!")); } } else { //! otherwise standard page parameter $page->setParameter($F->name, $param['value']); if (!$page->save()) { Core::error(L("Unable to save page!")); } } //! close the modal if save was successful if (!Core::isError()) { //! release the page lock $page->release(); die("<html><script>parent.pe.cms.close(true);</script></html>"); } } //! copy the form data. normally you don't need to do that //! but here form name and object name differs, so it's not automatic foreach ($param as $k => $v) { $page->{$k} = $v; } } //! get the input(s) if (method_exists($F, 'edit')) { $this->field = $F->edit(); } else { //! fallback to a simple input field. Should never happen $this->field = "<input type='text' class='input" . (Core::isError("page.value") ? " errinput" : "") . "' name='page_value' value=\"" . htmlspecialchars($F->value) . "\">"; } //! focus first input View::js("init()", "var inp=document.querySelector('.reqinput,.input');if(inp!=null){inp.focus();inp.selectionStart=inp.selectionEnd=(inp.value!=null?inp.value:inp.innerHTML).length;}", true); }
/** * default action, loaded via AJAX */ function action($item) { //! available tags $list = ["/form" => "*variable [url [onsubmitjs", "/if" => "*expression", "else" => "*", "/foreach" => "*dataset", "/template" => "*", "include" => "*view", "app" => "*", "dump" => "variable", "cms" => "*addon ) variable", "=" => "expression", "L" => "label", "date" => "expression", "time" => "expression", "difftime" => "expression", "var" => "*addon ) variable", "field" => "*addon ) variable", "widget" => "*addon ) variable"]; //! Add-Ons $d = array_merge(get_declared_classes(), array_keys(ClassMap::$map)); foreach ($d as $c) { if (strtolower(substr($c, 0, 12)) == "phppe\\addon\\") { $F = new $c([], "dummy", $c, []); if (isset($F->conf) && $F->conf != "*") { $list["_" . strtolower(substr($c, 12))] = $F->conf; } unset($F); } } if (!empty($item)) { //! edit form $acl = $widget = ""; $req = $needsel = 0; if (substr($item, 0, 2) != "<!") { die(View::e("E", L("Unknown tag"))); } else { $d = ""; $c = ""; foreach ($list as $k => $v) { if ($k[0] == "_") { continue; } if (substr($item, 2, strlen($k)) == $k || "/" . substr($item, 2, strlen($k) - 1) == $k) { $d = $k[0] == "/" ? substr($k, 1) : $k; $c = $v[0] == '*' ? substr($v, 1) : $v; } } if (empty($d)) { die(View::e("E", L("Unknown tag"))); } if ($d == "=") { $d = "eval"; $a = [substr($item, 3, strlen($item) - 4)]; } else { $a = str_getcsv(preg_replace("/[\\ ]+/", " ", strtr(substr($item, 2, strlen($item) - 3), ["(," => " - ", "(" => " ", ")" => " )", ",," => " - ", "," => " "])), " "); array_shift($a); } if (substr($c, 0, 5) == "addon") { if (@$a[0][0] == "@") { $acl = substr($a[0], 1); array_shift($a); } if (@$a[0][0] == "*") { $req = 1; $a[0] = substr($a[0], 1); } $widget = array_shift($a); if (empty($widget)) { $widget = "hidden"; } $needsel = 1; } echo "<b>" . L(!empty($widget) && !empty(Core::$l[$widget]) ? $widget : "help_" . $d) . "</b><br/>\n<div id='tageditor' style='padding:5px;'><input type='hidden' name='tag' value='" . htmlspecialchars($d) . "'>\n"; if (substr($c, 0, 5) == "addon") { $t = $d == "cms" ? L("Show value") : L("Required value"); echo "<input type='checkbox' class='input' name='required' onchange='pe.cms.settag(\"tageditor\");' title=\"" . htmlspecialchars($t) . "\" value='*'" . ($req ? " checked" : "") . ">\n"; echo "<select class='input' name='widget' onchange='pe.cms.settag(\"tageditor\");pe.wyswyg.popup(event,\"layout_data\",\"cms/tag?item=" . urlencode("<!" . $d . " " . ($req ? "*" : "")) . "\"+this.value+\">\",true);' onmouseover='pe_w();'>"; foreach ($list as $k => $v) { if ($k[0] != "_") { continue; } echo "<option value='" . htmlspecialchars(substr($k, 1)) . "'" . (substr($k, 1) == $widget ? " selected" : "") . " onmouseover='pe_w();'>" . L(substr($k, 1)) . "</option>\n"; } echo "</select>\n<input type='text' class='input smallinput' name='acl' onkeydown='if(event.key==\"Enter\"){event.preventDefault();pe_p();}' onkeyup='pe.cms.settag(\"tageditor\");event.preventDefault();' onchange='pe.cms.settag(\"tageditor\");' title=\"" . L("Access filters") . "\" placeholder=\"" . L("Access filters") . "\" value=\"" . htmlspecialchars($acl) . "\" list='filters'>"; echo "<datalist id='filters'>"; foreach (ClassMap::ace() as $b) { echo "<option value='" . $b . "'>" . L($b) . "</option>"; } echo "<option value='siteadm|webadm'>" . L("Administrator") . "</option>"; echo "</datalist><br/>\n"; $c = @$list["_" . $widget]; } if (empty($c) || @$item[2] == "/") { die(L("Not configurable")); } if ($c[0] == "*") { $c = substr($c, 1); } $c = str_getcsv(preg_replace("/[\\ ]+/", " ", strtr($c, ["(" => "( ", ")" => " ) ", "[" => " [ ", "]" => "", "," => " "])), " "); if (in_array(")", $c)) { if (!in_array(")", $a)) { array_unshift($a, ")"); } array_shift($c); } if ($c[0] != ")" && in_array(")", $a)) { echo "(<input type='hidden' value='('><br/><div style='padding-left:10px;'>"; } elseif ($c[0] == ")") { array_shift($c); } $i = 0; $optional = ""; $f = 1; $js = 0; foreach ($c as $k => $v) { if ($v == "[") { $optional = " optional"; continue; } if ($v == ")") { echo "</div>)<input type='hidden' value=')'><br/>\n"; while ($a[$i] != ")" && !empty($a[$i])) { $i++; } $i++; $optional = ""; continue; } if (empty($optional) && $f) { $optional = " focus"; $f = 0; } switch ($v) { case "": $i++; break; case "view": $views = Views::find([], "sitebuild=''", "id", "id,name"); foreach (array_merge(glob("app/views/*.tpl"), glob("vendor/phppe/Core/views/*.tpl")) as $view) { $w = str_replace(".tpl", "", basename($view)); if ($w != "frame") { $views[] = ['id' => $w, 'name' => ucfirst($w)]; } } if ($a[$i] == ")") { $i--; } echo "<select class='input" . $optional . "' name='arg" . $k . "' data-type='" . htmlspecialchars($v) . "' " . "onchange='pe.cms.settag(\"tageditor\");' title=\"" . L($v) . "\">"; $w = 0; foreach ($views as $view) { echo "<option value='" . htmlspecialchars($view['id']) . "'" . ($view['id'] == $a[$i] ? " selected" : "") . ">" . L($view['name'] ? $view['name'] : $view['id']) . "</option>"; if ($view['id'] == $a[$i]) { $w = 1; } } if (!$w) { echo "<option value='" . htmlspecialchars($a[$i]) . "' selected>" . (!empty($a[$i]) ? L($a[$i]) : "*") . "</option>"; } echo "</select>\n"; $i++; break; case "min": case "max": case "maxlen": case "rows": case "size": case "picturesize": case "iconheight": case "iconwidth": case "itemheight": case "itemwidth": case "num": echo "<input type='number' class='input" . $optional . "' name='arg" . $k . "' data-type='" . htmlspecialchars($v) . "' " . "onkeyup='pe.cms.settag(\"tageditor\");' onkeydown='if(event.key==\"Enter\"){event.preventDefault();pe_p();}' onchange='pe.cms.settag(\"tageditor\");' title=\"" . L($v) . "\" placeholder=\"" . L($v) . "\" " . "value=\"" . htmlspecialchars(@$a[$i] == ")" ? "" : @$a[$i++]) . "\"><br/>\n"; break; default: echo "<input type='text' class='input" . $optional . "' name='arg" . $k . "' data-type='" . htmlspecialchars($v) . "' " . "onkeyup='pe.cms.settag(\"tageditor\");' onkeydown='if(event.key==\"Enter\"){event.preventDefault();pe_p();}' onchange='pe.cms.settag(\"tageditor\");' title=\"" . L($v) . "\" placeholder=\"" . L($v) . "\" " . "value=\"" . htmlspecialchars(@$a[$i] == ")" ? "" : @$a[$i++]) . "\"" . ($v == "label" || $v == "cssclass" || $v == "dataset" || $v == "listopts" ? " list=\"" . ($v == "listopts" ? "dataset" : $v) . "s\"" : (substr($v, -2) == "js" ? " list='jss'" : "")) . "><br/>\n"; if (substr($v, -2) == "js" && $js == 0) { //! filled in by JavaScript echo "<datalist id=\"jss\"></datalist>\n"; $js = 1; } if ($v == "label" || $v == "cssclass") { //! filled in by JavaScript echo "<datalist id=\"" . $v . "s\"></datalist>\n"; } if ($v == "dataset" || $v == "listopts") { echo "<datalist id=\"datasets\">\n"; $pages = Page::find([], "", "created DESC", "dds", "id"); $dds = []; foreach ($pages as $p) { $g = @json_decode(@$p['dds'], true); if (!empty($g) && is_array($g)) { foreach ($g as $G => $w) { $dds[$G] = $G; } } } ksort($dds); foreach ($dds as $G) { echo "<option value=\"" . htmlspecialchars($G) . "\">" . L($G) . "</option>"; } echo "</datalist>\n"; } } if ($optional == "focus") { $optional = ""; } } } die("</div>\n<small>" . L(!empty(Core::$l['_' . $d]) ? '_' . $d : "") . "</small>"); } else { // tag chooser $onlywidget = strpos($_SERVER['HTTP_REFERER'], "/cms/layouts/") === false; echo "<input type='text' style='width:98%;' placeholder='" . L("Search") . "' onkeyup='pe.wyswyg.search(this,this.nextSibling);'>"; echo "<div class='wyswyg_tag wyswyg_scroll'>\n"; foreach ($list as $tag => $cfg) { if ($cfg[0] == '*' && $onlywidget) { continue; } if (substr($tag, 0, 1) == "_") { $tag = ($onlywidget ? "widget" : "field") . " " . substr($tag, 1); } else { if (substr($tag, 0, 1) == "/") { echo "<img class='wyswyg_icon' src='js/wyswyg.js.php?item=" . urlencode("<!" . substr($tag, 1) . ">") . "' alt=\"" . strtr("<!" . substr($tag, 1) . ">", ["<" => "<", ">" => ">", "\"" => """]) . "\">\n"; } } echo "<img class='wyswyg_icon' src='js/wyswyg.js.php?item=" . urlencode("<!" . $tag . ">") . "' alt=\"" . strtr("<!" . $tag . ">", ["<" => "<", ">" => ">", "\"" => """]) . "\">\n"; } die("</div>"); } }
function save($params) { //! save page as new return Page::savePageInfo($params, true); }
function save($params) { return Page::savePageList($this->name, str_getcsv($params['value'], ',')); }
/** * default action */ function action($item) { //! check access rights if (!Core::$user->has("siteadm|webadm")) { Http::redirect("403"); } //! if we have to delete a page version if (isset($_REQUEST['pagedel'])) { if (!empty($_REQUEST['created'])) { Page::delete($item, $_REQUEST['created']); } Http::redirect($item); } //! revert to an old version of the page if (isset($_REQUEST['revert'])) { if (!empty($_REQUEST['created'])) { Core::log('A', sprintf("Page %s reverted to %s by %s", $item, $_REQUEST['created'], Core::$user->name), "cmsaudit"); DS::exec("UPDATE pages set created=CURRENT_TIMESTAMP,modifyd=CURRENT_TIMESTAMP,modifyid=? WHERE id=? AND (lang='' OR lang=?) AND created=?", [Core::$user->id, $item, Core::$client->lang, $_REQUEST['created']]); } Http::redirect($item); } //! get the latest public version's date if (empty($_REQUEST['created'])) { $_REQUEST['created'] = DS::field("created", "pages", "(id=? OR ? LIKE id||'/%') AND (lang='' OR lang=?) AND publishid!=0", "", "id DESC,created DESC", [$item, $item, Core::$client->lang]); if (empty($_REQUEST['created'])) { $_REQUEST['created'] = DS::field("created", "pages", "(id=? OR ? LIKE id||'/%') AND (lang='' OR lang=?)", "", "id DESC,created ASC", [$item, $item, Core::$client->lang]); } } //! load frame page for page parameters and dds $frame = DS::fetch("data,dds", "pages", "id='frame' AND (lang='' OR lang=?) AND created<=?", "", "", [Core::$client->lang, $_REQUEST['created']]); $frame['dss'] = @json_decode($frame['dds'], true); $frame['data'] = @json_decode($frame['data'], true); View::assign("frame", $frame['data']); //! load archive version //! normally you would use Model, but that would only return the latest version $page = DS::fetch("*", "pages", "(id=? OR ? LIKE id||'/%') AND (lang='' OR lang=?) AND created=?", "", "id DESC,created DESC", [$item, $item, Core::$client->lang, $_REQUEST['created']]); $this->title = $page['name']; $title = L("ARCHIVE") . " " . $page['name']; if (is_string($page['data'])) { $page['data'] = @json_decode($page['data'], true); } if (is_array($page['data'])) { foreach ($page['data'] as $k => $v) { $this->{$k} = $v; } } foreach (["id", "name", "lang", "filter", "template", "pubd", "expd", "dds", "ownerid", "created"] as $k) { $this->{$k} = $page[$k]; } $p = @array_merge($frame['dds'], @json_decode($page['dds'], true)); if (is_array($p)) { foreach ($p as $k => $c) { if ($k != "dds") { try { $this->{$k} = DS::query($c[0], $c[1], @$c[2], @$c[3], @$c[4], @$c[5], View::getval(@$c[6])); } catch (\Exception $e) { Core::log("E", $item . " " . $e->getMessage() . " " . implode(" ", $c), "dds"); } } } } $old = View::template($this->template); //! if we have to compare to an older (or the latest) version if (isset($_REQUEST['diff'])) { include_once "vendor/phppe/CMS/libs/simplediff.php"; //! load current version $frame = DS::fetch("data,dds", "pages", "id='frame' AND (lang='' OR lang=?) AND publishid!=0", "", "created DESC", [Core::$client->lang]); $frame['dss'] = @json_decode($frame['dds'], true); $frame['data'] = @json_decode($frame['data'], true); View::assign("frame", $frame['data']); $page = DS::fetch("*", "pages", "id=? OR ? LIKE id||'/%'", "", "id DESC,created DESC", [$item, $item]); if (is_string($page['data'])) { $page['data'] = @json_decode($page['data'], true); } if (is_array($page['data'])) { foreach ($page['data'] as $k => $v) { $this->{$k} = $v; } } foreach (["id", "name", "lang", "filter", "template", "pubd", "expd", "dds", "ownerid", "created"] as $k) { $this->{$k} = $page[$k]; } $p = @array_merge($frame['dds'], @json_decode($page['dds'], true)); if (is_array($p)) { foreach ($p as $k => $c) { if ($k != "dds") { try { $this->{$k} = DS::query($c[0], $c[1], @$c[2], @$c[3], @$c[4], @$c[5], View::getval(@$c[6])); } catch (\Exception $e) { Core::log("E", $item . " " . $e->getMessage() . " " . implode(" ", $c), "dds"); } } } } $this->title = $page['name']; $curr = View::template($this->template); //! make sure diff splits on tag end $this->result = htmlDiff(preg_replace("/>([^\\ \t\n])/m", "> \\1", $old), preg_replace("/>([^\\ \t\n])/m", "> \\1", $curr)); //! remove diff inside tags $this->result = preg_replace("/(<[^<>]+)<ins>.*?<\\/ins>([^<>]*>)/ims", "\\1\\2", $this->result); $this->result = preg_replace("/(<[^<>]+)<del>(.*?)<\\/del>([^<>]*>)/ims", "\\1\\2\\3", $this->result); } else { $this->result = $old; } $this->title = $title; }