]> 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 a78a27f4a2b35e3e490d991b56e12b0f1c79d322..494c697e425fab0fa9726cba9bf0aac41635e2ff 100644 (file)
@@ -37,11 +37,17 @@ class Profile extends Memcached_DataObject
     public $homepage;                        // varchar(255)  multiple_key
     public $bio;                             // text()  multiple_key
     public $location;                        // varchar(255)  multiple_key
+    public $lat;                             // decimal(10,7)
+    public $lon;                             // decimal(10,7)
+    public $location_id;                     // int(4)
+    public $location_ns;                     // int(4)
     public $created;                         // datetime()   not_null
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile',$k,$v); }
+    function staticGet($k,$v=NULL) {
+        return Memcached_DataObject::staticGet('Profile',$k,$v);
+    }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
@@ -304,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();
@@ -327,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 {
@@ -335,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()
@@ -494,6 +529,7 @@ class Profile extends Memcached_DataObject
                          'Reply',
                          'Group_member',
                          );
+        Event::handle('ProfileDeleteRelated', array($this, &$related));
 
         foreach ($related as $cls) {
             $inst = new $cls();
@@ -556,4 +592,280 @@ class Profile extends Memcached_DataObject
         $block->blocked = $this->id;
         $block->delete();
     }
+
+    // XXX: identical to Notice::getLocation.
+
+    function getLocation()
+    {
+        $location = null;
+
+        if (!empty($this->location_id) && !empty($this->location_ns)) {
+            $location = Location::fromId($this->location_id, $this->location_ns);
+        }
+
+        if (is_null($location)) { // no ID, or Location::fromId() failed
+            if (!empty($this->lat) && !empty($this->lon)) {
+                $location = Location::fromLatLon($this->lat, $this->lon);
+            }
+        }
+
+        if (is_null($location)) { // still haven't found it!
+            if (!empty($this->location)) {
+                $location = Location::fromName($this->location);
+            }
+        }
+
+        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;
+    }
+
 }