/**
  * Send an email notification to a user
  * 
  * @static
  * @since 1.1.0
  * @param string $user_id User object_id
  * @param string $subject Email subject line
  * @param string $message Email body
  */
 public static function notify_user($user_id, $subject, $message, $short_text = null)
 {
     $error = new argent_error();
     if (!class_exists('PHPMailer')) {
         $error->add('1042', 'PHPMailer is not available', NULL, 'argent_notification');
     }
     if ($error->has_errors()) {
         return $error;
     }
     $mail = new PHPMailer();
     $mail->AddReplyTo(NOTIFICATION_FROM_MAIL, NOTIFICATION_FROM_NAME);
     $mail->SetFrom(NOTIFICATION_FROM_MAIL, NOTIFICATION_FROM_NAME);
     $user_data = argent_uauth::user_get_data($user_id);
     if (argent_error::check($user_data)) {
         return $user_data;
     }
     $mail->AddAddress($user_data['email'], $user_data['display_name']);
     $mail->Subject = $subject;
     $mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
     // optional, comment out and test
     $merge_fields = array('user_name' => $user_data['display_name'], 'email' => $user_data['email'], 'body' => $message, 'subject' => $subject, 'intro' => $short_text);
     $message_body = self::merge_template(ABSOLUTE_PATH . 'argent/html_email_templates/basic.html', $merge_fields);
     if (argent_error::check($message_body)) {
         return $message_body;
     }
     $mail->MsgHTML($message_body);
     if (!$mail->Send()) {
         $error->add('1040', 'Error sending mail', $mail->ErrorInfo, 'argent_notification');
         return $error;
     } else {
         return 'Mail sent to ' . $user_data['email'];
     }
 }
 /**
  * Log an error
  * 
  * @static
  * @since 1.0.1
  * @param string $code Error code
  * @param string $message Error message
  * @param string $payload Data related to or causing the error
  * @param string $application The name of your module e.g. "Search API"
  * @return boolean 
  */
 public static function log_error($code, $message = "", $payload = NULL, $application = 'argent_powered_app')
 {
     if (argent_error::check($code)) {
         if ($code->has_errors()) {
             $errors = $code->read();
             if (!empty($errors)) {
                 foreach ($errors as $code => $error) {
                     $message = $error['message'];
                     $payload = $error['data'];
                     /* Timestamp */
                     $errmsg = date('Y-m-d H:i:s');
                     /* Process */
                     $errmsg .= "\t[{$application}]\t";
                     /* IP */
                     $errmsg .= $_SERVER['REMOTE_ADDR'] . "\t";
                     /* UA */
                     $errmsg .= $_SERVER['HTTP_USER_AGENT'] . "\t";
                     /* Error Code */
                     $errmsg .= $code . "\t";
                     /* Error Message */
                     $errmsg .= $message . "\t";
                     /* Error PayLoad */
                     $errmsg .= "\t" . $payload;
                     self::write_to_log("error", $errmsg);
                     return true;
                 }
             }
         }
         return false;
     }
     /* Timestamp */
     $errmsg = date('Y-m-d H:i:s');
     /* Process */
     $errmsg .= "\t[{$application}]\t";
     /* IP */
     $errmsg .= $_SERVER['REMOTE_ADDR'] . "\t";
     /* UA */
     $errmsg .= $_SERVER['HTTP_USER_AGENT'] . "\t";
     /* Error Code */
     $errmsg .= $code . "\t";
     /* Error Message */
     $errmsg .= $message . "\t";
     /* Error PayLoad */
     $errmsg .= "\t" . (string) $payload;
     self::write_to_log("error", $errmsg);
     return true;
 }
 /**
  * Returns true if the given user has the specified User Right
  * 
  * @param string $right
  * @param string $user_id
  * @return boolean
  */
 public static function user_has_right($right, $user_id = null)
 {
     $error = new argent_error();
     if ($user_id == null) {
         $user_id = self::session_user();
     }
     if (!self::object_exists($user_id)) {
         $error->add('1013', 'Invalid user account', $user_id, 'argent_uauth');
     }
     $right_id = self::right_exists($right);
     if (!$right_id) {
         $error->add('1042', 'Invalid user right', $right, 'argent_uauth');
     }
     $user_right = argent_meta::related($user_id, $right_id, 'user_right');
     if ($user_right == false || argent_error::check($user_right)) {
         return false;
     }
     return true;
 }
 /**
  * Break a defined relationship relationship between two objects
  * 
  * @param string $primary_object_id
  * @param string $secondary_object_id
  * @param string $relationship
  * @return array|\argent_error
  */
 public static function unrelate($primary_object_id, $secondary_object_id, $relationship, $include_reverse = false)
 {
     $error = new argent_error();
     $db = new argent_database();
     $related = self::related($primary_object_id, $secondary_object_id, $relationship, $include_reverse);
     if (argent_error::check($related)) {
         return $related;
     }
     if (!$related) {
         return $related;
     }
     $sql = "\r\n                    DELETE FROM\r\n                        `ua_relationships`\r\n                    WHERE\r\n                        (`primary_object_id` = '{$db->escape_value($primary_object_id)}'\r\n                    AND\r\n                        `secondary_object_id` = '{$db->escape_value($secondary_object_id)}' )\r\n                    ";
     if ($include_reverse) {
         $sql .= "\r\n                    OR\r\n                        (`primary_object_id` = '{$db->escape_value($secondary_object_id)}'\r\n                    AND\r\n                        `secondary_object_id` = '{$db->escape_value($primary_object_id)}' )\r\n                    ";
     }
     $sql .= "\r\n                    AND\r\n                        `relationship` = '{$db->escape_value($relationship)}'\r\n                    ";
     $db->query($sql);
     return true;
 }