예제 #1
0
파일: Query.php 프로젝트: openclerk/db
 function fetchAll()
 {
     if ($this->cursor === null) {
         throw new DbException("Query must be executed first");
     }
     Events::trigger('db_fetch_all_start', $this->query);
     $result = $this->cursor->fetchAll();
     Events::trigger('db_fetch_all_end', $this->query);
     return $result;
 }
예제 #2
0
 /**
  * We can bind and then unbind.
  */
 function testBindThenUnbind()
 {
     $bind = Events::on('test_simple', array($this, 'onTestSimple'));
     try {
         Events::trigger('test_simple', "cat");
         $this->assertEquals(array("cat"), $this->last_simple_data);
     } finally {
         Events::unbind($bind);
     }
     Events::trigger('test_simple', "dog");
     $this->assertEquals(array("cat"), $this->last_simple_data);
     // hasn't changed
 }
예제 #3
0
파일: Email.php 프로젝트: openclerk/emails
 /**
  * Send an email with the given template to the given user or address.
  * The subject of the e-mail is obtained from the first line of the text e-mail template, or the
  * <title> of the HTML template.
  *
  * TODO support mock mailing
  * TODO support i18n
  * TODO service wrapper to allow emails to be queued
  *
  * @param $to_or_user either an email address, or something with getEmail() and optionally getName()
  * @throws MailerException if the mail could not be immediately sent (e.g. technical error, invalid e-mail address...)
  * @return the email result object, which is also sent to the `email_sent` event trigger
  */
 static function send($to_or_user, $template_id, $arguments = array())
 {
     // add any global arguments
     foreach (static::$global_arguments as $name => $callback) {
         if (!isset($arguments[$name])) {
             $arguments[$name] = call_user_func($callback, $arguments);
         }
     }
     $to_name = false;
     $to_id = null;
     if (is_object($to_or_user)) {
         $to_email = $to_or_user->getEmail();
         if (method_exists($to_or_user, 'getName')) {
             $to_name = $to_or_user->getName();
         }
         if (method_exists($to_or_user, 'getId')) {
             $to_id = $to_or_user->getId();
         }
     } else {
         if (is_string($to_or_user)) {
             $to_email = $to_or_user;
         } else {
             throw new MailerException("Unknown 'to' type " . gettype($to_or_user));
         }
     }
     if (!$to_name) {
         $to_name = $to_email;
     }
     // default arguments
     if (!isset($arguments['email'])) {
         $arguments['email'] = $to_email;
     }
     if (!isset($arguments['name'])) {
         $arguments['name'] = $to_name;
     }
     $compiled = self::compile($template_id, $arguments);
     $template = $compiled['text'];
     $html_template = $compiled['html'];
     $subject = $compiled['subject'];
     // now send the email
     // may throw MailerException
     if (self::$mock_mailer) {
         $message_id = call_user_func(self::$mock_mailer, $to_email, $to_name, $subject, $template, $html_template);
     } else {
         $message_id = Email::phpmailer($to_email, $to_name, $subject, $template, $html_template);
     }
     // allow others to capture this event
     $result = array("user_id" => $to_id, "to_name" => $to_name, "to_email" => $to_email, "subject" => $subject, "template_id" => $template_id, "arguments" => $arguments, "message_id" => $message_id);
     \Openclerk\Events::trigger('email_sent', $result);
     return $result;
 }
예제 #4
0
 /**
  * Execute OAuth2 authentication and return the user.
  */
 static function auth(ProviderInterface $provider)
 {
     if (!require_get("code", false)) {
         redirect($provider->getAuthorizationUrl());
         return false;
     } else {
         // optionally check for abuse etc
         if (!\Openclerk\Events::trigger('oauth2_auth', $provider)) {
             throw new UserAuthenticationException("Login was cancelled by the system.");
         }
         $token = $provider->getAccessToken('authorization_code', array('code' => require_get("code")));
         // now find the relevant user
         return $provider->getUserDetails($token);
     }
 }
예제 #5
0
 function prepare($query)
 {
     if ($this->shouldUseMaster($query)) {
         if ($this->isWriteQuery($query)) {
             // update the session, but only for write queries
             $_SESSION['master_slave_data'][$this->getTable($query)] = time();
         }
         $this->lastConnection = $this->master;
         Events::trigger('db_prepare_master', $query);
         return new ReplicatedQuery($this->master, $query, true);
     } else {
         $this->lastConnection = $this->slave;
         Events::trigger('db_prepare_slave', $query);
         return new ReplicatedQuery($this->slave, $query, false);
     }
 }
