├── MIT-LICENSE.txt ├── README ├── api ├── README ├── getencircled.php ├── getplusperson.php ├── getplusposts.php └── getvisgraph.php ├── assets ├── css │ └── README ├── images │ └── README ├── js │ └── README └── uploads │ └── README ├── includes ├── README ├── common.inc ├── config.inc.editme ├── database.inc ├── standard_daemon_logic.inc └── standard_page_logic.inc ├── lib ├── GooglePlus │ ├── GoogleUtil.php │ ├── PlusPerson.php │ ├── PlusPost.php │ ├── PlusRelationship.php │ └── PostAttachment.php └── README ├── sql ├── README ├── plusperson.sql ├── pluspost.sql └── plusrelationship.sql ├── templates ├── pages │ ├── README │ ├── example.inc │ └── tests │ │ ├── plusactivity.inc │ │ └── plususer.inc └── shared │ ├── README │ ├── footer.inc │ └── header.inc └── tests ├── examplefollowerdata.html ├── exampleprofiledata.html ├── plusactivity.php └── plususer.php /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Jason M. Striegel (@jmstriegel) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | An unofficial Google Plus API. Right now this consists of the following: 2 | 3 | PHP Classes 4 | ----------- 5 | GoogleUtil - functions for parsing the almost-JSON that Google Plus produces 6 | PlusPerson - a person entity in Gooogle plus that can be stored to a local mysql DB 7 | PlusRelationship - a relationship between people in Google plus. This does not contain any circle context 8 | PlusPost - a post to a user's activty stream 9 | PostAttachment - encapsulates a media attachment to a post 10 | 11 | 12 | Tests 13 | ----------- 14 | tests/plususer.php?plusid=xxxxxxxx - demonstrates loading and caching users, as well as traversing the social graph 15 | tests/plusactivity.php?plusid=xxxxxxx - demonstrates loading and caching public posts from a user's activity stream 16 | 17 | 18 | API 19 | ----------- 20 | api/getplusperson.php?plusid=xxx - JSON(P) API for retrieving profile data for a person. 21 | api/getplusposts.php?plusid=xxx - JSON(P) API for retrieving post activty for a person. 22 | 23 | 24 | Installation 25 | ------------ 26 | 1. Copy includes/config.inc.editme to /includes/config.inc 27 | 2. Edit config.inc with your path, url and mysql information 28 | 3. Import the sql tables in the sql/ subdirectory 29 | 30 | 31 | TODO 32 | ----------- 33 | 34 | - create getters for the rest of the data fields into the PlusPerson and PlusPosts objects 35 | - do something interesting with all of this 36 | 37 | -------------------------------------------------------------------------------- /api/README: -------------------------------------------------------------------------------- 1 | Place any json/xml services here. Having these in a subdirectory helps keep 2 | things organized, and makes it easy to handle url mapping and permissions 3 | if you need to handle api calls differently than main pages. 4 | -------------------------------------------------------------------------------- /api/getencircled.php: -------------------------------------------------------------------------------- 1 | googleplus_id ); 60 | foreach ( $followees as $followee ) { 61 | $pdata = extractPersonData( $followee, 1 ); 62 | if ( !isset( $plookup[$pdata['id']] ) ) { 63 | $people[] = $pdata; 64 | $plookup[ $pdata['id'] ] = 1; 65 | } 66 | } 67 | 68 | 69 | 70 | $data = array( 71 | 'person' => extractPersonData( $person, 0 ), 72 | 'relationships' => $people 73 | ); 74 | 75 | $responsedata = json_encode( $data ); 76 | 77 | //wrap jsonp if necessary 78 | if ( $template['callback'] != "" && preg_match( '/^\w+$/', $template['callback'] ) ) { 79 | $responsedata = $template['callback'] . '(' . $responsedata . ');'; 80 | } 81 | 82 | echo $responsedata; 83 | } 84 | 85 | function extractPersonData( $person, $group ) { 86 | $result = array(); 87 | $result['id'] = $person->googleplus_id; 88 | $result['name'] = $person->first_name . " " . $person->last_name; 89 | $result['group'] = $group; 90 | 91 | return $result; 92 | } 93 | 94 | 95 | function getCachedPerson( $pid ) { 96 | $person = new PlusPerson(); 97 | $person->loadByGooglePlusID( $pid ); 98 | 99 | if ( $person->plusperson_id == 0 ) { 100 | $person->googleplus_id = $pid; 101 | $person->updateFromGooglePlusService(); 102 | $person->insertIntoDB(); 103 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 104 | $person->updateFromGooglePlusService(); 105 | $person->fetched_relationships = 0; 106 | $person->updateDB(); 107 | } 108 | 109 | return $person; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /api/getplusperson.php: -------------------------------------------------------------------------------- 1 | loadByGooglePlusID( $pid ); 47 | 48 | if ( $person->plusperson_id == 0 ) { 49 | $person->googleplus_id = $pid; 50 | $person->updateFromGooglePlusService(); 51 | $person->insertIntoDB(); 52 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 53 | $person->updateFromGooglePlusService(); 54 | $person->fetched_relationships = 0; 55 | $person->updateDB(); 56 | } 57 | 58 | 59 | $data = array( 60 | 'googleplus_id' => $person->googleplus_id, 61 | 'first_name' => $person->first_name, 62 | 'last_name' => $person->last_name, 63 | 'profile_photo' => $person->profile_photo, 64 | 'introduction' => $person->introduction, 65 | 'subhead' => $person->subhead 66 | ); 67 | 68 | $responsedata = json_encode( $data ); 69 | 70 | //wrap jsonp if necessary 71 | if ( $template['callback'] != "" && preg_match( '/^\w+$/', $template['callback'] ) ) { 72 | $responsedata = $template['callback'] . '(' . $responsedata . ');'; 73 | } 74 | 75 | echo $responsedata; 76 | } 77 | -------------------------------------------------------------------------------- /api/getplusposts.php: -------------------------------------------------------------------------------- 1 | loadByGooglePlusID( $pid ); 47 | 48 | if ( $person->plusperson_id == 0 ) { 49 | $person->googleplus_id = $pid; 50 | $person->updateFromGooglePlusService(); 51 | $person->insertIntoDB(); 52 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 53 | $person->updateFromGooglePlusService(); 54 | $person->fetched_relationships = 0; 55 | $person->updateDB(); 56 | } 57 | 58 | //Get the posts from G+ 59 | $posts = PlusPost::FetchActivityStream( $person->googleplus_id ); 60 | 61 | //Save them all into the DB (merge will try to update them if they exist already) 62 | foreach ( $posts as $post ) { 63 | $post->mergeStreamPostIntoDB(); 64 | } 65 | 66 | 67 | $postsdata = array(); 68 | foreach ( $posts as $post ) { 69 | $data = array( 70 | 'googleplus_postid' => $post->googleplus_postid, 71 | 'author_id' => $post->author_id, 72 | 'post_data' => $post->post_data, 73 | 'share_content' => $post->share_content, 74 | 'shared_postid' => $post->shared_postid 75 | ); 76 | $postsdata[] = $data; 77 | } 78 | 79 | $persondata = array( 80 | 'googleplus_id' => $person->googleplus_id, 81 | 'first_name' => $person->first_name, 82 | 'last_name' => $person->last_name, 83 | 'profile_photo' => $person->profile_photo, 84 | 'introduction' => $person->introduction, 85 | 'subhead' => $person->subhead 86 | ); 87 | 88 | $data = array( 89 | 'plusperson' => $persondata, 90 | 'posts' => $postsdata 91 | ); 92 | 93 | $responsedata = json_encode( $data ); 94 | 95 | //wrap jsonp if necessary 96 | if ( $template['callback'] != "" && preg_match( '/^\w+$/', $template['callback'] ) ) { 97 | $responsedata = $template['callback'] . '(' . $responsedata . ');'; 98 | } 99 | 100 | echo $responsedata; 101 | } 102 | -------------------------------------------------------------------------------- /api/getvisgraph.php: -------------------------------------------------------------------------------- 1 | fetched_relationships != 1 ) { 82 | 83 | $rels = PlusPerson::FetchVisiblePlusPeople( $cp->googleplus_id ); 84 | 85 | } else { 86 | 87 | $or = PlusRelationship::FetchRelationshipsByOwner( $cp->googleplus_id ); 88 | 89 | foreach ( $or as $r ) { 90 | $p = new PlusPerson(); 91 | $p->googleplus_id = $r->hasincircle_id; 92 | 93 | $rels[] = $p; 94 | } 95 | } 96 | 97 | 98 | foreach ( $rels as $rel ) { 99 | $link = array(); 100 | $link['from'] = $cp->googleplus_id; 101 | $link['to'] = $rel->googleplus_id; 102 | $link['weight'] = 1; 103 | 104 | 105 | //only add the links if they link back to someone we know 106 | //and only add them once per connection pair 107 | if ( isset( $plookup[ $rel->googleplus_id ] ) ) { 108 | 109 | /* if ( !isset( $linklookup[ $link['from'] . "-" . $link['to'] ] ) && 110 | !isset( $linklookup[ $link['to'] . "-" . $link['from'] ] ) ) { 111 | 112 | $linklookup[ $link['from'] . "-" . $link['to'] ] = count( $links ); 113 | $links[] = $link; 114 | } else { 115 | if ( isset( $linklookup[ $link['from'] . "-" . $link['to'] ] )) { 116 | $links[ $linklookup[ $link['from'] . "-" . $link['to'] ] ]['weight'] += 1; 117 | } else { 118 | $links[ $linklookup[ $link['to'] . "-" . $link['from']] ]['weight'] += 1; 119 | } 120 | } 121 | */ 122 | 123 | if ( !isset( $linklookup[ $link['from'] . "-" . $link['to'] ] ) ) { 124 | $linklookup[ $link['from'] . "-" . $link['to'] ] = count( $links ); 125 | $links[] = $link; 126 | } 127 | if ( isset( $linklookup[ $link['to'] . "-" . $link['from'] ] )) { 128 | $links[ $linklookup[ $link['from'] . "-" . $link['to'] ]]['weight'] += 1; 129 | $links[ $linklookup[ $link['to'] . "-" . $link['from'] ]]['weight'] += 1; 130 | } 131 | 132 | } 133 | } 134 | } 135 | 136 | 137 | //lets filter out only the bidirectional links 138 | $bilinks = array(); 139 | foreach( $links as $link ) { 140 | if ( $link['weight'] > 1 ) { 141 | $bilinks[] = $link; 142 | } 143 | } 144 | 145 | 146 | $data = array( 147 | 'people' => $people, 148 | 'relationships' => $links 149 | ); 150 | 151 | $responsedata = json_encode( $data ); 152 | 153 | //wrap jsonp if necessary 154 | if ( $template['callback'] != "" && preg_match( '/^\w+$/', $template['callback'] ) ) { 155 | $responsedata = $template['callback'] . '(' . $responsedata . ');'; 156 | } 157 | 158 | echo $responsedata; 159 | } 160 | 161 | function extractPersonData( $person, $group ) { 162 | $result = array(); 163 | $result['id'] = $person->googleplus_id; 164 | $result['name'] = $person->first_name . " " . $person->last_name; 165 | $result['group'] = $group; 166 | 167 | return $result; 168 | } 169 | 170 | 171 | function getCachedPerson( $pid ) { 172 | $person = new PlusPerson(); 173 | $person->loadByGooglePlusID( $pid ); 174 | 175 | if ( $person->plusperson_id == 0 ) { 176 | $person->googleplus_id = $pid; 177 | $person->updateFromGooglePlusService(); 178 | $person->insertIntoDB(); 179 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 180 | $person->updateFromGooglePlusService(); 181 | $person->fetched_relationships = 0; 182 | $person->updateDB(); 183 | } 184 | 185 | return $person; 186 | } 187 | 188 | function getCachedCircled( $person ) { 189 | 190 | $circled = array(); 191 | 192 | if ( $person->fetched_relationships != 1 ) { 193 | 194 | $followees = PlusPerson::FetchVisiblePlusPeople( $person->googleplus_id ); 195 | 196 | $or = PlusRelationship::FetchRelationshipsByOwner( $person->googleplus_id ); 197 | foreach ( $or as $r ) { 198 | $r->deleteFromDB(); 199 | } 200 | 201 | foreach( $followees as $fp ) { 202 | $pid = $fp->googleplus_id; 203 | $followee = getCachedPerson( $pid ); 204 | 205 | $circled[] = $followee; 206 | 207 | $rel = new PlusRelationship(); 208 | $rel->owner_id = $person->googleplus_id; 209 | $rel->hasincircle_id = $followee->googleplus_id; 210 | $rel->insertIntoDB(); 211 | 212 | } 213 | 214 | $person->fetched_relationships = 1; 215 | $person->updateDB(); 216 | 217 | } else { 218 | 219 | $or = PlusRelationship::FetchRelationshipsByOwner( $person->googleplus_id ); 220 | 221 | foreach ( $or as $r ) { 222 | $p = new PlusPerson(); 223 | $p->loadByGooglePlusID( $r->hasincircle_id ); 224 | if ( $p->plusperson_id <= 0 ) { 225 | $p->googleplus_id = $r->hasincircle_id; 226 | } 227 | $circled[] = $p; 228 | } 229 | 230 | } 231 | 232 | return $circled; 233 | } 234 | 235 | -------------------------------------------------------------------------------- /assets/css/README: -------------------------------------------------------------------------------- 1 | All css files go here. 2 | -------------------------------------------------------------------------------- /assets/images/README: -------------------------------------------------------------------------------- 1 | Any site images go here. 2 | -------------------------------------------------------------------------------- /assets/js/README: -------------------------------------------------------------------------------- 1 | All javascript files go here. 2 | -------------------------------------------------------------------------------- /assets/uploads/README: -------------------------------------------------------------------------------- 1 | If your site receives user uploaded files that are available for http access, 2 | place them here. Use .htaccess to ensure proper directory and security 3 | permissions. Make sure users cannot upload files with an executable (.php) 4 | extension or they'll be able to run arbitrary code on your server. 5 | -------------------------------------------------------------------------------- /includes/README: -------------------------------------------------------------------------------- 1 | Any config information, common page logic procedures, and utility functions 2 | should go here. Keep things reasonable here and use /lib for your more 3 | structured object oriented classes. 4 | -------------------------------------------------------------------------------- /includes/common.inc: -------------------------------------------------------------------------------- 1 | $v) { 32 | unset($process[$key][$k]); 33 | if (is_array($v)) { 34 | $process[$key][stripslashes($k)] = $v; 35 | $process[] = &$process[$key][stripslashes($k)]; 36 | } else { 37 | $process[$key][stripslashes($k)] = stripslashes($v); 38 | } 39 | } 40 | } 41 | unset($process); 42 | } 43 | 44 | //custom php includes for dev server mail pear and socket libraries 45 | $baselibpath = $config[$config['env']]['base_lib_path']; 46 | $libspath = $baselibpath .'lib'; 47 | 48 | set_include_path( get_include_path() . PATH_SEPARATOR . $libspath ); 49 | -------------------------------------------------------------------------------- /includes/database.inc: -------------------------------------------------------------------------------- 1 | '; 20 | $instring = false; 21 | $inescape = false; 22 | $lastchar = ''; 23 | $output = ""; 24 | for ( $x=0; $xcleardata(); 27 | } 28 | 29 | private function cleardata() { 30 | 31 | $this->plusperson_id = 0; 32 | $this->googleplus_id = ""; 33 | $this->profile_photo = ""; 34 | $this->first_name = ""; 35 | $this->last_name = ""; 36 | $this->introduction = ""; 37 | $this->subhead = ""; 38 | $this->raw_data = ""; 39 | $this->fetched_relationships = 0; 40 | $this->created_dt = ""; 41 | $this->modified_dt = ""; 42 | 43 | } 44 | 45 | private function loadFromRowResult( $row ) { 46 | $this->plusperson_id = $row['plusperson_id']; 47 | $this->googleplus_id = $row['googleplus_id']; 48 | $this->profile_photo = $row['profile_photo']; 49 | $this->first_name = $row['first_name']; 50 | $this->last_name = $row['last_name']; 51 | $this->introduction = $row['introduction']; 52 | $this->subhead = $row['subhead']; 53 | $this->raw_data = $row['raw_data']; 54 | $this->created_dt = $row['created_dt']; 55 | $this->fetched_relationships = $row['fetched_relationships']; 56 | $this->modified_dt = $row['modified_dt']; 57 | } 58 | 59 | public function loadByID( $id ) { 60 | global $db; 61 | 62 | $this->cleardata(); 63 | 64 | $query = sprintf("SELECT * FROM plusperson WHERE plusperson_id = %d", clean_int( $id )); 65 | $result = mysql_query( $query, $db ); 66 | 67 | if ( $row = mysql_fetch_assoc( $result ) ) { 68 | $this->loadFromRowResult( $row ); 69 | } 70 | 71 | } 72 | 73 | public function loadByGooglePlusID( $id ) { 74 | global $db; 75 | 76 | $this->cleardata(); 77 | 78 | $query = sprintf("SELECT * FROM plusperson WHERE googleplus_id = '%s'", clean_string( $id )); 79 | $result = mysql_query( $query, $db ); 80 | 81 | if ( $row = mysql_fetch_assoc( $result ) ) { 82 | $this->loadFromRowResult( $row ); 83 | } 84 | 85 | } 86 | 87 | 88 | 89 | public function insertIntoDB() { 90 | global $db; 91 | 92 | if ( $this->plusperson_id <= 0 ) { 93 | $query = sprintf("INSERT INTO plusperson ( googleplus_id, profile_photo, first_name, last_name, subhead, introduction, raw_data, fetched_relationships, created_dt, modified_dt ) " . 94 | " VALUES ( '%s', '', '', '', '', '', '', 0, NOW(), NOW() ) ", 95 | clean_string( $this->googleplus_id )); 96 | $result = mysql_query( $query, $db ); 97 | if ( $result ) { 98 | $this->plusperson_id = mysql_insert_id( $db ); 99 | $this->updateDB(); 100 | $this->loadByID( $this->plusperson_id ); 101 | } 102 | } 103 | } 104 | 105 | public function updateDB() { 106 | global $db; 107 | 108 | if ( $this->plusperson_id > 0 ) { 109 | 110 | $query = sprintf("UPDATE plusperson SET " . 111 | " googleplus_id='%s', " . 112 | " profile_photo='%s', " . 113 | " first_name='%s', " . 114 | " last_name='%s', " . 115 | " subhead='%s', " . 116 | " introduction='%s', " . 117 | " raw_data='%s', " . 118 | " fetched_relationships=%d, " . 119 | " modified_dt = NOW() " . 120 | " WHERE plusperson_id=%d ", 121 | clean_string( $this->googleplus_id ), 122 | clean_string( $this->profile_photo ), 123 | clean_string( $this->first_name ), 124 | clean_string( $this->last_name ), 125 | clean_string( $this->subhead ), 126 | clean_string( $this->introduction ), 127 | clean_string( $this->raw_data ), 128 | clean_int( $this->fetched_relationships ), 129 | clean_int( $this->plusperson_id ) ); 130 | $result = mysql_query( $query, $db ); 131 | 132 | } 133 | } 134 | 135 | public function deleteFromDB() { 136 | global $db; 137 | 138 | if ( $this->plusperson_id > 0 ) { 139 | 140 | //DELETE ALL SUB-CONTENT 141 | $rs = PlusRelationship::FetchRelationshipsByOwner( $this->googleplus_id ); 142 | foreach ( $rs as $r ) { 143 | $r->deleteFromDB(); 144 | } 145 | 146 | $rs = PlusRelationship::FetchRelationshipsByCircled( $this->googleplus_id ); 147 | foreach ( $rs as $r ) { 148 | $r->deleteFromDB(); 149 | } 150 | 151 | $query = sprintf("DELETE FROM plusperson WHERE plusperson_id = %d", clean_int( $this->plusperson_id ) ); 152 | $result = mysql_query( $query, $db ); 153 | if ( $result ) { 154 | $this->plusperson_id = 0; 155 | } 156 | } 157 | } 158 | 159 | 160 | private function loadFromGooglePlusJSON( $data ) { 161 | $this->googleplus_id = $data[1][0]; 162 | $this->profile_photo = $data[1][2][3]; 163 | $this->first_name = $data[1][2][4][1]; 164 | $this->last_name = $data[1][2][4][2]; 165 | $this->introduction = $data[1][2][14][1]; 166 | $this->subhead = $data[1][2][33][1]; 167 | $this->raw_data = json_encode( $data ); 168 | } 169 | 170 | 171 | public function updateFromGooglePlusService( ) { 172 | 173 | if ( $this->googleplus_id != "" ) { 174 | //echo "update profile
"; 175 | $profile_url = 'https://plus.google.com/_/profiles/get/' . $this->googleplus_id; 176 | 177 | $jsondata = GoogleUtil::FetchGoogleJSON( $profile_url ); 178 | 179 | $this->loadFromGooglePlusJSON( $jsondata ); 180 | 181 | } 182 | 183 | } 184 | 185 | public static function FetchVisiblePlusPeople( $plusid ) { 186 | 187 | $people = array(); 188 | if ( $plusid != "" ) { 189 | //echo "fetch followees
"; 190 | $visible_url = 'https://plus.google.com/_/socialgraph/lookup/visible/?o=%5Bnull%2Cnull%2C%22' . $plusid . '%22%5D'; 191 | $jsondata = GoogleUtil::FetchGoogleJSON( $visible_url ); 192 | $visiblepeople = $jsondata[2]; 193 | //var_dump($jsondata); 194 | foreach( $visiblepeople as $pdata ) { 195 | 196 | $person = new PlusPerson(); 197 | $person->googleplus_id = $pdata[0][2]; 198 | 199 | $name = $pdata[2][0]; 200 | if ( preg_match( '/^([\w\.\s]+) (\w+)$/', $name, $matches ) ) { 201 | $person->first_name = $matches[1]; 202 | $person->last_name = $matches[2]; 203 | } else { 204 | $person->first_name = $name; 205 | } 206 | 207 | $people[] = $person; 208 | } 209 | 210 | 211 | } 212 | 213 | return $people; 214 | 215 | } 216 | 217 | public static function FetchIncomingPlusPeople( $plusid ) { 218 | 219 | $people = array(); 220 | if ( $plusid != "" ) { 221 | //echo "fetch followers
"; 222 | $visible_url = 'https://plus.google.com/_/socialgraph/lookup/incoming/?o=%5Bnull%2Cnull%2C%22' . $plusid .'%22%5D&n=1000'; 223 | $jsondata = GoogleUtil::FetchGoogleJSON( $visible_url ); 224 | $inpeople = $jsondata[2]; 225 | 226 | foreach( $inpeople as $pdata ) { 227 | 228 | $person = new PlusPerson(); 229 | $person->googleplus_id = $pdata[0][2]; 230 | 231 | $name = $pdata[2][0]; 232 | if ( preg_match( '/^([\w\.\s]+) (\w+)$/', $name, $matches ) ) { 233 | $person->first_name = $matches[1]; 234 | $person->last_name = $matches[2]; 235 | } else { 236 | $person->first_name = $name; 237 | } 238 | $people[] = $person; 239 | } 240 | 241 | 242 | } 243 | 244 | return $people; 245 | 246 | } 247 | 248 | } 249 | -------------------------------------------------------------------------------- /lib/GooglePlus/PlusPost.php: -------------------------------------------------------------------------------- 1 | cleardata(); 24 | } 25 | 26 | private function cleardata() { 27 | 28 | $this->pluspost_id = 0; 29 | $this->googleplus_postid = ""; 30 | $this->author_id = ""; 31 | $this->post_data = ""; 32 | $this->share_content = ""; 33 | $this->shared_postid = ""; 34 | 35 | $this->raw_data = ""; 36 | $this->created_dt = ""; 37 | $this->modified_dt = ""; 38 | 39 | } 40 | 41 | private function loadFromRowResult( $row ) { 42 | $this->pluspost_id = $row['pluspost_id']; 43 | $this->googleplus_postid = $row['googleplus_postid']; 44 | $this->author_id = $row['author_id']; 45 | $this->post_data = $row['post_data']; 46 | $this->share_content = $row['share_content']; 47 | $this->shared_postid = $row['shared_postid']; 48 | 49 | $this->raw_data = $row['raw_data']; 50 | $this->created_dt = $row['created_dt']; 51 | $this->modified_dt = $row['modified_dt']; 52 | } 53 | 54 | public function loadByID( $id ) { 55 | global $db; 56 | 57 | $this->cleardata(); 58 | 59 | $query = sprintf("SELECT * FROM pluspost WHERE pluspost_id = %d", clean_int( $id )); 60 | $result = mysql_query( $query, $db ); 61 | 62 | if ( $row = mysql_fetch_assoc( $result ) ) { 63 | $this->loadFromRowResult( $row ); 64 | } 65 | 66 | } 67 | 68 | public function loadByGooglePlusPostID( $id ) { 69 | global $db; 70 | 71 | $this->cleardata(); 72 | 73 | $query = sprintf("SELECT * FROM pluspost WHERE googleplus_postid = '%s'", clean_string( $id )); 74 | $result = mysql_query( $query, $db ); 75 | 76 | if ( $row = mysql_fetch_assoc( $result ) ) { 77 | $this->loadFromRowResult( $row ); 78 | } 79 | 80 | } 81 | 82 | public function mergeStreamPostIntoDB() { 83 | global $db; 84 | 85 | if ( $this->pluspost_id <= 0 ) { 86 | //if the google post id exists, hijack this insert and update the existing record instead 87 | if ( $this->googleplus_postid != "" ) { 88 | $existing = new PlusPost(); 89 | $existing->loadByGooglePlusPostID( $this->googleplus_postid ); 90 | if ( $existing->pluspost_id != 0 ) { 91 | 92 | $this->pluspost_id = $existing->pluspost_id; 93 | $this->updateDB(); 94 | 95 | } else { 96 | 97 | $this->insertIntoDB(); 98 | 99 | } 100 | } 101 | } 102 | } 103 | 104 | public function insertIntoDB() { 105 | global $db; 106 | 107 | 108 | if ( $this->pluspost_id <= 0 ) { 109 | 110 | 111 | $query = sprintf("INSERT INTO pluspost ( googleplus_postid, author_id, post_data, share_content, shared_postid, raw_data, created_dt, modified_dt ) " . 112 | " VALUES ( '%s', '', '', '', '', '', NOW(), NOW() ) ", 113 | clean_string( $this->googleplus_postid )); 114 | $result = mysql_query( $query, $db ); 115 | if ( $result ) { 116 | $this->pluspost_id = mysql_insert_id( $db ); 117 | $this->updateDB(); 118 | $this->loadByID( $this->pluspost_id ); 119 | } 120 | } 121 | } 122 | 123 | public function updateDB() { 124 | global $db; 125 | 126 | if ( $this->pluspost_id > 0 ) { 127 | 128 | $query = sprintf("UPDATE pluspost SET " . 129 | " googleplus_postid='%s', " . 130 | " author_id='%s', " . 131 | " post_data='%s', " . 132 | " share_content='%s', " . 133 | " shared_postid='%s', " . 134 | " raw_data='%s', " . 135 | " modified_dt = NOW() " . 136 | " WHERE pluspost_id=%d ", 137 | clean_string( $this->googleplus_postid ), 138 | clean_string( $this->author_id ), 139 | clean_string( $this->post_data ), 140 | clean_string( $this->share_content ), 141 | clean_string( $this->shared_postid ), 142 | clean_string( $this->raw_data ), 143 | clean_int( $this->pluspost_id ) ); 144 | $result = mysql_query( $query, $db ); 145 | 146 | } 147 | } 148 | 149 | public function deleteFromDB() { 150 | global $db; 151 | 152 | if ( $this->pluspost_id > 0 ) { 153 | 154 | //DELETE ALL SUB-CONTENT 155 | 156 | $query = sprintf("DELETE FROM pluspost WHERE pluspost_id = %d", clean_int( $this->pluspost_id ) ); 157 | $result = mysql_query( $query, $db ); 158 | if ( $result ) { 159 | $this->pluspost_id = 0; 160 | } 161 | } 162 | } 163 | 164 | public function getAttachments() { 165 | 166 | $attachments = array(); 167 | 168 | $data = json_decode( $this->raw_data ); 169 | 170 | if ( isset( $data ) && isset( $data[11] ) ) { 171 | foreach ( $data[11] as $attachdata ) { 172 | 173 | $attch = new PostAttachment(); 174 | $attch->loadFromGooglePlusJSON( $attachdata ); 175 | $attachments[] = $attch; 176 | 177 | } 178 | } 179 | 180 | return $attachments; 181 | } 182 | 183 | private function loadFromGooglePlusJSON( $data ) { 184 | $this->googleplus_postid = $data[21]; 185 | $this->author_id = $data[16]; 186 | $this->share_content = $data[47]; 187 | $this->post_data = $data[4]; 188 | $this->shared_postid = $data[77]; 189 | 190 | $this->raw_data = json_encode( $data ); 191 | } 192 | 193 | public function getUpdateID() { 194 | $updateid=""; 195 | if ( preg_match( '/\/posts\/(\w+)$/', $this->googleplus_postid, $matches ) ) { 196 | $updateid = $matches[1]; 197 | } 198 | return $updateid; 199 | } 200 | public function getAuthorIDFromPostID() { 201 | $authorid=""; 202 | if ( preg_match( '/^(\w+)\/posts\//', $this->googleplus_postid, $matches ) ) { 203 | $authorid = $matches[1]; 204 | } 205 | return $authorid; 206 | } 207 | 208 | //this updates a single post 209 | public function updateFromGooglePlusService( ) { 210 | 211 | if ( $this->googleplus_postid != "" ) { 212 | $post_url = 'https://plus.google.com/_/stream/getactivity/' . $this->getAuthorIDFromPostID() . '?updateId=' . $this->getUpdateID(); 213 | 214 | $jsondata = GoogleUtil::FetchGoogleJSON( $post_url ); 215 | 216 | $this->loadFromGooglePlusJSON( $jsondata[1] ); 217 | 218 | } 219 | } 220 | 221 | 222 | public static function FetchPostsByGooglePlusID( $googleplus_id ) { 223 | global $db; 224 | 225 | $query = sprintf( "SELECT * FROM pluspost WHERE author_id = '%s' ORDER BY created_dt DESC" , clean_string($googleplus_id) ); 226 | $result = mysql_query( $query, $db ); 227 | $ps = array(); 228 | while ( $row = mysql_fetch_assoc( $result ) ) { 229 | $p = new PlusPost(); 230 | $p->loadFromRowResult( $row ); 231 | $ps[] = $p; 232 | } 233 | 234 | return $ps; 235 | } 236 | 237 | public static function FetchActivityStream( $googleplus_id ) { 238 | 239 | $activity_url = 'https://plus.google.com/_/stream/getactivities/' . $googleplus_id . '/?sp=%5B1%2C2%2C%22' . $googleplus_id . '%22%2Cnull%2Cnull%2Cnull%2Cnull%2C%22social.google.com%22%2C%5B%5D%5D'; 240 | $jsondata = GoogleUtil::FetchGoogleJSON( $activity_url ); 241 | $activities = $jsondata[1][0]; 242 | 243 | //var_dump( $jsondata ); 244 | $posts = array(); 245 | foreach( $activities as $postdata ) { 246 | $post = new PlusPost(); 247 | $post->loadFromGooglePlusJSON( $postdata ); 248 | $posts[] = $post; 249 | } 250 | return $posts; 251 | 252 | } 253 | 254 | 255 | 256 | } 257 | -------------------------------------------------------------------------------- /lib/GooglePlus/PlusRelationship.php: -------------------------------------------------------------------------------- 1 | cleardata(); 18 | } 19 | 20 | private function cleardata() { 21 | 22 | $this->plusrelationship_id = 0; 23 | $this->owner_id = 0; 24 | $this->hasincircle_id = 0; 25 | $this->created_dt = ""; 26 | $this->modified_dt = ""; 27 | 28 | } 29 | 30 | private function loadFromRowResult( $row ) { 31 | $this->plusrelationship_id = $row['plusrelationship_id']; 32 | $this->owner_id = $row['owner_id']; 33 | $this->hasincircle_id = $row['hasincircle_id']; 34 | $this->created_dt = $row['created_dt']; 35 | $this->modified_dt = $row['modified_dt']; 36 | } 37 | 38 | public function loadByID( $id ) { 39 | global $db; 40 | 41 | $this->cleardata(); 42 | 43 | $query = sprintf("SELECT * FROM plusrelationship WHERE plusrelationship_id = %d", clean_int( $id )); 44 | $result = mysql_query( $query, $db ); 45 | 46 | if ( $row = mysql_fetch_assoc( $result ) ) { 47 | $this->loadFromRowResult( $row ); 48 | } 49 | 50 | } 51 | 52 | 53 | public function insertIntoDB() { 54 | global $db; 55 | 56 | if ( $this->plusrelationship_id <= 0 ) { 57 | $query = sprintf("INSERT INTO plusrelationship ( owner_id, hasincircle_id, created_dt, modified_dt ) " . 58 | " VALUES ( '','', NOW(), NOW() ) "); 59 | $result = mysql_query( $query, $db ); 60 | if ( $result ) { 61 | $this->plusrelationship_id = mysql_insert_id( $db ); 62 | $this->updateDB(); 63 | $this->loadByID( $this->plusrelationship_id ); 64 | } 65 | } 66 | } 67 | 68 | public function updateDB() { 69 | global $db; 70 | 71 | if ( $this->plusrelationship_id > 0 ) { 72 | 73 | $query = sprintf("UPDATE plusrelationship SET " . 74 | " owner_id='%s', " . 75 | " hasincircle_id='%s', " . 76 | " modified_dt = NOW() " . 77 | " WHERE plusrelationship_id=%d ", 78 | clean_string( $this->owner_id ), 79 | clean_string( $this->hasincircle_id ), 80 | clean_int( $this->plusrelationship_id ) ); 81 | $result = mysql_query( $query, $db ); 82 | 83 | } 84 | } 85 | 86 | public function deleteFromDB() { 87 | global $db; 88 | 89 | if ( $this->plusrelationship_id > 0 ) { 90 | 91 | //DELETE ALL SUB-CONTENT 92 | //$revs = DocRevision::FetchByGroupDoc( $this->groupdoc_id ); 93 | //foreach ( $revs as $rev ) { 94 | // $rev->deleteFromDB(); 95 | //} 96 | 97 | $query = sprintf("DELETE FROM plusrelationship WHERE plusrelationship_id = %d", clean_int( $this->plusrelationship_id ) ); 98 | $result = mysql_query( $query, $db ); 99 | if ( $result ) { 100 | $this->plusrelationship_id = 0; 101 | } 102 | } 103 | } 104 | 105 | 106 | public static function FetchRelationshipsByOwner( $googleplus_id ) { 107 | global $db; 108 | 109 | $query = sprintf( "SELECT * FROM plusrelationship WHERE owner_id = '%s' ORDER BY modified_dt ASC" , clean_string($googleplus_id) ); 110 | $result = mysql_query( $query, $db ); 111 | $rs = array(); 112 | while ( $row = mysql_fetch_assoc( $result ) ) { 113 | $r = new PlusRelationship(); 114 | $r->loadFromRowResult( $row ); 115 | $rs[] = $r; 116 | } 117 | 118 | return $rs; 119 | 120 | } 121 | 122 | 123 | public static function FetchRelationshipsByCircled( $googleplus_id ) { 124 | global $db; 125 | 126 | $query = sprintf( "SELECT * FROM plusrelationship WHERE hasincircle_id = '%s' ORDER BY modified_dt ASC" , clean_string($googleplus_id) ); 127 | $result = mysql_query( $query, $db ); 128 | $rs = array(); 129 | while ( $row = mysql_fetch_assoc( $result ) ) { 130 | $r = new PlusRelationship(); 131 | $r->loadFromRowResult( $row ); 132 | $rs[] = $r; 133 | } 134 | 135 | return $rs; 136 | 137 | } 138 | 139 | 140 | } 141 | -------------------------------------------------------------------------------- /lib/GooglePlus/PostAttachment.php: -------------------------------------------------------------------------------- 1 | cleardata(); 21 | } 22 | 23 | private function cleardata() { 24 | 25 | $this->title = ""; 26 | $this->description = ""; 27 | $this->url = ""; 28 | $this->media_url = ""; 29 | $this->media_width = ""; 30 | $this->media_height = ""; 31 | $this->media_type = ""; 32 | $this->preview_img = ""; 33 | $this->raw_data = ""; 34 | 35 | } 36 | 37 | 38 | public function loadFromGooglePlusJSON( $data ) { 39 | $this->title = $data[3]; 40 | $this->description = $data[21]; 41 | 42 | if ( isset( $data[24] ) ) { 43 | $this->url = $data[24][1]; 44 | } 45 | if ( isset( $data[5] ) ) { 46 | $this->media_url = $data[5][1]; 47 | $this->media_width = $data[5][2]; 48 | $this->media_height = $data[5][3]; 49 | $this->media_type = $data[24][4]; 50 | $this->preview_img = $data[41][0][1]; 51 | } 52 | 53 | $this->raw_data = json_encode( $data ); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | Any class libraries and external libs (facebook, twitter oauth, etc.) should 2 | go in here. Use a subdirectory for each libray to keep things organized. 3 | -------------------------------------------------------------------------------- /sql/README: -------------------------------------------------------------------------------- 1 | Place any .sql table definitions here for easy site xfer and setup. 2 | -------------------------------------------------------------------------------- /sql/plusperson.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `plusperson` ( 2 | `plusperson_id` bigint(20) NOT NULL auto_increment, 3 | `googleplus_id` varchar(32) collate utf8_bin NOT NULL, 4 | `profile_photo` varchar(255) collate utf8_bin NOT NULL, 5 | `first_name` varchar(128) collate utf8_bin NOT NULL, 6 | `last_name` varchar(128) collate utf8_bin NOT NULL, 7 | `introduction` text collate utf8_bin NOT NULL, 8 | `subhead` text collate utf8_bin NOT NULL, 9 | `raw_data` text collate utf8_bin NOT NULL, 10 | `fetched_relationships` int(11) NOT NULL default '0', 11 | `created_dt` datetime NOT NULL, 12 | `modified_dt` datetime NOT NULL, 13 | PRIMARY KEY (`plusperson_id`), 14 | UNIQUE KEY `googleplus_id` (`googleplus_id`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 16 | -------------------------------------------------------------------------------- /sql/pluspost.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `pluspost` ( 2 | `pluspost_id` bigint(20) NOT NULL auto_increment, 3 | `googleplus_postid` varchar(128) collate utf8_bin NOT NULL, 4 | `author_id` varchar(32) collate utf8_bin NOT NULL, 5 | `post_data` text collate utf8_bin NOT NULL, 6 | `share_content` text collate utf8_bin NOT NULL, 7 | `shared_postid` varchar(128) collate utf8_bin NOT NULL, 8 | `raw_data` text collate utf8_bin NOT NULL, 9 | `created_dt` datetime NOT NULL, 10 | `modified_dt` datetime NOT NULL, 11 | PRIMARY KEY (`pluspost_id`), 12 | UNIQUE KEY `googleplus_postid` (`googleplus_postid`), 13 | KEY `author_id` (`author_id`), 14 | KEY `shared_postid` (`shared_postid`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 16 | 17 | -------------------------------------------------------------------------------- /sql/plusrelationship.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `plusrelationship` ( 2 | `plusrelationship_id` bigint(20) NOT NULL auto_increment, 3 | `owner_id` varchar(32) collate utf8_bin NOT NULL, 4 | `hasincircle_id` varchar(32) collate utf8_bin NOT NULL, 5 | `created_dt` datetime NOT NULL, 6 | `modified_dt` datetime NOT NULL, 7 | PRIMARY KEY (`plusrelationship_id`), 8 | KEY `owner_id` (`owner_id`), 9 | KEY `hasincircle_id` (`hasincircle_id`) 10 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 11 | 12 | -------------------------------------------------------------------------------- /templates/pages/README: -------------------------------------------------------------------------------- 1 | These files will contain predominatelyi body HTML. This is used by main page 2 | logic to render output. Template variables will be in the global $template 3 | array. Try to keep from using any php code in here, aside from simple 4 | conditions for displaying alternate html, or loop control to iterate over 5 | results. 6 | -------------------------------------------------------------------------------- /templates/pages/example.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Example template file

