public static function write($stack) { if (self::$isOpen === false) { $default = array('ident' => 'PhotonApp', 'facility' => LOG_USER, 'option' => LOG_CONS | LOG_NDELAY | LOG_PID); $conf = Conf::f('log_syslog', $default); $conf = array_merge($default, $conf); // Windows can log only in LOG_USER if (substr(PHP_OS, 0, 3) === 'WIN') { $conf['facility'] = LOG_USER; } $rc = openlog($conf['ident'], $conf['option'], $conf['facility']); if ($rc === true) { self::$isOpen = true; } } foreach ($stack as $elt) { $level = self::$photon2syslog[$elt[1]]; if (is_array($elt[2]) || is_object($elt[2])) { $msg = json_encode($elt[2]); } else { $msg = $elt[2]; } syslog($level, $msg); } return false; }
public function __construct($conf = array()) { parent::__construct($conf); // Connect to each mongrel2 servers on port PUB & Control only // The worker do not want to receive HTTP requests from mongrel2 $servers = Conf::f('server_conf', null); if ($servers === null) { Log::fatal("No mongrel2 servers in the configuration"); Log::flush(); exit(0); } foreach ($servers as $serverId => $server) { // Ignore servers without control port if (isset($server['ctrl_addr']) === false || $server['ctrl_addr'] === null || isset($server['pub_addr']) === false || $server['pub_addr'] === null) { continue; } Log::info('Server #' . $serverId . ' Control = ' . $server['ctrl_addr'] . ' Pub = ' . $server['pub_addr']); $connection = new Connection(null, $server['pub_addr'], $server['ctrl_addr']); $connection->connect(); $this->connections[] = $connection; $this->jobs[] = array(); } if (count($this->connections) === 0) { Log::fatal('No mongrel2 servers with control port detected'); Log::flush(); exit(0); } Log::info('Task ready, ' . gmdate('c')); }
private function connectTask($name, $class = null) { if (null === self::$ctx) { return false; } if (isset(self::$sockets[$name])) { return true; } if ($class === null) { $tasks = Conf::f('installed_tasks', array()); $class = $tasks[$name]; } // We need to know if this is an async or sync task // We need to get the bind socket. $conf = Conf::f('photon_task_' . $name, array()); $bind = isset($conf['sub_addr']) ? $conf['sub_addr'] : SUB_ADDR; $type = isset($conf['type']) ? $conf['type'] : $class::$type; if ('async' === $type) { self::$sockets[$name] = new \ZMQSocket(self::$ctx, \ZMQ::SOCKET_DOWNSTREAM); self::$sockets[$name]->connect($bind); } else { self::$sockets[$name] = new \ZMQSocket(self::$ctx, \ZMQ::SOCKET_REQ); self::$sockets[$name]->connect($bind); } self::$types[$name] = $type; return true; }
public function testDumpLoad() { $this->assertequals(true, Conf::f('debug')); $conf = Conf::dump(); $new_conf = array('debug' => false); Conf::load($new_conf); $this->assertequals(false, Conf::f('debug')); Conf::load($conf); $this->assertequals(true, Conf::f('debug')); }
public function __construct() { $backendConfiguration = Conf::f('session_mongodb', array()); foreach ($backendConfiguration as $key => $value) { $this->{$key} = $value; } if ($this->database === null || $this->collection === null) { throw new Exception('Configuration missing or invalid for MongoDB Session Backend'); } $this->db = DB::get($this->database)->selectCollection($this->collection); }
public static function get($db = 'default') { if (isset(self::$conns[$db]) === false) { $defs = Conf::f('databases', array()); if (!isset($defs[$db])) { throw new UndefinedConnection(sprintf('The connection "%s" is not defined in the configuration.', $db)); } $engine = $defs[$db]['engine']; self::$conns[$db] = $engine::get($defs[$db]); } return self::$conns[$db]; }
public function __construct() { $backendConfiguration = Conf::f('session_memcached', array()); foreach ($backendConfiguration as $key => $value) { $this->{$key} = $value; } $this->expire = Conf::f('session_cookie_expire', null); if ($this->database === null) { throw new Exception('Configuration missing or invalid for Memcached Session Backend'); } $this->db = DB::get($this->database); }
public function __construct($gridFsName, $filter = array()) { $databases = Conf::f('databases', array()); $config = Conf::f('storage-mongodb-object', array()); $dbName = isset($config['databases']) ? $config['databases'] : 'default'; if (!isset($databases[$dbName])) { throw new \photon\db\UndefinedConnection(sprintf('The connection "%s" is not defined in the configuration.', $dbName)); } $class = class_exists('\\MongoClient') ? '\\MongoClient' : '\\Mongo'; $conn = new $class($databases[$dbName]['server'], $databases[$dbName]['options']); $db = $conn->selectDB($databases[$dbName]['database']); $gridfs = $db->getGridFS($gridFsName); $ns = $databases[$dbName]['database'] . '.' . $gridFsName . '.files'; $fields = array(); parent::__construct($gridfs, $conn, $ns, $filter, $fields); }
public function __construct($objectType, $filter = array(), $collectionName = null) { $this->objectType = $objectType; $objectType; if ($collectionName === null) { $collectionName = $objectType::collectionName; } else { $this->collectionName = $collectionName; } $databases = Conf::f('databases', array()); $config = Conf::f('storage-mongodb-object', array()); $dbName = isset($config['databases']) ? $config['databases'] : 'default'; if (!isset($databases[$dbName])) { throw new \photon\db\UndefinedConnection(sprintf('The connection "%s" is not defined in the configuration.', $db)); } $class = class_exists('\\MongoClient') ? '\\MongoClient' : '\\Mongo'; $conn = new $class($databases[$dbName]['server'], $databases[$dbName]['options']); $ns = $databases[$dbName]['database'] . '.' . $collectionName; $fields = array('_id' => 1); parent::__construct($conn, $ns, $filter, $fields); }
/** * Request object provided to the Photon views. * * @param &$mess Mongrel2 request message object. */ function __construct(&$mess) { $this->mess = $mess; $this->path = $this->mess->path; $this->method = $this->mess->headers->METHOD; $this->sender = $this->mess->sender; $this->client = $this->mess->conn_id; $this->headers = $this->mess->headers; if (isset($this->mess->headers->QUERY)) { \mb_parse_str($this->mess->headers->QUERY, $this->GET); $this->query = $this->mess->headers->QUERY; } if ('POST' === $this->mess->headers->METHOD || 'PUT' === $this->mess->headers->METHOD) { if (isset($this->mess->headers->{'content-type'}) === false) { $this->BODY =& $mess->body; } else { if (0 === strpos($this->mess->headers->{'content-type'}, 'multipart/form-data; boundary=')) { $parser = new \photon\http\multipartparser\MultiPartParser($mess->headers, $mess->body); foreach ($parser->parse() as $part) { if ('FIELD' === $part['of_type']) { add_to_post($this->POST, $part['name'], $part['data']); } else { add_file_to_post($this->FILES, $part['name'], $part); } } } else { if (false !== mb_strstr($this->mess->headers->{'content-type'}, 'application/x-www-form-urlencoded')) { $this->POST = parse_str(substr(stream_get_contents($mess->body), 0, -1)); } else { $this->BODY =& $mess->body; } } } } else { if ('JSON' === $this->mess->headers->METHOD) { $this->BODY = $this->mess->body; } } $this->COOKIE = CookieHandler::parse($this->mess->headers, Conf::f('secret_key', '')); }
/** * Flush the stack to the disk. * * @param $stack Array */ public static function write($stack) { if (null === self::$log_file) { self::$log_file = Conf::f('photon_log_file', Conf::f('tmp_folder', sys_get_temp_dir()) . '/photon.log'); } $out = array(); foreach ($stack as $elt) { $out[] = date(DATE_ISO8601, $elt[0]) . ' [' . Log::$reverse[$elt[1]] . '] ' . json_encode($elt[2]); } file_put_contents(self::$log_file, implode(PHP_EOL, $out) . PHP_EOL, FILE_APPEND | LOCK_EX); if (!self::$chmoded) { @chmod($file, 0666); self::$chmoded = true; } return self::$return; }
public function process_response($request, $response) { if (!$response) { // The view took care of everything. return $response; } if (isset($request->session) == false) { // The request do not have execute process_request before // A more highly priority middleware have return a answer return $response; } if ($request->session->accessed) { // This view used session data to render, this means it // varies on the cookie information. \photon\http\HeaderTool::updateVary($response, array('Cookie')); } if ($request->session->modified || Conf::f('session_save_every_request', false)) { // Time to store $request->session->commit($response); $expire = Conf::f('session_cookie_expire', 1209600); if ($expire) { $expire += time(); } $response->COOKIE->setCookie(Conf::f('session_cookie_name', 'sid'), $request->session->key, $expire, Conf::f('session_cookie_path', ''), Conf::f('session_cookie_domain', ''), Conf::f('session_cookie_secure', false), Conf::f('session_cookie_httponly', false)); } return $response; }
public function testStorageCookie() { Conf::set('session_storage', '\\photon\\session\\storage\\Cookies'); Conf::set('secret_key', 'dummy'); // used to crypt/sign the cookies $req = \photon\test\HTTP::baseRequest(); $mid = new \photon\session\Middleware(); $this->assertEquals(false, $mid->process_request($req)); $this->assertEquals(false, isset($req->session['foo'])); $req->session['foo'] = 'bar'; $this->assertEquals(true, isset($req->session['foo'])); $this->assertEquals('bar', $req->session['foo']); unset($req->session['foo']); $this->assertEquals(null, $req->session['foo']); $this->assertEquals(false, isset($req->session['foo'])); $req->session['foo'] = 'bar'; unset($req->session['todelete']); $res = new \photon\http\Response('Hello!'); $mid->process_response($req, $res); $this->assertEquals(true, isset($res->headers['Vary'])); $this->assertEquals(true, isset($res->COOKIE['sid'])); $this->assertEquals(true, isset($res->COOKIE['scs-foo'])); $this->assertEquals(true, isset($res->COOKIE['scs-todelete'])); $iv = $res->COOKIE['scsiv']; // Now we generate a new request with an iv to test the retrieval $req = \photon\test\HTTP::baseRequest(); $req->COOKIE['scsiv'] = $iv; $req->COOKIE['scs-foo'] = \photon\crypto\Crypt::encrypt('bar', Conf::f('secret_key'), $iv); $this->assertEquals(false, $mid->process_request($req)); $this->assertEquals('bar', $req->session['foo']); }
public function run() { $this->loadConfig(); $folders = Conf::f('template_folders', array()); $tmp_folder = sys_get_temp_dir() . '/' . uniqid('photon', true); @mkdir($tmp_folder); @touch($this->potfile); // Compile all template to generate PHP Code $already_compiled = array(); foreach ($folders as $folder) { foreach (\photon\path\Dir::listFiles($folder) as $tpl) { if (!in_array($tpl, $already_compiled)) { // Compile the template $compiler = new compiler\Compiler($tpl, $folders); $content = $compiler->compile(); // save it $output = $tmp_folder . '/' . $tpl; $directory = dirname($output); if (is_dir($directory) === false) { mkdir($directory, 0777, true); } file_put_contents($output, $content); $already_compiled[] = $tpl; } } } $return_var = 0; // Run xgettext on PHP project source $cmd = 'cd ' . $this->cwd . ' && find . -type f -iname "*.php" | sed -e \'s/^\\.\\///\' | xargs xgettext -o ' . $this->potfile . ' -p ' . $this->cwd . ' --from-code=UTF-8 -j --keyword --keyword=__ --keyword=_n:1,2 -L PHP'; passthru($cmd, $return_var); // Run xgettext on PHP project compiled template source $cmd = 'cd ' . $tmp_folder . ' && find . -type f | sed -e \'s/^\\.\\///\' | xargs xgettext -o ' . $this->potfile . ' -p ' . $this->cwd . ' --from-code=UTF-8 -j --keyword --keyword=__ --keyword=_n:1,2 -L PHP'; passthru($cmd, $return_var); \photon\path\Dir::remove($tmp_folder); }
/** * Given a user id, retrieve it. * */ public static function loadUser($user_id) { $users = Conf::f('auth_config_users', array()); if (!isset($users[$user_id])) { return false; } // FUTURE: Need to load the user from the defined backend/storage. return (object) array('login' => $user_id, 'password' => $users[$user_id], 'is_anonymous' => false); }
/** * Construct the compiler. * * @param $template_file string Basename of the template file * @param $folders array Source folders of the templates * @param $options array */ function __construct($template_file, $folders, $options = array()) { $this->_sourceFile = $template_file; $this->templateFolders = $folders; $options = array_merge(array('load' => true, 'tags' => array(), 'modifiers' => array()), $options); $this->_allowedTags = array_merge($this->_allowedTags, $options['tags'], Conf::f('template_tags', array())); Event::send('\\photon\\template\\compiler\\Compiler::construct_load_tags', null, $this->_allowedTags); $this->_modifier = array_merge($this->_modifier, $options['modifiers'], Conf::f('template_modifiers', array())); Event::send('\\photon\\template\\compiler\\Compiler::construct_load_modifiers', null, $this->_modifier); foreach ($this->_allowedTags as $name => $model) { $this->_extraTags[$name] = new $model(); } $this->_allowedInVar = array_merge($this->_vartype, $this->_op); $this->_allowedInExpr = array_merge($this->_vartype, $this->_op); $this->_allowedAssign = array_merge($this->_vartype, $this->_assignOp, $this->_op); if ($options['load']) { $this->sourceFiles[] = $this->loadTemplateFile($this->_sourceFile); } }
/** * Effectively sends the email. */ function sendMail() { $body = $this->message->get(); $hdrs = $this->message->headers($this->headers); $params = Conf::pf('mail_', true); // strip the prefix 'mail_' unset($params['backend']); $gmail = new \Mail(); $mail = $gmail->factory(Conf::f('mail_backend', 'mail'), $params); if (Conf::f('send_emails', true)) { $ret = $mail->send($this->to_address, $hdrs, $body); // Mail return true on success and a PEAR_Error object on failure if ($ret !== true) { throw new Exception($ret->getMessage()); } } }
function __construct($exception, $mimetype = null) { $this->exception = $exception; $content = ''; $admins = Conf::f('admins', array()); if (count($admins) > 0) { // Get a nice stack trace and send it by emails. $stack = pretty_server_error($exception); $subject = $exception->getMessage(); $subject = substr(strip_tags(nl2br($subject)), 0, 50) . '...'; foreach ($admins as $admin) { $email = new Mail($admin[1], $admin[1], $subject); $email->addTextMessage($stack); $email->sendMail(); } } try { $context = new template\Context(array('message' => $exception->getMessage())); $renderer = new template\Renderer('500.html'); $content = $renderer->render($context); $mimetype = null; } catch (\Exception $e) { $mimetype = 'text/plain'; $content = 'The server encountered an unexpected condition which prevented it from fulfilling your request.' . "\n\n" . 'An email has been sent to the administrators, we will correct this error as soon as possible. Thank you for your comprehension.' . "\n\n" . '500 - Internal Server Error'; } parent::__construct($content, $mimetype); $this->status_code = 500; }
public function testCustomTag() { $tags = Conf::f('template_tags', array()); $tags['relativity'] = '\\photon\\tests\\template\\rendererTest\\LocalTag'; Conf::set('template_tags', $tags); $renderer = new template\Renderer('data-template-custom-tag.html', array(__DIR__)); $this->assertequals("E=mc²\n", $renderer->render()); Conf::set('template_tags', array()); }
public static function isEmpty() { $config = Conf::f('storage-mongodb-object', array()); $db = isset($config['databases']) ? $config['databases'] : 'default'; $db = DB::get($db); $collection = $db->selectCollection($this->getCollectionName()); $it = $collection->find(); $it->limit(1); $it->rewind(); return $it->hasNext() === false; }
/** * Provide the full URL (without domain) to a view. * * @param string View. * @param array Parameters for the view (array()). * @param array Extra GET parameters for the view (array()). * @param bool Should the URL be encoded (true). * @return string URL. */ public static function forView($view, $params = array(), $get_params = array(), $encoded = true) { return self::generate(Conf::f('base_urls') . self::reverse(Conf::f('urls', array()), $view, $params), $get_params, $encoded); }
private static function getConfig() { // Cache the config if (self::$config !== null) { return self::$config; } // Build the config $config = Conf::f('middleware_security', array()); $default = array('hsts' => false, 'hsts_options' => array('max-age' => 31536000, 'includeSubDomains' => true, 'preload' => true), 'hpkp' => false, 'hpkp_options' => array('pin-sha256' => array(), 'max-age' => 31536000, 'includeSubDomains' => true, 'report-uri' => false), 'ssl_redirect' => false); self::$config = array_replace_recursive($default, $config); return self::$config; }
/** * Load the locales of a lang. * * It does not activate the locale. * * @param $lang Language to load * @param $photon Load the Photon translations (true) * @return array Path to loaded file */ public static function loadLocale($lang, $photon = true) { $locale_folders = Conf::f('locale_folders', array()); $path_folders = Dir::getIncludePath(); $loaded = array(); self::$loaded[$lang] = array(); if ($photon) { $pofile = sprintf('%s/locale/%s/photon.po', __DIR__, $lang); if (file_exists($pofile)) { self::$loaded[$lang] += self::readPoFile($pofile); $loaded[] = $pofile; } } foreach ($locale_folders as $locale_folder) { foreach ($path_folders as $path_folder) { $pofile = sprintf('%s/%s/%s.po', $path_folder, $locale_folder, $lang); if (file_exists($pofile)) { self::$loaded[$lang] += self::readPoFile($pofile); $loaded[] = $pofile; break; } } } if (count($loaded)) { self::$plural_forms[$lang] = plural_to_php(file_get_contents($loaded[0])); } return $loaded; }
public function __construct($request, $vars = array()) { $vars = array_merge(array('request' => $request), $vars); foreach (Conf::f('template_context_processors', array()) as $proc) { $vars = array_merge(call_user_func($proc, $request), $vars); } $this->_vars = new ContextVars($vars); }
/** * Render a template file and an array as a reponse. * * @param $tmpl Template file name * @param $context Associative array for the context * @return Rendered template as a string */ public static function RenderToString($tmpl, $context) { $renderer = new ptemplate\Renderer($tmpl, Conf::f('template_folders')); $context = new ptemplate\Context($context); return $renderer->render($context); }
/** * Handles the signals. * * @param $signo The POSIX signal. */ public static function signalHandler($signo) { if (\SIGTERM === $signo) { Log::info('Received SIGTERM, now stopping.'); foreach (Conf::f('shutdown', array()) as $i) { call_user_func($i); } die(0); // Happy death, normally we run the predeath hook. } }
/** * Get a value from the storage. * * @required public function get($offset) */ public function get($offset) { if (isset($this->deleted[$offset])) { return null; } if (isset($this->cache[$offset])) { return $this->cache[$offset]; } if (strlen($this->iv) && isset($this->cookie['scs-' . $offset])) { return Crypt::decrypt($this->cookie['scs-' . $offset], Conf::f('secret_key'), $this->iv); } return null; }