コード例 #1
0
ファイル: SyslogBackend.php プロジェクト: photon/log-syslog
 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;
 }
コード例 #2
0
 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'));
 }
コード例 #3
0
ファイル: task.php プロジェクト: photon/photon
 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;
 }
コード例 #4
0
ファイル: configTest.php プロジェクト: photon/photon
 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'));
 }
コード例 #5
0
ファイル: MongoDB.php プロジェクト: photon/session-mongodb
 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);
 }
コード例 #6
0
ファイル: db.php プロジェクト: photon/photon
 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];
 }
コード例 #7
0
 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);
 }
コード例 #8
0
 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);
 }
コード例 #9
0
 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);
 }
コード例 #10
0
ファイル: http.php プロジェクト: photon/photon
 /**
  * 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', ''));
 }
コード例 #11
0
ファイル: log.php プロジェクト: photon/photon
 /**
  * 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;
 }
コード例 #12
0
ファイル: session.php プロジェクト: photon/photon
 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;
 }
コード例 #13
0
ファイル: sessionTest.php プロジェクト: photon/photon
 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']);
 }
コード例 #14
0
ファイル: manager.php プロジェクト: photon/photon
 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);
 }
コード例 #15
0
ファイル: auth.php プロジェクト: photon/photon
 /**
  * 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);
 }
コード例 #16
0
ファイル: compiler.php プロジェクト: photon/photon
 /**
  * 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);
     }
 }
コード例 #17
0
ファイル: mail.php プロジェクト: photon/photon
 /**
  * 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());
         }
     }
 }
コード例 #18
0
ファイル: response.php プロジェクト: photon/photon
 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;
 }
コード例 #19
0
ファイル: rendererTest.php プロジェクト: photon/photon
 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());
 }
コード例 #20
0
 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;
 }
コード例 #21
0
ファイル: core.php プロジェクト: photon/photon
 /**
  * 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);
 }
コード例 #22
0
ファイル: middleware.php プロジェクト: photon/photon
 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;
 }
コード例 #23
0
ファイル: translation.php プロジェクト: photon/photon
 /**
  * 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;
 }
コード例 #24
0
ファイル: template.php プロジェクト: photon/photon
 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);
 }
コード例 #25
0
ファイル: shortcuts.php プロジェクト: photon/photon
 /**
  * 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);
 }
コード例 #26
0
ファイル: server.php プロジェクト: photon/photon
 /**
  * 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.
     }
 }
コード例 #27
0
ファイル: storage.php プロジェクト: photon/photon
 /**
  * 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;
 }