/** * Return data files as requested * * @param object $context The context object for the site * @param object $local The local object for the site * * @return string A template name */ public function handle($context) { $web = Web::getinstance(); # it's used all over the place so grab it once chdir($context->local()->basedir()); $fpt = $context->rest(); if (count($fpt) == 2 && $fpt[0] == 'file') { # this is access by upload ID $file = R::load('upload', $fpt[1]); if ($file->getID() == 0) { $web->notfound(); /* NOT REACHED */ } $this->file = substr($file->fname, 1); // drop the separator at the start.... } else { chdir(self::DATADIR); /** * Depending on how you construct the URL, it's possible to do some sanity checks on the * values passed in. The structure assumed here is /user_id/year/month/filename so * the regexp test following makes sense. * This all depends on your application and how you want to treat files and filenames and access of course! * * ALways be careful that filenames do not have .. in them of course. * */ $this->file = implode(DIRECTORY_SEPARATOR, $fpt); if (!preg_match('#^[0-9]+/[0-9]+/[0-9]+/[^/]+$#', implode('/', $fpt))) { # filename constructed is not the right format $web->bad(); /* NOT REACHED */ } # Now do an access control check $file = R::findOne('upload', 'fname=?', [DIRECTORY_SEPARATOR . self::DATADIR . DIRECTORY_SEPARATOR . $this->file]); if (!is_object($file)) { # not recorded in the database so 404 it $web->notfound(); /* NOT REACHED */ } } if (!$file->canaccess($context->user())) { # caurrent user cannot access the file $web->noaccess(); /* NOT REACHED */ } if (($this->mtime = filemtime($this->file)) === FALSE) { $web->internal('Lost File: ' . $this->file); /* NOT REACHED */ } $this->ifmodcheck(); # check to see if we actually need to send anything $web->addheader(['Last-Modified' => $this->mtime, 'Etag' => '"' . $this->makeetag() . '"']); $web->sendfile($this->file, $file->filename); return ''; }
/** * Add a role * * @param string $contextname The name of a context... * @param string $rolename The name of a role.... * @param string $otherinfo Any other info that is to be stored with the role * @param string $start A datetime * @param string $end A datetime or '' * * @return object */ public function addrole($contextname, $rolename, $otherinfo, $start, $end = '') { $cname = R::findOne('rolecontext', 'name=?', array($contextname)); if (!is_object($cname)) { Web::getinstance()->bad(); } $rname = R::findOne('rolename', 'name=?', array($rolename)); if (!is_object($rname)) { Web::getinstance()->bad(); } $this->addrolebybean($cname, $rname, $otherinfo, $start, $end); }
/** * We have a matched etag - check request method and send the appropriate header. * Does not return * * @link https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 * * @return void */ private function etagmatched() { $web = Web::getinstance(); $rqm = $web->method(); if ($rqm != 'GET' && $rqm != 'HEAD') { # fail if not a GET or HEAD - see W3C specification $web->sendheaders(StatusCodes::HTTP_PRECONDITION_FAILED); } else { $web->send304($this->makeetag(), $this->makemaxage()); } exit; }
/** * Display a string in an X-DEBUG-INFO header * * @param string $str * * @todo use the new ... stuff in PHP 5.6 to allow many parameters * * @return void */ public static function head($str) { Web::getinstance()->addheader('X-DEBUG-INFO', $str); }
$context = Context::getinstance()->setup($local); /* * The valid actions for the site, i.e. valid first part of the URL * * If the value is false then just the template is rendered and no object called up */ $pages = array('about' => array(Siteaction::TEMPLATE, 'about.twig'), 'admin' => array(Siteaction::OBJECT, 'Admin'), 'home' => array(Siteaction::TEMPLATE, 'index.twig')); $action = $context->action(); if (!isset($pages[$action])) { # oops, we've been asked to do something that we don't do Web::getinstance()->notfound('No such page'); # a basic 404 - the page should be much more helpful # DOES NOT RETURN } $local->addval('context', $context); $local->addval('page', $action); $local->addval('siteinfo', new SiteInfo($local)); switch ($pages[$action][0]) { case Siteaction::OBJECT: $op = new $pages[$action][1](); $tpl = $op->handle($context); break; case Siteaction::TEMPLATE: $tpl = $pages[$action][1]; break; default: Web::getinstance()->internal('Weird error'); } ob_start('ob_gzhandler'); $local->render($tpl); ob_end_flush();
/** * Return the Web object * * @return object */ public function web() { return Web::getinstance(); }
/** * Render a twig - do nothing if the template is the empty string * * @param string $tpl The template * @param array $vals Values to set for the twig */ public function render($tpl, $vals = []) { if ($tpl !== '') { Web::getinstance()->sendstring($this->getrender($tpl, $vals), 'text/html; charset="utf-8"'); } }
/** * Make an etag - overrides the function in SiteAction * * @return string */ public function makeetag() { return sprintf("%u", crc32($this->file)) . '-' . $this->mtime . '-' . (Web::getinstance()->acceptgzip() ? 1 : 0); }
/** * Handle various admin operations /admin/xxxx * * @param object $context The context object for the site * * @return string A template name */ public function handle($context) { $rest = $context->rest(); switch ($rest[0]) { case 'pages': $tpl = 'support/pages.twig'; break; case 'contexts': $tpl = 'support/contexts.twig'; break; case 'roles': $tpl = 'support/roles.twig'; break; case 'users': $tpl = 'support/users.twig'; break; case 'forms': $tpl = 'support/forms.twig'; break; case 'config': $tpl = 'support/config.twig'; break; case 'info': $_SERVER['PHP_AUTH_PW'] = '*************'; # hide the password in case it is showing. phpinfo(); exit; case 'edit': // Edit something - forms and users if (count($rest) < 3) { Web::getinstance()->bad(); } $kind = $rest[1]; $obj = $context->load($kind, $rest[2]); if (!is_object($obj)) { Web::getinstance()->bad(); } if (($bid = $context->formdata()->post('bean', '')) !== '') { # this is a post if ($bid != $obj->getID()) { # something odd... Web::getinstance()->bad(); } $obj->edit($context); // The edit call might divert to somewhere else so sometimes we may not get here. } Local::getinstance()->addval($kind, $obj); $tpl = 'support/edit' . $kind . '.twig'; break; case 'view': // view something - forms if (count($rest) < 3) { Web::getinstance()->bad(); } $kind = $rest[1]; $obj = $context->load($kind, $rest[2]); if (!is_object($obj)) { Web::getinstance()->bad(); } if (($bid = $context->formdata()->post('bean', '')) !== '') { # this is a post if ($bid != $obj->getID()) { # something odd... Web::getinstance()->bad(); } $obj->edit($context); // The edit call might divert to somewhere else so sometimes we may not get here. } Local::getinstance()->addval($kind, $obj); $tpl = 'support/view' . $kind . '.twig'; break; case 'update': if (function_exists('zip_open')) { $formd = $context->formdata(); if ($formd->hasfile('update')) { $data = $formd->filedata('update'); if (($zd = zip_open($data['tmp_name'])) === FALSE) { $context->local()->message(Local::ERROR, 'Cannot open the file'); } else { $context->local()->message(Local::MESSAGE, 'Done'); } } } else { $context->local()->addval('nozip', TRUE); } $tpl = 'support/update.twig'; break; default: $tpl = 'support/admin.twig'; break; } return $tpl; }
/** * Look in the $_COOKIE array for a key and return its trimmed value or fail * * @param string $name * @param boolean $fail * * @return mixed */ public function mustcookie($name, $fail = TRUE) { if (filter_has_var(INPUT_COOKIE, $name)) { return trim($_COOKIE[$name]); } if ($fail) { Web::getinstance()->bad(); } return NULL; }