public function testDataSource() { \PHPPE\DS::close(); $wasExc = false; try { $val = \PHPPE\DS::field("1+1"); } catch (\Exception $e) { $wasExc = true; } $this->assertTrue($wasExc, "No DS exception"); $ds = new \PHPPE\DS("sqlite::memory:"); $this->assertEquals("%a%", \PHPPE\DS::like("a"), "like #1"); $this->assertEquals("%a%b%", \PHPPE\DS::like("a b"), "like #2"); $this->assertEquals("%a%b%", \PHPPE\DS::like("a' \"b?"), "like #3"); \PHPPE\DS::db()->s = ["describe" => ".schema"]; $this->assertInstanceOf("PDO", \PHPPE\DS::db(), "PDO object"); $this->assertEquals(2, \PHPPE\DS::field("1+1"), "field"); $wasExc = false; try { $val = \PHPPE\DS::query("*", "nosuchtable"); } catch (\Exception $e) { $wasExc = true; } $this->assertTrue($wasExc, "No scheme exception"); $wasExc = false; try { $val = \PHPPE\DS::query("*", "badtable"); } catch (\Exception $e) { $wasExc = true; } $this->assertTrue($wasExc, "Bad scheme exception"); $this->assertEquals('a:4:{i:0;a:3:{s:2:"id";s:1:"1";s:4:"name";s:5:"first";s:8:"parentId";s:1:"0";}i:1;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}i:2;a:3:{s:2:"id";s:1:"3";s:4:"name";s:5:"third";s:8:"parentId";s:1:"1";}i:3;a:3:{s:2:"id";s:1:"4";s:4:"name";s:6:"fourth";s:8:"parentId";s:1:"0";}}', serialize(\PHPPE\DS::query("*", "test")), "scheme install"); $this->assertEquals(1, \PHPPE\DS::exec("-- sql comment"), "exec comment"); $this->assertEquals(1, \PHPPE\DS::exec("insert into test values (5,'fifth',0)"), "exec insert"); $this->assertEquals(1, \PHPPE\DS::exec("update test set parentId=1 where id=?", 5), "exec update unnamed"); $this->assertEquals(1, \PHPPE\DS::query("parentId", "test", "id=5")[0]["parentId"], "exec parentIdcheck"); $this->assertEquals(1, \PHPPE\DS::exec("update test set parentId=:newparent where id=:id", [":id" => 5, ":newparent" => 2]), "exec update named"); $this->assertEquals(2, \PHPPE\DS::query("parentId", "test", "id=5")[0]["parentId"], "exec parentIdcheck"); $this->assertEquals(0, \PHPPE\DS::exec("update test set parentId=:newparent where id=:id", [":id" => 6, ":newparent" => 2]), "exec update no match"); $this->assertInternalType("integer", \PHPPE\DS::exec("update test set parentId=1 where id=?", 5), "insert returns"); $this->assertInternalType("array", \PHPPE\DS::exec("select * from test"), "select returns"); $this->assertEquals('a:2:{i:0;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}i:1;a:3:{s:2:"id";s:1:"5";s:4:"name";s:5:"fifth";s:8:"parentId";s:1:"1";}}', serialize(\PHPPE\DS::query("*", "test", "id!=4", "parentId")), "query group by"); $this->assertEquals('a:2:{i:0;a:3:{s:2:"id";s:1:"5";s:4:"name";s:5:"fifth";s:8:"parentId";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}}', serialize(\PHPPE\DS::query("*", "test", "id!=4", "parentId", "id desc")), "query order by"); $this->assertEquals('a:2:{i:0;a:3:{s:2:"id";s:1:"5";s:4:"name";s:5:"fifth";s:8:"parentId";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}}', serialize(\PHPPE\DS::query("*", "test", "id!=4", "parentId", "id desc", 1)), "query offset"); $this->assertEquals('a:1:{i:0;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}}', serialize(\PHPPE\DS::query("*", "test", "id!=4", "parentId", "id desc", 1, 1)), "query limit"); $this->assertEquals('a:0:{}', serialize(\PHPPE\DS::query("*", "test", "id=11")), "query empty"); $this->assertEquals('a:2:{s:4:"name";s:5:"third";s:8:"parentId";s:1:"1";}', serialize(\PHPPE\DS::fetch("name,parentId", "test", "id=?", "", "", [3])), "fetch record"); $this->assertEquals('a:0:{}', serialize(\PHPPE\DS::fetch("*", "test", "id=11")), "fetch empty"); $this->assertEquals('a:3:{i:0;a:4:{s:2:"id";s:1:"1";s:4:"name";s:5:"first";s:8:"parentId";s:1:"0";s:1:"_";a:2:{i:0;a:3:{s:2:"id";s:1:"3";s:4:"name";s:5:"third";s:8:"parentId";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"5";s:4:"name";s:5:"fifth";s:8:"parentId";s:1:"1";}}}i:1;a:3:{s:2:"id";s:1:"2";s:4:"name";s:6:"second";s:8:"parentId";s:1:"0";}i:2;a:3:{s:2:"id";s:1:"4";s:4:"name";s:6:"fourth";s:8:"parentId";s:1:"0";}}', serialize(\PHPPE\DS::tree("select * from test where parentId=:id")), "tree all"); $this->assertEquals('a:2:{i:0;a:3:{s:2:"id";s:1:"3";s:4:"name";s:5:"third";s:8:"parentId";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"5";s:4:"name";s:5:"fifth";s:8:"parentId";s:1:"1";}}', serialize(\PHPPE\DS::tree("select * from test where parentId=:id", 1)), "tree sub-tree"); $this->assertEquals('a:0:{}', serialize(\PHPPE\DS::tree("select * from test where parentId=:id", 3)), "tree empty"); $wasExc = false; try { $val = \PHPPE\DS::query("nocolumn", "test"); } catch (\Exception $e) { $wasExc = true; } $this->assertTrue($wasExc, "PDO exception"); $wasExc = false; try { $val = \PHPPE\DS::db("nodrv:"); } catch (\Exception $e) { $wasExc = true; } $this->assertTrue($wasExc, "No driver exception"); $this->assertGreaterThan(0, \PHPPE\DS::bill(), "Billed secs"); }
/** * Action handler */ function action($item) { setlocale(LC_NUMERIC, "C"); $lib = Core::lib("ClusterSrv"); $nodes = DS::query("*", self::$_table, "", "", "type,load DESC,id"); $master = DS::field("id", self::$_table, "type='master' AND modifyd>CURRENT_TIMESTAMP-120"); //! check if executed from CLI if (Core::$client->ip != "CLI") { header("Content-type:application/json"); $loadavg = 0.0; $waspeek = 0; $minSync = ""; if (!empty($nodes)) { $minSync = reset($nodes)['syncd']; foreach ($nodes as $k => $node) { unset($nodes[$k]["cmd"]); $loadavg += floatval($node['load']); if ($node['load'] >= 0.5) { $waspeek = 1; } if ($node['load'] >= 0.75) { $waspeek = 2; } if ($node['syncd'] < $minSync) { $minSync = $node['syncd']; } } $loadavg /= count($nodes); } date_default_timezone_set('UTC'); $minSync = strtotime($minSync); $D = []; $d = $lib->_skeleton; if (substr($d, -1) != "/") { $d .= "/"; } foreach (['vendor/*', 'vendor/*/*', 'vendor/*/*/*', 'vendor/*/*/*/*', 'vendor/*/*/*/*/*'] as $v) { $D += array_fill_keys(@glob($d . $v, GLOB_NOSORT), 0); } $newfiles = 0; foreach ($D as $d => $v) { $t = filemtime($d); if ($t != 0 && $t > $minSync) { $newfiles = 1; break; } } die(json_encode(["status" => $loadavg < 0.1 ? "idle" : ($loadavg > 0.5 || $waspeek ? $loadavg > 0.75 || $waspeek == 2 ? "error" : "warn" : "ok"), "loadavg" => $loadavg, "peek" => $waspeek, "master" => $master, "newfiles" => $newfiles, "id" => Core::lib("ClusterSrv")->id, "nodes" => $nodes])); } else { echo chr(27) . "[96mThis node is: " . chr(27) . "[0m" . $lib->id . " " . chr(27) . "[" . (strtolower(trim($lib->id)) == strtolower(trim($master)) ? "91mMASTER" : "92mSLAVE") . chr(27) . "[0m\n" . chr(27) . "[96mCluster nodes:\n"; echo chr(27) . "[96m Id Type Load Last seen Last viewed Name\n -------------- --------- ----- ------------------- ------------------- -----------------------------" . chr(27) . "[0m\n"; foreach ($nodes as $node) { echo sprintf("%s%-16s%-8s%8s", strtolower(trim($node['id'])) == strtolower(trim($master)) ? chr(27) . "[93m*" : " ", $node['id'], $node['type'], $node['load']) . " " . (!empty($node['modifyd']) ? $node['modifyd'] : sprintf("%-19s", L("booting"))) . " " . (!empty($node['viewd']) ? $node['viewd'] : "????-??-?? ??:??:??") . " " . $node['name'] . chr(27) . "[0m\n"; } echo "\n"; if (Core::$core->action == "action") { $this->help(); } } }
function load(&$app) { $app->versions = DS::query("a.*,b.name as moduser,c.name as pubuser, CURRENT_TIMESTAMP as ct", "pages a left join users b on a.modifyid=b.id left join users c on a.publishid=c.id", "a.id=? AND (a.lang='' OR a.lang=?)", "", "a.created DESC", 0, 0, [$_SESSION['cms_url'], Core::$client->lang]); }
/** * 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; }