sqlite = $helper->getDB(); $this->loadPatterns(); } /** * Load existing assignment patterns */ protected function loadPatterns() { $sql = 'SELECT * FROM structpublish_assignments_patterns ORDER BY pattern'; $res = $this->sqlite->query($sql); $this->patterns = $this->sqlite->res2arr($res); $this->sqlite->res_close($res); } /** * Add a new assignment pattern to the pattern table * * @param string $pattern * @param string $user * @param string $status * @return bool */ public function addPattern($pattern, $user, $status) { // add the pattern $sql = 'REPLACE INTO structpublish_assignments_patterns (pattern, user, status) VALUES (?,?,?)'; $ok = (bool)$this->sqlite->query($sql, [$pattern, $user, $status]); // reload patterns $this->loadPatterns(); // update assignments // fetch known pages /** @var \helper_plugin_structpublish_db $dbHelper */ $dbHelper = plugin_load('helper', 'structpublish_db'); $pids = $dbHelper->getPages(); foreach ($pids as $pid) { $this->updatePageAssignments($pid); } return $ok; } /** * Remove an existing assignment pattern from the pattern table * * @param string $pattern * @param string $user * @param string $status * @return bool */ public function removePattern($pattern, $user, $status) { // remove the pattern $sql = 'DELETE FROM structpublish_assignments_patterns WHERE pattern = ? AND user = ? AND status = ?'; $ok = (bool)$this->sqlite->query($sql, [$pattern, $user, $status]); // reload patterns $this->loadPatterns(); // fetch possibly affected pages $sql = 'SELECT pid FROM structpublish_assignments WHERE user = ? AND status = ?'; $res = $this->sqlite->query($sql, [$user, $status]); $pagerows = $this->sqlite->res2arr($res); $this->sqlite->res_close($res); // reevalute the pages and unassign when needed foreach ($pagerows as $row) { $rules = $this->getPageAssignments($row['pid'], false); // remove assignments matching the rule foreach ($rules as $status => $users) { foreach ($users as $user) { $this->deassignPage($row['pid'], $user, $status); } } } return $ok; } /** * Updates all assignments of a given page against the current patterns * * @param string $pid */ public function updatePageAssignments($pid, $reload = false) { if ($reload) { $this->loadPatterns(); } $rules = $this->getPageAssignments($pid, true); foreach ($rules as $status => $users) { foreach ($users as $user) { $this->assignPage($pid, $user, $status); } } // FIXME reevalute existing assignments } /** * Clear all patterns - deassigns all pages * * This is mostly useful for testing and not used in the interface currently * * @param bool $full fully delete all previous assignments * @return bool */ public function clear($full = false) { $sql = 'DELETE FROM structpublish_assignments_patterns'; $ok = (bool)$this->sqlite->query($sql); if ($full) { $sql = 'DELETE FROM structpublish_assignments'; } else { $sql = 'UPDATE structpublish_assignments SET assigned = 0'; } $ok = $ok && (bool)$this->sqlite->query($sql); // reload patterns $this->loadPatterns(); return $ok; } /** * Add page to assignments * * @param string $page * @param string $user * @param string $status * @return bool */ public function assignPage($page, $user = null, $status = null) { $sql = 'REPLACE INTO structpublish_assignments (pid, user, status, assigned) VALUES (?, ?, ?, 1)'; return (bool)$this->sqlite->query($sql, [$page, $user, $status]); } /** * Remove page from assignments * * @param string $page * @param string $user * @return bool */ public function deassignPage($page, $user, $status) { $sql = 'REPLACE INTO structpublish_assignments (pid, user, status, assigned) VALUES (?, ?, ?, 0)'; return (bool)$this->sqlite->query($sql, [$page, $user, $status]); } /** * Get the whole pattern table * * @return array */ public function getAllPatterns() { return $this->patterns; } /** * Returns a list of user/group string lists per status assigned to the given page * * @param string $page * @param bool $checkpatterns Should the current patterns be re-evaluated? * @return array users assigned [role => [user, ...], ...] */ public function getPageAssignments($page, $checkpatterns = true) { $rules = []; $page = cleanID($page); if ($checkpatterns) { $helper = plugin_load('helper', 'structpublish_assignments'); // evaluate patterns $pns = ':' . getNS($page) . ':'; foreach ($this->patterns as $row) { if ($helper->matchPagePattern($row['pattern'], $page, $pns)) { $rules[$row['status']][] = $row['user']; } } } else { // just select $sql = 'SELECT user, status FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; $res = $this->sqlite->query($sql, [$page]); $list = $this->sqlite->res2arr($res); $this->sqlite->res_close($res); foreach ($list as $row) { $rules[$row['status']][] = $row['user']; } } return $rules; } /** * Get the pages known to struct and their assignment state * * @param bool $assignedonly limit results to currently assigned only * @return array */ public function getPages($assignedOnly = false) { $sql = 'SELECT pid, user, status, assigned FROM structpublish_assignments WHERE 1=1'; $opts = array(); if ($assignedOnly) { $sql .= ' AND assigned = 1'; } $sql .= ' ORDER BY pid, user, status'; $res = $this->sqlite->query($sql, $opts); $list = $this->sqlite->res2arr($res); $this->sqlite->res_close($res); $result = array(); foreach ($list as $row) { $pid = $row['pid']; $user = $row['user']; $status = $row['status']; if (!isset($result[$pid])) $result[$pid] = array(); $result[$pid][$user][$status] = (bool)$row['assigned']; } return $result; } }