function edit_parse($action, &$data) { if ($action != CONS_ACTION_DELETE) { // tests code and page if (isset($data['code']) && $data['code'] == "") { $data['code'] = 1; } if (isset($data['page'])) { $folders = explode("/", $data['page']); $data['page'] = array(); foreach ($folders as $f) { $data['page'][] = removeSimbols($f, true, false); } $data['page'] = implode("/", $data['page']); if ($data['page'][0] != "/") { $data['page'] = "/" . $data['page']; } } if (!isset($data['lang'])) { $data['lang'] = CONS_DEFAULT_LANG; } // checks if there is some non-unique item with keys code,page,lang (old version used these as keys, but changed to simplify parenting) if (isset($data['code']) && isset($data['lang']) && isset($data['page'])) { $cm = $this->parent->loaded($this->moduleRelation); $sql = "SELECT count(*) FROM " . $cm->dbname . " WHERE code='" . $data['code'] . "' AND page='" . $data['page'] . "' AND lang='" . $data['lang'] . "'" . ($action == CONS_ACTION_INCLUDE ? "" : " AND id<>'" . $data['id'] . "'"); if ($this->parent->dbo->fetch($sql) > 0) { $this->parent->errorControl->raise(520, $data['page'], $this->moduleRelation, $this->parent->langOut('cms_repeated_keys') . " " . $data['code'] . "," . $data['lang']); return false; } } } else { if ($_SESSION[CONS_SESSION_ACCESS_LEVEL] < 100) { // cannot DELETE an item marked as LOCKED $cm = $this->parent->loaded($this->moduleRelation); $sql = "SELECT locked FROM " . $cm->dbname . " WHERE id=" . $data['id']; $l = $this->parent->dbo->fetch($sql); if ($l == 'y') { $this->parent->errorControl->raise(521, $data['id'], $this->moduleRelation); return false; } } } return true; }
function runAction($action, $data, $silent = false, $mfo = false, $startedAt = "") { # mfo is "Mandatory Fields Ok", which removes the need to check them # returns TRUE or FALSE # check for auto_increment during insert on $parent->lastReturnCode if (is_object($action)) { $this->parent->errorControl->raise(126); } $this->parent->lastReturnCode = 0; unset($this->parent->storage['lastactiondata']); if (is_numeric($data)) { if ($action == CONS_ACTION_DELETE) { $id = $data; $data = array(); $data[$this->keys[0]] = $id; } else { if (!$silent) { $this->parent->errorControl->raise(187, $data, $this->name); } return false; } } if (count($this->plugins) > 0 && ($action == CONS_ACTION_UPDATE || $action == CONS_ACTION_INCLUDE || $action == CONS_ACTION_DELETE)) { foreach ($this->plugins as $pname) { if (!$this->parent->loadedPlugins[$pname]->edit_parse($action, $data)) { if (!$silent) { $this->parent->errorControl->raise(168, $pname, $this->name); } return false; } } } if (!$mfo) { $missing = $this->check_mandatory($data, $action); # returns a list of mandatory fields missing or invalid if (count($missing) > 0) { $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(127, implode(",", $missing), $this->name); } return false; } } $EnumPrunecache = array(); switch ($action) { case CONS_ACTION_UPDATE: ###################################################### UPDATE ############################################ $wS = ""; # whereStruct $kA = array(); # keyArray $haveAllKeys = $this->getKeys($wS, $kA, $data); // is it ok not to have all keys? # security if ($this->parent->safety && $_SESSION[CONS_SESSION_ACCESS_LEVEL] < 100) { $Owner = $this->parent->authControl->checkOwner($this, $kA); // array with isOwner and isSameGroup $this->parent->lockPermissions(); # Load permissions to this, in case something changed if (!$this->parent->authControl->checkPermission($this, CONS_ACTION_UPDATE, $Owner, $data)) { $this->parent->errorControl->raise(151, '', $this->name); return false; } } $this->parent->notifyEvent($this, CONS_ACTION_UPDATE, $data, $startedAt, true); # early notify $sql = "UPDATE " . $this->dbname . " SET "; $output = ""; $outfield = false; foreach ($this->fields as $name => $field) { if ($this->parent->safety && isset($field[CONS_XML_RESTRICT]) && $_SESSION[CONS_SESSION_ACCESS_LEVEL] < $field[CONS_XML_RESTRICT] && !isset($field[CONS_XML_UPDATESTAMP])) { # safety is on and this is a restricted field, while the user trying to change it does not have enough level if (isset($data[$name])) { $this->parent->errorControl->raise(145, $name, $this->name); } continue; } if ($name != $this->keys[0] && strpos($field[CONS_XML_SQL], "AUTO_INCREMENT") === false) { # cannot change main key or auto_increment ones $outfield = $this->sqlParameter(false, $data, $name, $field, $EnumPrunecache, false, $kA, $wS); if ($outfield !== false) { $output .= $name . "=" . $outfield . ","; } } # if (not key) } #foreach unset($outfield); if ($output != "") { # removes end , $output = substr($output, 0, strlen($output) - 1); $sql .= $output . " WHERE " . $wS; if (!$this->parent->dbo->simpleQuery($sql, $this->parent->debugmode)) { $this->parent->errorState = true; $lastError = $this->parent->dbo->log[count($this->parent->dbo->log) - 1]; if (strpos(strtolower($lastError), "duplicate") === false) { if (!$silent) { $this->parent->errorControl->raise(136, "", $this->name); } } else { if (!$silent) { $this->parent->errorControl->raise(137, "", $this->name); } } return false; } else { $this->parent->notifyEvent($this, CONS_ACTION_UPDATE, $data, $startedAt); # later notify $this->parent->storage['lastactiondata'] =& $data; } } else { $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(138, "", $this->name); } return false; } if (count($EnumPrunecache) != 0) { $this->autoPrune($EnumPrunecache, $data); } return true; break; case CONS_ACTION_INCLUDE: ###################################################### INCLUDE ############################################ if ($this->parent->safety) { # checkPermission has this test but this is faster if ($this->parent->safety && $_SESSION[CONS_SESSION_ACCESS_LEVEL] < 100) { $this->parent->lockPermissions(); if (!$this->parent->authControl->checkPermission($this, CONS_ACTION_INCLUDE, array(true, true, true, 0))) { $this->parent->errorControl->raise(150, '', $this->name); return false; # cannot create even OWNED items } } # can create items } # if this module have multiple key fields, there is no auto_increment IF there is an id (id created automatically w/o AI) if (count($this->keys) > 1 && $this->keys[0] == "id") { $wheres = array(); foreach ($this->keys as $field) { if ($field != "") { if (!isset($data[$field])) { # we need this parent data to create the id, but it's missing! $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(139, $field, $this->name); } return false; } array_push($wheres, $field . "=\"" . $data[$field] . "\""); } } # foreach $sql = "SELECT MAX(id) FROM " . $this->dbname . (count($wheres) != 0 ? " WHERE " . implode(" AND ", $wheres) : ""); $id = $this->parent->dbo->fetch($sql, $this->parent->debugmode); if (!$id) { # suposes it was empty $id = 1; } else { $id++; } $sql = "INSERT INTO " . $this->dbname . " SET id='{$id}',"; $data['id'] = $id; } else { $id = false; $sql = "INSERT INTO " . $this->dbname . " SET "; } $output = ""; $hasAuto = ""; $outfield = false; foreach ($this->fields as $name => $field) { if ($this->parent->safety && isset($field[CONS_XML_RESTRICT]) && $_SESSION[CONS_SESSION_ACCESS_LEVEL] < $field[CONS_XML_RESTRICT]) { # safety is on and this is a restricted field, while the user trying to add it does not have enough level # however while ADDING a field that is mandatory, if it has no default you can add if (!isset($field[CONS_XML_MANDATORY]) || isset($field[CONS_XML_DEFAULT])) { if (isset($data[$name])) { $this->parent->errorControl->raise(145, $name, $this->name, 'not mandatory or default on add'); } unset($data[$name]); } } if (strpos(strtolower($field[CONS_XML_SQL]), "auto_increment") === false && !($this->keys[0] == "id" && $name == $this->keys[0] && count($this->keys) > 1)) { # cannot change auto_increment or main key fields $outfield = $this->sqlParameter(true, $data, $name, $field, $EnumPrunecache); if ($outfield !== false) { $output .= $name . "=" . $outfield . ","; } if ((!$outfield || !isset($data[$name]) || $data[$name] == '') && isset($field[CONS_XML_AUTOFILL]) && !isset($field[CONS_XML_DEFAULT])) { if (isset($data[$field[CONS_XML_AUTOFILL]])) { $data[$name] = $data[$field[CONS_XML_AUTOFILL]]; // if the autofill field is HTML and this is NOT, remove HTML if ($field[CONS_XML_TIPO] == CONS_TIPO_TEXT && !isset($field[CONS_XML_HTML])) { if (isset($this->fields[$field[CONS_XML_AUTOFILL]][CONS_XML_HTML])) { $data[$name] = preg_replace("/(<)([^<>]*)(>)/", "", $data[$name]); } } $output .= $name . "=\"" . $data[$name] . "\","; } } } else { # if (not AutoIncrement) $hasAuto = $name; } } #foreach $id = 0; unset($outfield); if ($output != "") { # removes end , $output = substr($output, 0, strlen($output) - 1); $sql .= $output; if (!$this->parent->dbo->simpleQuery($sql, $this->parent->debugmode)) { $this->parent->errorState = true; $lastError = $this->parent->dbo->log[count($this->parent->dbo->log) - 1]; if (strpos(strtolower($lastError), "duplicate") === false) { if (!$silent) { $this->parent->errorControl->raise(140, $lastError, $this->name); } } else { if (!$silent) { $this->parent->errorControl->raise(141, $lastError, $this->name); } } return false; } else { # post processing ... if ($this->keys[0] == "id") { $id = $this->parent->dbo->insert_id(); if ($hasAuto != "") { $data[$hasAuto] = $id; } else { $data['id'] = $id; } } # check for uploads and urla $wS = ""; $kA = array(); $this->getKeys($wS, $kA, $data); foreach ($this->fields as $name => $field) { if ($field[CONS_XML_TIPO] == CONS_TIPO_SERIALIZED) { foreach ($field[CONS_XML_SERIALIZEDMODEL] as $exname => $exfield) { #--- serialized uploads if ($exfield[CONS_XML_TIPO] == CONS_TIPO_UPLOAD) { $upOk = $this->prepareUpload($name . "_" . $exname, $kA, $data); if ($upOk != 4 && $upOk != 0) { // 4 = nothing sent, 0 = sent and ok # not mandatory but failed, warn about it but do not abort if (!$silent) { $this->parent->errorControl->raise(200 + $upOk, $upOk, $this->name, $name . '_' . $exname); } //$this->deleteUploads($kA,$name."_".$exname,'',$name); // delete possible partial thumbnail process # so far, serialized uploads have no flag //} else if ($upOk == 0) { // $this->parent->dbo->simpleQuery("UPDATE ".$this->dbname." SET $name='y' WHERE $wS"); } } } } if ($field[CONS_XML_TIPO] == CONS_TIPO_UPLOAD) { #--- normal uploads $upOk = $this->prepareUpload($name, $kA, $data); if ($upOk != 0 && isset($field[CONS_XML_MANDATORY])) { # failed or didn't send upload but it's mandatory $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(200 + $upOk, $upOk, $this->name, $name); } # must remove inserted data! $this->parent->dbo->simpleQuery("DELETE FROM " . $this->dbname . " WHERE " . $wS, $this->parent->debugmode); $this->deleteUploads($kA); return false; } else { if ($upOk != 4 && $upOk != 0) { // 4 = nothing sent, 0 = sent and ok # not mandatory but failed, warn about it but do not abort if (!$silent) { $this->parent->errorControl->raise(200 + $upOk, $upOk, $this->name, $name); } $this->deleteUploads($kA, $name); // delete possible partial thumbnail process } else { if ($upOk == 0) { $this->parent->dbo->simpleQuery("UPDATE " . $this->dbname . " SET {$name}='y' WHERE {$wS}"); } } } } else { if ($field[CONS_XML_TIPO] == CONS_TIPO_VC && isset($field[CONS_XML_SPECIAL]) && $field[CONS_XML_SPECIAL] == "urla" && (!isset($data[$name]) || $data[$name] == '')) { # EMPTY special VC urla might require the data to be fully processed to create the proper result, so we do it after the include $source = isset($field[CONS_XML_SOURCE]) ? $field[CONS_XML_SOURCE] : "{" . $this->title . "}"; $tp = new CKTemplate($this->parent->template); $tp->tbreak($source); $urla = removeSimbols($tp->techo($data), true, false); if ($urla != '') { $this->parent->dbo->simpleQuery("UPDATE " . $this->dbname . " SET {$name}=\"{$urla}\" WHERE {$wS}"); $data[$name] = $urla; } unset($tp); } } } $this->parent->lastReturnCode = $id; $this->parent->notifyEvent($this, CONS_ACTION_INCLUDE, $data, $startedAt, false); # later notify (there is no early notify for an include) $this->parent->lastReturnCode = $id; // notifyEvent could have changed/consumed lastReturnCode $this->parent->storage['lastactiondata'] =& $data; } } else { # null insert? error $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(142, "", $this->name); } return false; } if (count($EnumPrunecache) != 0) { $this->autoPrune($EnumPrunecache, $data); } return true; break; case CONS_ACTION_DELETE: ###################################################### DELETE ############################################ $wS = ""; $kA = array(); $haveallKeys = $this->getKeys($wS, $kA, $data); # security $Owner = $this->parent->authControl->checkOwner($this, $kA); // array with isOwner and isSameGroup if ($this->parent->safety && $_SESSION[CONS_SESSION_ACCESS_LEVEL] < 100) { $this->parent->lockPermissions($this, $data, $Owner); if (!$this->parent->authControl->checkPermission($this, CONS_ACTION_DELETE, $Owner, $data)) { $this->parent->errorControl->raise(149, '', $this->name); return false; } } $this->parent->notifyEvent($this, CONS_ACTION_DELETE, $data, $startedAt, true); # early notify if ($this->parent->dbo->simpleQuery("DELETE FROM " . $this->dbname . " WHERE " . $wS, $this->parent->debugmode)) { $this->deleteUploads($kA); $this->parent->notifyEvent($this, CONS_ACTION_DELETE, $data, $startedAt, false); # later notify return true; } else { $this->parent->errorState = true; if (!$silent) { $this->parent->errorControl->raise(143, "", $this->name); } return false; } break; } # switch }
function checkActions() { // look for the first valid context if this is invalid (a.k.a. remove virtual folders) $tempContext = $this->context; $strContext = implode("/", $tempContext); while (count($tempContext) > 1 && !is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/template" . $strContext) && !is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/content" . $strContext) && !is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $strContext)) { array_pop($tempContext); $strContext = implode("/", $tempContext); $this->virtualFolder = true; // if this remains true, we will 404 } #$this->warning[] = "load VF=".($this->virtualFolder?"T":"F"); if ($this->maintenanceMode) { $this->log[] = cReadFile("maint.txt"); } if (!isset($_SESSION[CONS_SESSION_ACCESS_LEVEL])) { $_SESSION[CONS_SESSION_ACCESS_LEVEL] = CONS_SESSION_ACCESS_LEVEL_GUEST; $this->currentAuth = CONS_AUTH_SESSION_GUEST; } if (isset($_POST['haveinfo'])) { $this->loadAllmodules(); } # haveinfo flags the framework that an action MIGHT take place, and thus some extra libraries and precautions should be taken $this->currentAuth = $this->authControl->auth(); // <-- authControl or whatever plugin that snatches it, should also give the user warnings. Check errorControl for standard raise codes (3xx) // built-in ajax captured to the default folder. BEFORE any other action because we don't want default behaviour messing this if ($this->action == "ajaxquery") { // this is used by some plugins (mostly the admin) to fill a select based on other select include_once CONS_PATH_SYSTEM . "lazyload/ajaxQuery.php"; // ajaxQuery SHOULD perform a graceful close, but let's ensure $this->close(true); } else { if ($this->action == "ajaxqueryunique") { // this queries if a certain field (ex: login or mail) is unique for a certain database (good to check if a login is already taken) include_once CONS_PATH_SYSTEM . "lazyload/ajaxqueryunique.php"; // ajaxqueryunique SHOULD perform a graceful close, but let's ensure $this->close(true); } } // allows you to download a file field (f) from a module (m), with the specified module title as filename, checking permission. // will also trigger a "download" notifyEvent on the module // NOTE: if bi_stats is on, this will NOT BE LOGGED (TODO: fix?) if ($this->action == "_download" && isset($_REQUEST['m']) && isset($_REQUEST['f'])) { // same as above $m = $this->loaded($_REQUEST['m']); if ($m !== false && isset($m->fields[$_REQUEST['f']])) { if (!$this->authControl->checkPermission($m)) { $this->fastClose(403); } // read permission $ws = ""; $ka = array(); $m->getKeys($ws, $ka, $_REQUEST); $sql = "SELECT " . $m->title . " FROM " . $m->dbname . " as " . $m->name . " WHERE " . $ws; $filename = removeSimbols($this->dbo->fetch($sql), true, false); $file = CONS_FMANAGER . $m->name . "/" . $_REQUEST['f'] . "_"; foreach ($ka as $kn => $ki) { // this is multikey =D $file .= $ki . "_"; } $file .= "1"; if (locateAnyFile($file, $ext)) { $filename .= "." . $ext; $this->notifyEvent($m, "download", $ka, $m, true); // plugin should handle this $this->close(false); // gracefull $this->readfile($file, $ext, true, $filename, true); $this->close(true); // should never get here } } $this->action = '404'; $this->warning[] = "404 because download request of invalid file"; } foreach ($this->onActionCheck as $scriptName) { $this->loadedPlugins[$scriptName]->onCheckActions(); #$this->warning[] = "VF after $scriptName = ".($this->virtualFolder?"T":"F"); } if ($this->virtualFolder) { // if we are in a virtualFolder, we run the closest default.php #$this->warning[] = "still VF after onCheckActions"; if ($strContext == "" || $strContext[strlen($strContext) - 1] != "/") { $strContext .= "/"; } // closest default (which SHOULD disable virtualFolder or disable 404) if (is_file(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $strContext . "default.php")) { include_once CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $strContext . "default.php"; } // bring to real context $this->context = $tempContext; $this->context_str = $strContext; if ($this->virtualFolder && !$this->ignore404) { // still virtual!? 404 $this->action = "404"; $this->warning[] = "404 because of untreated virtualFolder at actions"; } } else { // default behaviour if (is_file(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $this->context_str . "default.php")) { include_once CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $this->context_str . "default.php"; } } if (is_file(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $this->context_str . $this->action . ".php")) { include_once CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions" . $this->context_str . $this->action . ".php"; } // at this point, all DEFAULT scripts were called; Rechecks for permissions (if auth module or some plugin set it before) $this->lockPermissions(); // replace in case some action redirected us $this->template->constants['ACTION'] = $this->action; $this->template->constants['CONTEXT'] = $this->context_str; $this->template->constants['ORIGINAL_ACTION'] = $this->original_context_str . $this->original_action; }
<?php if (isset($_REQUEST['delfile'])) { $dir = str_replace(".", "", $_REQUEST['dir']); if ($dir != "" && $dir[0] == "/") { $dir = substr($dir, 1); } if ($dir != "" && $dir[strlen($dir) - 1] == "/") { $dir = substr($dir, 0, -1); } $core->storage['dir'] = "/" . $dir; if ($this->canEdit($dir)) { $file = removeSimbols($_REQUEST['delfile']); if (!is_file(CONS_FMANAGER . $dir . "/" . $file) && is_file(CONS_FMANAGER . $dir . "/" . $_REQUEST['delfile'])) { $file = $_REQUEST['delfile']; } if (is_file(CONS_FMANAGER . $dir . "/" . $file)) { if (unlink(CONS_FMANAGER . $dir . "/" . $file)) { $core->log[] = "File {$file} deleted at {$dir}"; $core->storage['error'] = $core->langOut("delete_file_ok"); $core->errorControl->raise(510, "Delete file {$file} at {$dir}", "fmanager"); $fakeLink = false; $core->notifyEvent($fakeLink, 'fmanager_delete', CONS_FMANAGER . $dir . "/" . $file, 'bi_adm', false); } else { $core->log[] = "Error deleting {$file} deleted at {$dir}"; $core->storage['error'] = $core->langOut("delete_file_err"); $core->errorControl->raise(511, "Delete file FAIL: {$file} at {$dir}", "fmanager"); } } else { $core->storage['error'] = $core->langOut("delete_file_nf") . ": " . CONS_FMANAGER . $dir . "/" . $file; }
function killCache($tag) { // kills all caches for this tag (supports a * at the end) $lazymatch = false; if ($tag[strlen($tag) - 1] == "*") { $lazymatch = true; $tag = substr($tag, 0, strlen($tag) - 1); } // shared caches $tags = removeSimbols($this->cacheuid(true) . $tag, true, false); if ($lazymatch) { $files = listFiles(CONS_PATH_CACHE . $_SESSION["CODE"] . "/caches/", "/^" . $tags . "/"); foreach ($files as $file) { @unlink($file); } } else { $file = CONS_PATH_CACHE . $_SESSION["CODE"] . "/caches/{$tag}.cache"; @unlink($file); } $tagns = removeSimbols($this->cacheuid(false) . $tag, true, false); if ($lazymatch) { $size = strlen($tagns); foreach ($_SESSION[CONS_SESSION_CACHE] as $key => $cache) { if (substr($key, $size) == $tag) { unset($_SESSION[CONS_SESSION_CACHE][$key]); } } } else { unset($_SESSION[CONS_SESSION_CACHE][$tagns]); } }
<?php if (isset($_REQUEST['haveinfo'])) { if (isset($_REQUEST['makedir'])) { $core->storage['dir'] = '/'; $theDir = trim($_REQUEST['makedir']); if ($theDir != "" && $theDir[strlen($theDir) - 1] == "/") { $theDir = substr($theDir, 0, -1); } $theDir = explode("/", $theDir); $coreDir = removeSimbols(array_pop($theDir), false, true); $theDir = implode("/", $theDir); // parent if (is_dir(CONS_FMANAGER . $theDir)) { $core->storage['dir'] = $theDir; $theDir .= "/" . $coreDir; if ($this->canEdit($theDir)) { if (safe_mkdir(CONS_FMANAGER . $theDir)) { $core->log[] = "Folder " . $theDir . " created"; $core->errorControl->raise(506, "Created {$theDir}", "fmanager"); $core->storage['error'] = $core->langOut("create_folder_ok"); $core->storage['dir'] = $theDir; } else { $core->logaction(CONS_ACTION_INCLUDE, $fm, false, false); $core->storage['error'] = $core->langOut("create_folder_error"); } } else { $core->storage['error'] = $core->langOut("create_folder_pd"); } } else { $core->storage['error'] = $core->langOut("create_folder_error_pnf");
function extractUri($install_root = "", $uri = "") { // returns an array with: array of folders from URI, filename (no extension), actual filename with extension, extension // removes install_root to make some changes to how it is handled (basically, ignores it) # context if ($uri == "") { $uri = str_replace("%2F", "/", isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] != "" ? $_SERVER['REQUEST_URI'] : ""); } if ($uri != "") { # removes query from request if ($uri[0] != "/") { $uri = "/" . $uri; } # ALWAYS START WITH / $uri = explode("?", $uri); $uri = str_replace("..", ".", array_shift($uri)); # little exploit remover if ($install_root != "/" && preg_match("@^(" . $install_root . ")(.*)\$@", $uri, $regs)) { $uri = "/" . $regs[2]; } $uri = explode("/", str_replace("//", "/", $uri)); } else { $uri = array("/"); } $context = array(); foreach ($uri as $part) { array_push($context, preg_replace("/(\\.){2,}/", "\\.", $part)); } # prevents .. $action = array_pop($context); $original_action = $action; $ext = ""; if ($action == "") { $action = 'index'; } else { if (strpos($action, ".") !== false) { $action = explode(".", $action); $ext = array_pop($action); $action = implode(".", $action); $action = removeSimbols($action, true, false); # note extension was removed } } return array($context, $action, $original_action, $ext); }