4 |

5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /templates/pages/tests/plusactivity.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?= $template['title'] ?> 5 | 6 | 7 | 8 |

first_name ?> last_name ?> (photo)

9 | 10 |

first_name ?>'s Posts:

11 | 12 | shared_postid == "" ) 16 | { 17 | 18 | //normal post 19 | ?> 20 |
21 |
22 | googleplus_postid ?>
23 | post_data ?> 24 |
25 | 26 | 31 | 32 |
33 |
34 | googleplus_postid ?>
35 | share_content ?> 36 |
37 | Shared post:
38 | shared_postid ?>
39 | post_data ?> 40 |
41 |
42 | 43 | getAttachments(); 47 | foreach ( $attchs as $attch ) { 48 | ?> 49 | 50 |
51 | preview_img != "" ) { 53 | ?> 54 | 55 | 58 | title ?>
59 | description ?> 60 | 63 | 64 |
65 | 66 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /templates/pages/tests/plususer.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?= $template['title'] ?> 5 | 6 | 7 | 8 |

first_name ?> last_name ?> (photo)

9 | 10 |

In first_name ?>'s Circles:

11 | 12 |

13 | 16 | googleplus_id ?> first_name ?> last_name ?>
17 | 20 |

21 | 22 | 23 |

Have first_name ?> in Circles:

24 |

25 | 26 | 29 | googleplus_id ?> first_name ?> last_name ?>
30 | 33 | 34 |

35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /templates/shared/README: -------------------------------------------------------------------------------- 1 | If many templates uses pieces of similar code, put those snippets here. Most 2 | commonly, this is convenient for header and footer files. 3 | -------------------------------------------------------------------------------- /templates/shared/footer.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /templates/shared/header.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?php echo $template['title'] ?> 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/examplefollowerdata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /tests/exampleprofiledata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 331 | 332 | 333 | -------------------------------------------------------------------------------- /tests/plusactivity.php: -------------------------------------------------------------------------------- 1 | loadByGooglePlusID( $pid ); 33 | 34 | if ( $person->plusperson_id == 0 ) { 35 | $person->googleplus_id = $pid; 36 | $person->updateFromGooglePlusService(); 37 | $person->insertIntoDB(); 38 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 39 | $person->updateFromGooglePlusService(); 40 | $person->updateDB(); 41 | } 42 | 43 | $template['title'] = $person->first_name . " " . $person->last_name . " // " . $template['title']; 44 | 45 | 46 | //Get the posts from G+ 47 | $posts = PlusPost::FetchActivityStream( $person->googleplus_id ); 48 | 49 | 50 | //Save them all into the DB (merge will try to update them if they exist already) 51 | foreach ( $posts as $post ) { 52 | $post->mergeStreamPostIntoDB(); 53 | } 54 | 55 | //Pull them back out of the db for display 56 | $posts = PlusPost::FetchPostsByGooglePlusID( $person->googleplus_id ); 57 | 58 | $template['person'] = $person; 59 | $template['posts'] = $posts; 60 | require_once $templatesdir . 'pages/tests/plusactivity.inc'; 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /tests/plususer.php: -------------------------------------------------------------------------------- 1 | loadByGooglePlusID( $pid ); 33 | 34 | if ( $person->plusperson_id == 0 ) { 35 | $person->googleplus_id = $pid; 36 | $person->updateFromGooglePlusService(); 37 | $person->insertIntoDB(); 38 | } else if ( strtotime( $person->modified_dt ) < strtotime( "-6 hours" ) ) { 39 | $person->updateFromGooglePlusService(); 40 | $person->fetched_relationships = 0; 41 | $person->updateDB(); 42 | } 43 | 44 | $template['title'] = $person->first_name . " " . $person->last_name . " // " . $template['title']; 45 | 46 | $hascircled = array(); 47 | $circledby = array(); 48 | 49 | if ( $person->fetched_relationships != 1 ) { 50 | 51 | $followees = PlusPerson::FetchVisiblePlusPeople( $person->googleplus_id ); 52 | $followers = PlusPerson::FetchIncomingPlusPeople( $person->googleplus_id ); 53 | 54 | 55 | $or = PlusRelationship::FetchRelationshipsByOwner( $person->googleplus_id ); 56 | foreach ( $or as $r ) { 57 | $r->deleteFromDB(); 58 | } 59 | $cr = PlusRelationship::FetchRelationshipsByCircled( $person->googleplus_id ); 60 | foreach ( $cr as $r ) { 61 | $r->deleteFromDB(); 62 | } 63 | 64 | //These could be easily sped up with a map that loads all existing in one db hit. 65 | //Leaving as-is to improve readability for demo. 66 | foreach( $followees as $fp ) { 67 | $pid = $fp->googleplus_id; 68 | $fp->loadByGooglePlusID( $pid ); 69 | if ( $fp->plusperson_id <= 0 ) { 70 | $fp->googleplus_id = $pid; 71 | $fp->updateFromGooglePlusService(); 72 | $fp->insertIntoDB(); 73 | } 74 | $hascircled[] = $fp; 75 | 76 | $rel = new PlusRelationship(); 77 | $rel->owner_id = $person->googleplus_id; 78 | $rel->hasincircle_id = $fp->googleplus_id; 79 | $rel->insertIntoDB(); 80 | 81 | } 82 | 83 | 84 | //Some people are circled by a ton of other people. 85 | //Let's not fetch these profiles if they aren't already cached. 86 | foreach( $followers as $fp ) { 87 | $pid = $fp->googleplus_id; 88 | $fp->loadByGooglePlusID( $pid ); 89 | if ( $fp->plusperson_id <= 0 ) { 90 | $fp->googleplus_id = $pid; 91 | } 92 | $circledby[] = $fp; 93 | 94 | $rel = new PlusRelationship(); 95 | $rel->owner_id = $fp->googleplus_id; 96 | $rel->hasincircle_id = $person->googleplus_id; 97 | $rel->insertIntoDB(); 98 | 99 | } 100 | 101 | $person->fetched_relationships = 1; 102 | $person->updateDB(); 103 | 104 | } else { 105 | 106 | $or = PlusRelationship::FetchRelationshipsByOwner( $person->googleplus_id ); 107 | foreach ( $or as $r ) { 108 | $p = new PlusPerson(); 109 | $p->loadByGooglePlusID( $r->hasincircle_id ); 110 | if ( $p->plusperson_id <= 0 ) { 111 | $p->googleplus_id = $r->hasincircle_id; 112 | } 113 | $hascircled[] = $p; 114 | } 115 | 116 | $cr = PlusRelationship::FetchRelationshipsByCircled( $person->googleplus_id ); 117 | foreach ( $cr as $r ) { 118 | $p = new PlusPerson(); 119 | $p->loadByGooglePlusID( $r->owner_id ); 120 | if ( $p->plusperson_id <= 0 ) { 121 | $p->googleplus_id = $r->owner_id; 122 | } 123 | $circledby[] = $p; 124 | } 125 | 126 | } 127 | 128 | $template['person'] = $person; 129 | $template['circledby'] = $circledby; 130 | $template['hascircled'] = $hascircled; 131 | require_once $templatesdir . 'pages/tests/plususer.inc'; 132 | 133 | } 134 | 135 | --------------------------------------------------------------------------------