예제 #6
0
/**
 * Log an Exception into the {@code uncaught_exceptions} table.
 * If the exception is a {@link TypedException}, or the {@code argument_id} and
 * {@code argument_type} parameters are provided, this argument ID/type will be inserted as well.
 *
 * @param $argument_id optional argument type
 * @param $argmuent_type optional argument id
 */
function log_uncaught_exception($e, $argument_type = null, $argument_id = null)
{
    // check db() is defined
    $db = openclerk_exceptions_check_db($e);
    // events
    Events::trigger('exception_uncaught', $e);
    $extra_args = array();
    $extra_query = "";
    // logging
    if ($argument_id !== null && $argument_type !== null) {
        // unwrap it
        $extra_args[] = $argument_id;
        $extra_args[] = $argument_type;
        $extra_query .= ", argument_id=?, argument_type=?";
    } else {
        if ($e instanceof \Openclerk\TypedException) {
            // unwrap it
            $extra_args[] = $e->getArgumentId();
            $extra_args[] = $e->getArgumentType();
            $extra_query .= ", argument_id=?, argument_type=?";
        }
    }
    if (get_class($e) !== false) {
        $extra_args[] = get_class($e);
        $extra_query .= ", class_name=?";
    }
    $q = $db->prepare("INSERT INTO uncaught_exceptions SET\n    message=?,\n    previous_message=?,\n    filename=?,\n    line_number=?,\n    raw=?,\n    created_at=NOW() {$extra_query}");
    try {
        $serialized = serialize($e);
    } catch (\Exception $e2) {
        if (preg_match("#Serialization of .+ is not allowed#im", $e2->getMessage())) {
            $serialized = serialize($e2->getMessage());
        } else {
            $serialized = serialize($e->getMessage());
        }
    }
    $args = array_merge(array(mb_substr($e->getMessage(), 0, 255), mb_substr($e->getPrevious() ? $e->getPrevious()->getMessage() : "", 0, 255), mb_substr($e->getFile(), 0, 255), $e->getLine(), mb_substr($serialized, 0, 65535)), $extra_args);
    return $q->execute($args);
}
예제 #7
0
파일: User.php 프로젝트: openclerk/users
 /**
  * Delete the given user. Triggers a 'user_deleted' event with the
  * current user as an argument.
  */
 function delete(\Db\Connection $db)
 {
     // delete all possible identities
     $q = $db->prepare("DELETE FROM user_passwords WHERE user_id=?");
     $q->execute(array($this->getId()));
     $q = $db->prepare("DELETE FROM user_openid_identities WHERE user_id=?");
     $q->execute(array($this->getId()));
     $q = $db->prepare("DELETE FROM user_oauth2_identities WHERE user_id=?");
     $q->execute(array($this->getId()));
     $q = $db->prepare("DELETE FROM user_valid_keys WHERE user_id=?");
     $q->execute(array($this->getId()));
     $q = $db->prepare("DELETE FROM users WHERE id=?");
     $q->execute(array($this->getId()));
     \Openclerk\Events::trigger('user_deleted', $this);
 }
예제 #8
0
파일: I18n.php 프로젝트: openclerk/i18n
 static function tWithoutCategory($key = false, $args = array())
 {
     $locale = self::getCurrentLocale();
     // remove any unnecessary whitespace in the key that won't be displayed
     $key = self::stripKey($key);
     if ($locale != 'en' && !isset(self::$global_loaded_locales[$locale])) {
         if (!isset(self::$locales[$locale])) {
             throw new LocaleException("No known locale '{$locale}'");
         }
         $localeInstance = self::$locales[$locale];
         $loaded = $localeInstance->load();
         self::$global_loaded_locales[$locale] = $loaded;
     }
     if (!is_array($args)) {
         throw new LocaleException("Expected array argument");
     }
     foreach ($args as $k => $value) {
         if (is_numeric($k)) {
             throw new LocaleException("Did not expect numeric key '{$k}'");
         }
         if (substr($k, 0, 1) !== ":") {
             throw new LocaleException("Did not expect non-parameterised key '{$k}'");
         }
     }
     // add default arguments (but keep any existing keys used)
     $args += self::$default_keys;
     if (!isset(self::$global_loaded_locales[$locale][$key])) {
         if ($locale != 'en') {
             \Openclerk\Events::trigger('i18n_missing_string', array("locale" => $locale, "key" => $key));
         }
         // if (is_admin() && get_site_config('show_i18n')) {
         //   return "[" . strtr($key, $args) . "]";
         // } else {
         return strtr($key, $args);
         // }
     }
     // if (is_admin() && get_site_config('show_i18n')) {
     //   return "[" . strtr(self::$global_loaded_locales[$locale][$key], $args) . "]";
     // } else {
     return strtr(self::$global_loaded_locales[$locale][$key], $args);
     // }
 }
