]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - classes/Profile.php
Merge branch 'master' into testing
[quix0rs-gnu-social.git] / classes / Profile.php
index a50f4951de3abd2701702440f4035951ee4351fc..494c697e425fab0fa9726cba9bf0aac41635e2ff 100644 (file)
@@ -101,7 +101,7 @@ class Profile extends Memcached_DataObject
         }
 
         foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
-            # We do not do a scaled one if original is our scaled size
+            # We don't do a scaled one if original is our scaled size
             if (!($avatar->width == $size && $avatar->height == $size)) {
 
                 $scaled_filename = $imagefile->resize($size);
@@ -174,7 +174,7 @@ class Profile extends Memcached_DataObject
 
     function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
     {
-        // XXX: I'm not sure this is going to be any faster. It probably is not.
+        // XXX: I'm not sure this is going to be any faster. It probably isn't.
         $ids = Notice::stream(array($this, '_streamDirect'),
                               array(),
                               'profile:notice_ids:' . $this->id,
@@ -310,10 +310,12 @@ class Profile extends Memcached_DataObject
           'AND subscription.subscribed != subscription.subscriber ' .
           'ORDER BY subscription.created DESC ';
 
-        if (common_config('db','type') == 'pgsql') {
-            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-        } else {
-            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+        if ($offset>0 && !is_null($limit)){
+            if (common_config('db','type') == 'pgsql') {
+                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+            } else {
+                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+            }
         }
 
         $profile = new Profile();
@@ -333,7 +335,34 @@ class Profile extends Memcached_DataObject
           'AND subscription.subscribed != subscription.subscriber ' .
           'ORDER BY subscription.created DESC ';
 
-        if ($offset) {
+        if ($offset>0 && !is_null($limit)){
+            if ($offset) {
+                if (common_config('db','type') == 'pgsql') {
+                    $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+                } else {
+                    $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+                }
+            }
+        }
+
+        $profile = new Profile();
+
+        $cnt = $profile->query(sprintf($qry, $this->id));
+
+        return $profile;
+    }
+
+    function getApplications($offset = 0, $limit = null)
+    {
+        $qry =
+          'SELECT a.* ' .
+          'FROM oauth_application_user u, oauth_application a ' .
+          'WHERE u.profile_id = %d ' .
+          'AND a.id = u.application_id ' .
+          'AND u.access_type > 0 ' .
+          'ORDER BY u.created DESC ';
+
+        if ($offset > 0) {
             if (common_config('db','type') == 'pgsql') {
                 $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
             } else {
@@ -341,11 +370,11 @@ class Profile extends Memcached_DataObject
             }
         }
 
-        $profile = new Profile();
+        $application = new Oauth_application();
 
-        $cnt = $profile->query(sprintf($qry, $this->id));
+        $cnt = $application->query(sprintf($qry, $this->id));
 
-        return $profile;
+        return $application;
     }
 
     function subscriptionCount()
@@ -500,6 +529,7 @@ class Profile extends Memcached_DataObject
                          'Reply',
                          'Group_member',
                          );
+        Event::handle('ProfileDeleteRelated', array($this, &$related));
 
         foreach ($related as $cls) {
             $inst = new $cls();
@@ -587,4 +617,255 @@ class Profile extends Memcached_DataObject
 
         return $location;
     }
+
+    function hasRole($name)
+    {
+        $has_role = false;
+        if (Event::handle('StartHasRole', array($this, $name, &$has_role))) {
+            $role = Profile_role::pkeyGet(array('profile_id' => $this->id,
+                                                'role' => $name));
+            $has_role = !empty($role);
+            Event::handle('EndHasRole', array($this, $name, $has_role));
+        }
+        return $has_role;
+    }
+
+    function grantRole($name)
+    {
+        $role = new Profile_role();
+
+        $role->profile_id = $this->id;
+        $role->role       = $name;
+        $role->created    = common_sql_now();
+
+        $result = $role->insert();
+
+        if (!$result) {
+            common_log_db_error($role, 'INSERT', __FILE__);
+            return false;
+        }
+
+        return true;
+    }
+
+    function revokeRole($name)
+    {
+        $role = Profile_role::pkeyGet(array('profile_id' => $this->id,
+                                            'role' => $name));
+
+        if (empty($role)) {
+            throw new Exception('Cannot revoke role "'.$name.'" for user #'.$this->id.'; does not exist.');
+        }
+
+        $result = $role->delete();
+
+        if (!$result) {
+            common_log_db_error($role, 'DELETE', __FILE__);
+            throw new Exception('Cannot revoke role "'.$name.'" for user #'.$this->id.'; database error.');
+        }
+
+        return true;
+    }
+
+    function isSandboxed()
+    {
+        return $this->hasRole(Profile_role::SANDBOXED);
+    }
+
+    function isSilenced()
+    {
+        return $this->hasRole(Profile_role::SILENCED);
+    }
+
+    function sandbox()
+    {
+        $this->grantRole(Profile_role::SANDBOXED);
+    }
+
+    function unsandbox()
+    {
+        $this->revokeRole(Profile_role::SANDBOXED);
+    }
+
+    function silence()
+    {
+        $this->grantRole(Profile_role::SILENCED);
+    }
+
+    function unsilence()
+    {
+        $this->revokeRole(Profile_role::SILENCED);
+    }
+
+    /**
+     * Does this user have the right to do X?
+     *
+     * With our role-based authorization, this is merely a lookup for whether the user
+     * has a particular role. The implementation currently uses a switch statement
+     * to determine if the user has the pre-defined role to exercise the right. Future
+     * implementations may allow per-site roles, and different mappings of roles to rights.
+     *
+     * @param $right string Name of the right, usually a constant in class Right
+     * @return boolean whether the user has the right in question
+     */
+
+    function hasRight($right)
+    {
+        $result = false;
+        if (Event::handle('UserRightsCheck', array($this, $right, &$result))) {
+            switch ($right)
+            {
+            case Right::DELETEOTHERSNOTICE:
+            case Right::MAKEGROUPADMIN:
+            case Right::SANDBOXUSER:
+            case Right::SILENCEUSER:
+            case Right::DELETEUSER:
+                $result = $this->hasRole(Profile_role::MODERATOR);
+                break;
+            case Right::CONFIGURESITE:
+                $result = $this->hasRole(Profile_role::ADMINISTRATOR);
+                break;
+            case Right::NEWNOTICE:
+            case Right::NEWMESSAGE:
+            case Right::SUBSCRIBE:
+                $result = !$this->isSilenced();
+                break;
+            case Right::PUBLICNOTICE:
+            case Right::EMAILONREPLY:
+            case Right::EMAILONSUBSCRIBE:
+            case Right::EMAILONFAVE:
+                $result = !$this->isSandboxed();
+                break;
+            default:
+                $result = false;
+                break;
+            }
+        }
+        return $result;
+    }
+
+    function hasRepeated($notice_id)
+    {
+        // XXX: not really a pkey, but should work
+
+        $notice = Memcached_DataObject::pkeyGet('Notice',
+                                                array('profile_id' => $this->id,
+                                                      'repeat_of' => $notice_id));
+
+        return !empty($notice);
+    }
+
+    /**
+     * Returns an XML string fragment with limited profile information
+     * as an Atom <author> element.
+     *
+     * Assumes that Atom has been previously set up as the base namespace.
+     *
+     * @return string
+     */
+    function asAtomAuthor()
+    {
+        $xs = new XMLStringer(true);
+
+        $xs->elementStart('author');
+        $xs->element('name', null, $this->nickname);
+        $xs->element('uri', null, $this->getUri());
+        $xs->elementEnd('author');
+
+        return $xs->getString();
+    }
+
+    /**
+     * Returns an XML string fragment with profile information as an
+     * Activity Streams <activity:actor> element.
+     *
+     * Assumes that 'activity' namespace has been previously defined.
+     *
+     * @return string
+     */
+    function asActivityActor()
+    {
+        return $this->asActivityNoun('actor');
+    }
+
+    /**
+     * Returns an XML string fragment with profile information as an
+     * Activity Streams noun object with the given element type.
+     *
+     * Assumes that 'activity' namespace has been previously defined.
+     *
+     * @param string $element one of 'actor', 'subject', 'object', 'target'
+     * @return string
+     */
+    function asActivityNoun($element)
+    {
+        $xs = new XMLStringer(true);
+
+        $xs->elementStart('activity:' . $element);
+        $xs->element(
+            'activity:object-type',
+            null,
+            'http://activitystrea.ms/schema/1.0/person'
+        );
+        $xs->element(
+            'id',
+            null,
+            $this->getUri()
+            );
+        $xs->element('title', null, $this->getBestName());
+
+        $avatar = $this->getAvatar(AVATAR_PROFILE_SIZE);
+
+        $xs->element(
+            'link', array(
+                'type' => empty($avatar) ? 'image/png' : $avatar->mediatype,
+                'rel'  => 'avatar',
+                'href' => empty($avatar)
+                ? Avatar::defaultImage(AVATAR_PROFILE_SIZE)
+                : $avatar->displayUrl()
+            ),
+            ''
+        );
+
+        $xs->elementEnd('activity:' . $element);
+
+        return $xs->getString();
+    }
+
+    /**
+     * Returns the best URI for a profile. Plugins may override.
+     *
+     * @return string $uri
+     */
+    function getUri()
+    {
+        $uri = null;
+
+        // check for a local user first
+        $user = User::staticGet('id', $this->id);
+
+        if (!empty($user)) {
+            $uri = common_local_url(
+                'userbyid',
+                array('id' => $user->id)
+            );
+        } else {
+
+            // give plugins a chance to set the URI
+            if (Event::handle('StartGetProfileUri', array($this, &$uri))) {
+
+                // return OMB profile if any
+                $remote = Remote_profile::staticGet('id', $this->id);
+
+                if (!empty($remote)) {
+                    $uri = $remote->uri;
+                }
+
+                Event::handle('EndGetProfileUri', array($this, &$uri));
+            }
+        }
+
+        return $uri;
+    }
+
 }