/**
  * Set one or more permissions for a user on an object
  * 
  * @param array $permissions
  * @param string $object_id
  * @param string $user_id
  * @param boolean $cascade_down
  */
 public static function set_permissions($permissions, $object_id, $user_id, $cascade_down = true)
 {
     $error = new argent_error();
     if (is_array($permissions) && count($permissions) > 0) {
         foreach ($permissions as $permission => $setting) {
             $permission = strtolower($permission);
             if ($permission != AG_PERMISSION_CREATE && $permission != AG_PERMISSION_READ && $permission != AG_PERMISSION_UPDATE && $permission != AG_PERMISSION_DELETE && $setting != 0 && $setting != 1) {
                 $error->add('2020', 'Invalid permission setting', $permission, 'argent_uauth');
             }
         }
     } else {
         $error->add('2020', 'Invalid permission setting', $permission, 'argent_uauth');
     }
     if (!argent_meta::object_registered($object_id)) {
         $error->add('1038', 'Object does not exist', $object_id, 'argent_uauth');
     }
     if (!self::object_exists($user_id)) {
         $error->add('1013', 'Invalid user account', $user_id, 'argent_uauth');
     }
     if ($error->has_errors()) {
         return $error;
     }
     $perms = self::get_permission_record($object_id, $user_id);
     if (argent_error::check($perms)) {
         return $perms;
     } elseif ($perms == false) {
         $perms = array();
         $perms['object_id'] = $object_id;
         $perms['user_id'] = $user_id;
     }
     $old_record = $perms['meta_guid'];
     $perms = array_merge($perms, $permissions);
     if ($cascade_down == true) {
         $perms['cascade'] = 1;
     } else {
         $perms['cascade'] = 0;
     }
     $perms = argent_meta::add_meta($perms);
     $db = new argent_database();
     $db->start_transaction();
     $save = argent_meta::save_record($perms, 'ua_permissions');
     if (argent_error::check($save)) {
         return $save;
     }
     if (!empty($old_record)) {
         $sql = "\r\n                    DELETE FROM\r\n                        `ua_permissions`\r\n                    WHERE\r\n                        `meta_guid` = '{$db->escape_value($old_record)}'\r\n                    ";
         return $db->query($sql);
     }
     self::cascade_permissions();
     $db->end_transaction();
     return true;
 }
 /**
  * Creates a head view for a given table name, after dropping any
  * existing head view as part of a transaction
  * 
  * @since 1.0.1
  * @param string $table_name 
  * @return true
  */
 public static function create_head_view($table_name)
 {
     $db = new argent_database();
     $db->start_transaction();
     $sql = "\r\n                        DROP VIEW IF EXISTS\r\n                            `{$table_name}_head`\r\n                        ";
     $db->query($sql);
     $sql = "\r\n                        CREATE VIEW \r\n                            `{$table_name}_head` \r\n                        AS \r\n                            SELECT \r\n                                `{$table_name}`.* \r\n                            FROM\r\n                                `{$table_name}` \r\n                            WHERE \r\n                                `{$table_name}`.`meta_guid` \r\n                            IN\r\n                                (SELECT max(`{$table_name}`.`meta_guid`) \r\n                                AS `max(meta_guid)` from `{$table_name}` group by `{$table_name}`.`object_id`)\r\n                        ";
     $db->query($sql);
     $db->end_transaction();
     return true;
 }