예제 #9
0
/**
 * Wraps {@link #file_get_contents()} with timeout information etc.
 * May throw a {@link ExternalAPIException} if something unexpected occured.
 */
function crypto_get_contents($url, $options = array())
{
    \Openclerk\Events::trigger('curl_start', $url);
    // normally file_get_contents is OK, but if URLs are down etc, the timeout has no value and we can just stall here forever
    // this also means we don't have to enable OpenSSL on windows for file_get_contents('https://...'), which is just a bit of a mess
    $ch = crypto_curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; Openclerk PHP client; ' . php_uname('s') . '; PHP/' . phpversion() . ')');
    curl_setopt($ch, CURLOPT_URL, $url);
    // curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
    // enable gzip decompression if necessary
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    foreach ($options as $key => $value) {
        curl_setopt($ch, $key, $value);
    }
    // run the query
    $res = curl_exec($ch);
    \Openclerk\Events::trigger('curl_end', $url);
    if ($res === false) {
        throw new ExternalAPIException('Could not get reply: ' . curl_error($ch));
    }
    crypto_check_response($res);
    return $res;
}
예제 #10
0
 /**
  * Try do OpenID validation (with the given redirect).
  * @return the validated LightOpenID object on success
  * @throws UserSignupException if anything bad happened
  */
 static function validateOpenID($openid, $redirect)
 {
     if (!is_valid_url($openid)) {
         throw new UserSignupException("That is not a valid OpenID identity.");
     }
     if (!$redirect) {
         throw new \InvalidArgumentException("No redirect provided.");
     }
     $light = new \LightOpenID(\Openclerk\Config::get("openid_host"));
     if (!$light->mode) {
         // we still need to authenticate
         $light->identity = $openid;
         $light->returnUrl = $redirect;
         redirect($light->authUrl());
         return false;
     } else {
         if ($light->mode == 'cancel') {
             // user has cancelled
             throw new UserSignupException("User has cancelled authentication.");
         } else {
             // otherwise login as necessary
             // optionally check for abuse etc
             if (!\Openclerk\Events::trigger('openid_validate', $light)) {
                 throw new UserSignupException("Login was cancelled by the system.");
             }
             if ($light->validate()) {
                 return $light;
             } else {
                 $error = $light->validate_error ? $light->validate_error : "Please try again.";
                 throw new UserSignupException("OpenID validation was not successful: " . $error);
             }
         }
     }
 }
예제 #11
0
 /**
  * Render the given template.
  *
  * Searches for templates within each template directory, with the following
  * search order: {@code .php}, {@code .haml.php}, {@code .haml}.
  */
 static function requireTemplate($template, $arguments = array())
 {
     if (!is_array($arguments)) {
         throw new \InvalidArgumentException("Arguments '{$arguments}' need to be an array, not " . gettype($arguments));
     }
     Events::trigger('pages_template_start', $arguments + array('template' => $template));
     // so sub-templates can access all parent arguments
     if (self::$argument_stack) {
         $arguments += self::$argument_stack[count(self::$argument_stack) - 1];
     }
     // add to argument stack
     array_push(self::$argument_stack, $arguments);
     foreach (self::$templates as $dir) {
         // either include templates as direct PHP files...
         $file = $dir . "/" . $template . ".php";
         if (file_exists($file)) {
             // create locally scoped variables for all arguments
             foreach ($arguments as $key => $value) {
                 ${$key} = $value;
             }
             require $file;
             Events::trigger('pages_template_end', $arguments + array('template' => $template, 'filetype' => 'php'));
             // and then remove from argument stack
             array_pop(self::$argument_stack);
             return;
         }
         // ... or as HAML templates
         foreach (array($dir . "/" . $template . ".php.haml", $dir . "/" . $template . ".haml") as $file) {
             if (file_exists($file)) {
                 if (self::$executor === null) {
                     $haml = new \MtHaml\Environment('php', self::$haml_options);
                     self::$executor = new \MtHaml\Support\Php\Executor($haml, array('cache' => sys_get_temp_dir() . '/haml'));
                 }
                 // Compiles and executes the HAML template, with variables given as second argument
                 self::$executor->display($file, $arguments);
                 Events::trigger('pages_template_end', $arguments + array('template' => $template, 'filetype' => 'haml'));
                 // and then remove from argument stack
                 array_pop(self::$argument_stack);
                 return;
             }
         }
     }
     throw new TemplateNotFoundException("Could not find template '{$template}'", new TemplateNotFoundException("No template '{$template}' found in [" . implode(", ", self::$templates) . "]"));
 }