4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 class ATutorDbFetcher {
27 function debug($var, $title='') {
28 echo '<pre style="border: 1px black solid; padding: 0px; margin: 10px;" title="debugging box">';
30 echo '<h4>'.$title.'</h4>';
35 $str = ob_get_contents();
38 $str = str_replace('<', '<', $str);
40 $str = str_replace('[', '<span style="color: red; font-weight: bold;">[', $str);
41 $str = str_replace(']', ']</span>', $str);
42 $str = str_replace('=>', '<span style="color: blue; font-weight: bold;">=></span>', $str);
43 $str = str_replace('Array', '<span style="color: purple; font-weight: bold;">Array</span>', $str);
49 private static $fetcher;
51 private function connectDb() {
52 // one of the class paths should point to ATutor's document root, abuse that fact to find our config
53 $extension_class_paths = Config::get('extension_class_paths');
54 foreach (explode(',', $extension_class_paths) as $path) {
55 if (file_exists($path . "/ATutorDbFetcher.php")) {
56 $configFile = $path . '/../../../../include/lib/mysql_connect.inc.php';
57 if (file_exists($configFile)) {
58 define('AT_INCLUDE_PATH', $path . '/../../../../include/');
59 include(AT_INCLUDE_PATH.'config.inc.php');
60 include(AT_INCLUDE_PATH . 'lib/constants.inc.php');
61 include(AT_INCLUDE_PATH . 'lib/mysql_connect.inc.php');
67 if (! isset($configFile)) {
68 throw new Exception("Could not locate ATutor's configuration file while scanning extension_class_paths ({$extension_class_paths})");
70 // $this->db = mysqli_connect($config['db_host'], $config['db_user'], $config['db_passwd'], $config['db_database']);
71 // mysqli_select_db($this->db, $config['db_database']);
72 // $this->url_prefix = $config['partuza_url'];
75 private function __construct() {
76 $cache = Config::get('data_cache');
77 $this->cache = new $cache();
80 private function checkDb() {
81 if (! is_resource($this->db)) {
86 private function __clone() { // private, don't allow cloning of a singleton
89 static function get() {
90 // This object is a singleton
91 if (! isset(ATutorDbFetcher::$fetcher)) {
92 ATutorDbFetcher::$fetcher = new ATutorDbFetcher();
94 return ATutorDbFetcher::$fetcher;
97 public function createActivity($member_id, $activity, $app_id = '0') {
99 $app_id = intval($app_id);
100 $person_id = intval($member_id);
101 $title = trim(isset($activity['title']) ? $activity['title'] : '');
103 throw new Exception("Invalid activity: empty title");
105 // $body = isset($activity['body']) ? $activity['body'] : '';
106 $title = mysql_real_escape_string($title);
107 // $body = mysql_real_escape_string($body);
108 $sql = "insert into ".TABLE_PREFIX."social_activities (id, member_id, application_id, title, created_date) values (0, $member_id, $app_id, '$title', NOW())";
109 mysql_query($sql, $this->db);
110 if (! ($activityId = mysql_insert_id($this->db))) {
115 * I don't have this on my system yet. -Harris
117 $mediaItems = isset($activity['mediaItems']) ? $activity['mediaItems'] : array();
118 if (count($mediaItems)) {
119 foreach ($mediaItems as $mediaItem) {
120 $type = isset($mediaItem['type']) ? $mediaItem['type'] : '';
121 $mimeType = isset($mediaItem['mimeType']) ? $mediaItem['mimeType'] : '';
122 $url = isset($mediaItem['url']) ? $mediaItem['url'] : '';
123 $type = mysqli_real_escape_string($this->db, trim($type));
124 $mimeType = mysqli_real_escape_string($this->db, trim($mimeType));
125 $url = mysqli_real_escape_string($this->db, trim($url));
126 if (! empty($mimeType) && ! empty($type) && ! empty($url)) {
127 mysqli_query($this->db, "insert into activity_media_items (id, activity_id, mime_type, media_type, url) values (0, $activityId, '$mimeType', '$type', '$url')");
128 if (! mysqli_insert_id($this->db)) {
140 // public function getActivities($ids, $appId, $sortBy, $filterBy, $filterOp, $filterValue, $startIndex, $count, $fields, $activityIds) {
141 public function getActivities($ids, $appId, $sortBy, $filterBy, $filterOp, $filterValue, $startIndex, $count, $fields) {
143 //TODO add support for filterBy, filterOp and filterValue
145 $activities = array();
146 foreach ($ids as $key => $val) {
147 $ids[$key] = mysql_real_escape_string($val);
149 $ids = implode(',', $ids);
150 if (isset($activityIds) && is_array($activityIds)) {
151 foreach ($activityIds as $key => $val) {
152 $activityIds[$key] = mysql_real_escape_string($val);
154 $activityIdQuery = " and activities.id in (".implode(',', $activityIds);
156 $activityIdQuery = '';
158 // return a proper totalResults count
159 $sql = "select count(id) from ".TABLE_PREFIX."social_activities where ".TABLE_PREFIX."activities.person_id in ($ids) $activityIdQuery";
160 $res = mysql_query($sql, $this->db);
162 if ($res !== false) {
163 list($totalResults) = mysql_fetch_row($res);
167 $startIndex = (! is_null($startIndex) && $startIndex !== false && is_numeric($startIndex)) ? intval($startIndex) : '0';
168 $count = (! is_null($count) && $count !== false && is_numeric($count)) ? intval($count) : '20';
169 $activities['totalResults'] = $totalResults;
170 $activities['startIndex'] = $startIndex;
171 $activities['count'] = $count;
174 ".TABLE_PREFIX."social_activities.member_id as member_id,
175 ".TABLE_PREFIX."social_activities.id as activity_id,
176 ".TABLE_PREFIX."social_activities.title as title,
177 ".TABLE_PREFIX."social_activities.created as created
179 ".TABLE_PREFIX."social_activities
181 ".TABLE_PREFIX."social_activities.member_id in ($ids)
188 $res = mysql_query($query, $this->db);
190 if (@mysql_num_rows($res)) {
191 while ($row = @mysql_fetch_assoc($res)) {
192 $activity = new Activity($row['activity_id'], $row['member_id']);
193 $activity->setStreamTitle('activities');
194 $activity->setTitle($row['activity_title']);
195 // $activity->setBody($row['activity_body']);
196 $activity->setPostedTime($row['created']);
197 $activity->setMediaItems($this->getMediaItems($row['activity_id']));
198 $activities[] = $activity;
200 } elseif (isset($activityIds) && is_array($activityIds)) {
201 // specific activity id was specified, return a not found flag
210 public function deleteActivities($userId, $appId, $activityIds) {
212 foreach ($activityIds as $key => $val) {
213 $activityIds[$key] = mysql_real_escape_string($val);
215 $activityIds = implode(',', $activityIds);
216 $userId = intval($userId);
217 $appId = intval($appId);
218 //can use this instead: $sql = "delete from ".TABLE_PREFIX."social_activities where id in ($activityIds)";
219 $sql = "delete from ".TABLE_PREFIX."social_activities where member_id = $userId and application_id = $appId and id in ($activityIds)";
221 mysql_query($sql, $this->db);
222 return (mysql_affected_rows($this->db) != 0);
226 * I didn't implement this yet
228 private function getMediaItems($activity_id) {
230 // $activity_id = mysqli_real_escape_string($db, $activity_id);
231 // $res = mysqli_query($this->db, "select mime_type, media_type, url from ".TABLE_PREFIX."activity_media_items where activity_id = $activity_id");
232 // while (list($mime_type, $type, $url) = @mysqli_fetch_row($res)) {
233 // $media[] = new MediaItem($mime_type, $type, $url);
238 public function getFriendIds($member_id) {
242 $person_id = intval($person_id);
243 $sql = "select member_id, friend_id from ".TABLE_PREFIX."social_friends where member_id = $member_id or friend_id = $member_id";
244 $res = mysql_query($sql, $this->db);
245 while (list($mid, $fid) = mysql_fetch_row($res)) {
246 $id = ($mid == $member_id) ? $fid : $mid;
252 public function setAppData($member_id, $key, $value, $app_id) {
254 $member_id = intval($member_id);
255 $key = mysql_real_escape_string($key);
256 $value = mysql_real_escape_string($value);
257 $app_id = intval($app_id);
259 // empty key kind of became to mean "delete data" (was an old orkut hack that became part of the spec spec)
260 $sql = "delete from ".TABLE_PREFIX."social_application_settings where application_id = $app_id and member_id = $member_id and name = '$key'";
261 if (! @mysql_query($sql, $this->db)) {
265 $sql ="insert into ".TABLE_PREFIX."social_application_settings (application_id, member_id, name, value) values ($app_id, $member_id, '$key', '$value') on duplicate key update value = '$value'";
266 if (! @mysql_query($sql, $this->db)) {
273 public function deleteAppData($member_id, $key, $app_id) {
276 $person_id = intval($member_id);
277 $app_id = intval($app_id);
279 $sql = "delete from ".TABLE_PREFIX."social_application_settings where application_id = $app_id and member_id = $member_id";
280 if (! @mysql_query($sql, $this->db)) {
284 $key = mysql_real_escape_string($this->db, $key);
285 $sql = "delete from ".TABLE_PREFIX."social_application_settings where application_id = $app_id and member_id = $member_id and name = '$key'";
286 if (! @mysql_query($sql, $this->db)) {
293 public function getAppData($ids, $keys, $app_id) {
296 foreach ($ids as $key => $val) {
298 $ids[$key] = intval($val);
301 if (! isset($keys[0])) {
304 if ($keys[0] == '*') {
306 } elseif (is_array($keys)) {
307 foreach ($keys as $key => $val) {
308 $keys[$key] = "'" . addslashes($val) . "'";
310 $keys = "and name in (" . implode(',', $keys) . ")";
314 $sql = "select member_id, name, value from ".TABLE_PREFIX."social_application_settings where application_id = $app_id and member_id in (" . implode(',', $ids) . ") $keys";
315 $res = mysql_query($sql, $this->db);
316 while (list($member_id, $key, $value) = mysql_fetch_row($res)) {
317 if (! isset($data[$member_id])) {
318 $data[$member_id] = array();
320 $data[$member_id][$key] = $value;
325 public function getPeople($ids, $fields, $options, $token) {
326 $first = $options->getStartIndex();
327 $max = $options->getCount();
331 if ($options->getFilterBy() == 'hasApp') {
332 // remove the filterBy field, it's taken care of in the query already, otherwise filterResults will disqualify all results
333 $options->setFilterBy(null);
334 $appId = $token->getAppId();
335 $filterQuery = " and id in (select member_id from ".TABLE_PREFIX."social_applications where application_id = $appId)";
336 } elseif ($options->getFilterBy() == 'all') {
337 $options->setFilterBy(null);
339 $query = "SELECT member.*, info.interests, info.associations, info.awards FROM ".TABLE_PREFIX."members member LEFT JOIN ".TABLE_PREFIX."social_member_additional_information info ON member.member_id=info.member_id WHERE member.member_id IN (" . implode(',', $ids) . ") $filterQuery ORDER BY member.member_id ";
341 $res = mysql_query($query, $this->db);
343 while ($row = mysql_fetch_assoc($res)) {
344 $member_id = intval($row['member_id']);
345 $name = new Name($row['first_name'] . ' ' . $row['last_name']);
347 $name->setGivenName($row['first_name']);
348 $name->setFamilyName($row['last_name']);
349 $person = new Person($row['member_id'], $name);
350 $person->setDisplayName($name->getFormatted());
351 $person->setAboutMe($row['about_me']);
352 $person->setAge($row['age']);
353 $person->setChildren($row['children']);
354 $person->setBirthday(date('Y-m-d', $row['date_of_birth']));
355 $person->setEthnicity($row['ethnicity']);
356 $person->setFashion($row['fashion']);
357 $person->setHappiestWhen($row['happiest_when']);
358 $person->setHumor($row['humor']);
359 $person->setJobInterests($row['job_interests']);
360 $person->setLivingArrangement($row['living_arrangement']);
361 $person->setLookingFor($row['looking_for']);
362 $person->setNickname($row['nickname']);
363 $person->setPets($row['pets']);
364 $person->setPoliticalViews($row['political_views']);
365 $person->setProfileSong($row['profile_song']);
366 $person->setProfileUrl($this->url_prefix . '/profile/' . $row['member_id']);
367 $person->setProfileVideo($row['profile_video']);
368 $person->setRelationshipStatus($row['relationship_status']);
369 $person->setReligion($row['religion']);
370 $person->setRomance($row['romance']);
371 $person->setScaredOf($row['scared_of']);
372 $person->setSexualOrientation($row['sexual_orientation']);
373 $person->setStatus($row['status']);
374 $person->setThumbnailUrl(! empty($row['thumbnail_url']) ? $this->url_prefix . $row['thumbnail_url'] : '');
376 if (! empty($row['thumbnail_url'])) {
377 // also report thumbnail_url in standard photos field (this is the only photo supported by ATutor)
378 $person->setPhotos(array(
379 new Photo($this->url_prefix . 'get_profile_img.php?id='.$row['member_id'], 'thumbnail', true)));
381 $person->setUtcOffset(sprintf('%+03d:00', $row['time_zone'])); // force "-00:00" utc-offset format
382 if (! empty($row['drinker'])) {
383 $person->setDrinker($row['drinker']);
385 if (! empty($row['gender'])) {
386 $person->setGender(strtolower($row['gender']));
388 if (! empty($row['email'])){
389 //TODO: Assumed <static> object TYPE to be "home". Change it if ATutor starts accepting more than one email
390 $email = new Email(strtolower($row['email']), 'home');
391 $person->setEmails($email);
393 if (! empty($row['interests'])){
394 $strings = explode(',', $row['interests']);
395 $person->setInterests($strings);
398 //TODO: Not in ATutor yet, skeleton field
399 if (! empty($row['smoker'])) {
400 $person->setSmoker($row['smoker']);
402 /* the following fields require additional queries so are only executed if requested */
403 if (isset($fields['activities']) || isset($fields['@all'])) {
404 $activities = array();
405 $sql = "select title from ".TABLE_PREFIX."social_activities where member_id = " . $member_id;
406 $res2 = mysql_query($sql, $this->db);
408 while (list($activity) = mysql_fetch_row($res2)) {
409 $activities[] = $activity;
411 $person->setActivities($activities);
414 if (isset($fields['addresses']) || isset($fields['@all'])) {
415 $addresses = array();
416 $sql = "select address, postal, city, province, country from ".TABLE_PREFIX."members m where m.member_id = " . $member_id;
417 $res2 = mysql_query($sql, $this->db);
418 while ($row = mysql_fetch_assoc($res2)) {
419 if (empty($row['unstructured_address'])) {
420 $row['unstructured_address'] = trim($row['street_address'] . " " . $row['province'] . " " . $row['country']);
422 $addres = new Address($row['unstructured_address']);
423 $addres->setCountry($row['country']);
424 $addres->setLatitude($row['latitude']);
425 $addres->setLongitude($row['longitude']);
426 $addres->setLocality($row['locality']);
427 $addres->setPostalCode($row['postal_code']);
428 $addres->setRegion($row['province']);
429 $addres->setStreetAddress($row['street_address']);
430 $addres->setType($row['address_type']);
431 //FIXME quick and dirty hack to demo PC
432 $addres->setPrimary(true);
433 $addresses[] = $addres;
435 $person->setAddresses($addresses);
437 //TODO: Not in ATutor yet, skeleton field
438 if (isset($fields['bodyType']) || isset($fields['@all'])) {
439 $res2 = mysqli_query($db, "select * from ".TABLE_PREFIX."person_body_type where person_id = " . $person_id);
440 if (@mysqli_num_rows($res2)) {
441 $row = @mysql_fetch_array($res2, MYSQLI_ASSOC);
442 $bodyType = new BodyType();
443 $bodyType->setBuild($row['build']);
444 $bodyType->setEyeColor($row['eye_color']);
445 $bodyType->setHairColor($row['hair_color']);
446 $bodyType->setHeight($row['height']);
447 $bodyType->setWeight($row['weight']);
448 $person->setBodyType($bodyType);
451 //TODO: Not in ATutor yet, skeleton field
452 if (isset($fields['books']) || isset($fields['@all'])) {
454 $res2 = mysqli_query($db, "select book from ".TABLE_PREFIX."person_books where person_id = " . $person_id);
455 while (list($book) = @mysqli_fetch_row($res2)) {
458 $person->setBooks($books);
460 //TODO: Not in ATutor yet, skeleton field
461 if (isset($fields['cars']) || isset($fields['@all'])) {
463 $res2 = mysqli_query($db, "select car from ".TABLE_PREFIX."person_cars where person_id = " . $person_id);
464 while (list($car) = @mysqli_fetch_row($res2)) {
467 $person->setCars($cars);
469 //TODO: Not in ATutor yet, skeleton field
470 if (isset($fields['currentLocation']) || isset($fields['@all'])) {
471 $addresses = array();
472 $res2 = mysqli_query($db, "select a.* from ".TABLE_PREFIX."person_current_location pcl, ".TABLE_PREFIX."person_addresses pa, ".TABLE_PREFIX."addresses a where a.id = pcl.address_id and pa.person_id = " . $person_id);
473 if (@mysqli_num_rows($res2)) {
474 $row = mysqli_fetch_array($res2, MYSQLI_ASSOC);
475 if (empty($row['unstructured_address'])) {
476 $row['unstructured_address'] = trim($row['street_address'] . " " . $row['region'] . " " . $row['country']);
478 $addres = new Address($row['unstructured_address']);
479 $addres->setCountry($row['country']);
480 $addres->setLatitude($row['latitude']);
481 $addres->setLongitude($row['longitude']);
482 $addres->setLocality($row['locality']);
483 $addres->setPostalCode($row['postal_code']);
484 $addres->setRegion($row['region']);
485 $addres->setStreetAddress($row['street_address']);
486 $addres->setType($row['address_type']);
487 $person->setCurrentLocation($addres);
490 //TODO: Email is a singleton in ATutor, expand it. A person may have 1+ emails nowadays.
491 //added to the above with all the other member's properties
493 if (isset($fields['emails']) || isset($fields['@all'])) {
495 $sql = "select address, email_type from ".TABLE_PREFIX."person_emails where person_id = " . $person_id;
496 $res2 = mysql_query();
497 while (list($address, $type) = @mysqli_fetch_row($res2)) {
498 $emails[] = new Email(strtolower($address), $type); // TODO: better email canonicalization; remove dups
500 $person->setEmails($emails);
503 //TODO: Not in ATutor yet, skeleton field
504 if (isset($fields['food']) || isset($fields['@all'])) {
506 $res2 = mysqli_query($db, "select food from ".TABLE_PREFIX."person_foods where person_id = " . $person_id);
507 while (list($food) = @mysqli_fetch_row($res2)) {
510 $person->setFood($foods);
512 //TODO: Not in ATutor yet, skeleton field
513 if (isset($fields['heroes']) || isset($fields['@all'])) {
515 $res2 = mysqli_query($db, "select hero from ".TABLE_PREFIX."person_heroes where person_id = " . $person_id);
516 while (list($data) = @mysqli_fetch_row($res2)) {
519 $person->setHeroes($strings);
521 //Added with the above profile, interests is in CSV
523 if (isset($fields['interests']) || isset($fields['@all'])) {
525 $res2 = mysqli_query($db, "select interest from ".TABLE_PREFIX."person_interests where person_id = " . $person_id);
526 while (list($data) = @mysqli_fetch_row($res2)) {
529 $person->setInterests($strings);
532 $organizations = array();
534 if (isset($fields['jobs']) || isset($fields['@all'])) {
535 $sql = "SELECT * FROM ". TABLE_PREFIX . "social_member_position WHERE member_id = ".$member_id;
536 $res2 = mysql_query($sql, $this->db);
537 while ($row = mysql_fetch_assoc($res2)) {
538 $organization = new Organization();
539 $organization->setDescription($row['description']);
540 $organization->setEndDate($row['to']);
541 $organization->setField($row['field']);
542 $organization->setName($row['company']);
543 $organization->setSalary($row['salary']);
544 $organization->setStartDate($row['from']);
545 $organization->setSubField($row['sub_field']);
546 $organization->setTitle($row['title']);
547 $organization->setWebpage($row['webpage']);
548 $organization->setType('job');
550 //TODO: Address: To be implemented
552 if ($row['address_id']) {
553 $res3 = mysqli_query($db, "select * from ".TABLE_PREFIX."addresses where id = " . mysqli_real_escape_string($db, $row['address_id']));
554 if (mysqli_num_rows($res3)) {
555 $row = mysqli_fetch_array($res3, MYSQLI_ASSOC);
556 if (empty($row['unstructured_address'])) {
557 $row['unstructured_address'] = trim($row['street_address'] . " " . $row['region'] . " " . $row['country']);
559 $addres = new Address($row['unstructured_address']);
560 $addres->setCountry($row['country']);
561 $addres->setLatitude($row['latitude']);
562 $addres->setLongitude($row['longitude']);
563 $addres->setLocality($row['locality']);
564 $addres->setPostalCode($row['postal_code']);
565 $addres->setRegion($row['region']);
566 $addres->setStreetAddress($row['street_address']);
567 $addres->setType($row['address_type']);
568 $organization->setAddress($address);
572 $organizations[] = $organization;
576 if (isset($fields['schools']) || isset($fields['@all'])) {
577 $res2 = mysqli_query($db, "select o.* from ".TABLE_PREFIX."person_schools ps, ".TABLE_PREFIX."organizations o where o.id = ps.organization_id and ps.person_id = " . $person_id);
578 while ($row = mysqli_fetch_array($res2, MYSQLI_ASSOC)) {
579 $organization = new Organization();
580 $organization->setDescription($row['description']);
581 $organization->setEndDate($row['to']);
582 $organization->setField($row['field']);
583 $organization->setName($row['university']);
584 $organization->setSalary($row['salary']);
585 $organization->setStartDate($row['from']);
586 $organization->setSubField($row['sub_field']);
587 $organization->setTitle($row['degree']);
588 $organization->setWebpage($row['webpage']);
589 $organization->setType($row['school']);
590 //TODO: Address: To be implemented
592 if ($row['address_id']) {
593 $res3 = mysqli_query($db, "select * from ".TABLE_PREFIX."addresses where id = " . mysqli_real_escape_string($db, $row['address_id']));
594 if (mysqli_num_rows($res3)) {
595 $row = mysqli_fetch_array($res3, MYSQLI_ASSOC);
596 if (empty($row['unstructured_address'])) {
597 $row['unstructured_address'] = trim($row['street_address'] . " " . $row['region'] . " " . $row['country']);
599 $addres = new Address($row['unstructured_address']);
600 $addres->setCountry($row['country']);
601 $addres->setLatitude($row['latitude']);
602 $addres->setLongitude($row['longitude']);
603 $addres->setLocality($row['locality']);
604 $addres->setPostalCode($row['postal_code']);
605 $addres->setRegion($row['region']);
606 $addres->setStreetAddress($row['street_address']);
607 $addres->setType($row['address_type']);
608 $organization->setAddress($address);
612 $organizations[] = $organization;
617 $person->setOrganizations($organizations);
619 //TODO languagesSpoken, currently missing the languages / countries tables so can't do this yet
620 //TODO: Not in ATutor yet, skeleton field
621 if (isset($fields['movies']) || isset($fields['@all'])) {
623 $res2 = mysqli_query($db, "select movie from ".TABLE_PREFIX."person_movies where person_id = " . $person_id);
624 while (list($data) = @mysqli_fetch_row($res2)) {
627 $person->setMovies($strings);
629 if (isset($fields['music']) || isset($fields['@all'])) {
631 $res2 = mysqli_query($db, "select music from ".TABLE_PREFIX."person_music where person_id = " . $person_id);
632 while (list($data) = @mysqli_fetch_row($res2)) {
635 $person->setMusic($strings);
637 if (isset($fields['phoneNumbers']) || isset($fields['@all'])) {
639 $res2 = mysqli_query($db, "select number, number_type from ".TABLE_PREFIX."person_phone_numbers where person_id = " . $person_id);
640 while (list($number, $type) = @mysqli_fetch_row($res2)) {
641 $numbers[] = new Phone($number, $type);
643 $person->setPhoneNumbers($numbers);
645 if (isset($fields['ims']) || isset($fields['@all'])) {
647 $res2 = mysqli_query($db, "select value, value_type from ".TABLE_PREFIX."person_ims where person_id = " . $person_id);
648 while (list($value, $type) = @mysqli_fetch_row($res2)) {
649 $ims[] = new Im($value, $type);
651 $person->setIms($ims);
653 if (isset($fields['accounts']) || isset($fields['@all'])) {
655 $res2 = mysqli_query($db, "select domain, userid, username from ".TABLE_PREFIX."person_accounts where person_id = " . $person_id);
656 while (list($domain, $userid, $username) = @mysqli_fetch_row($res2)) {
657 $accounts[] = new Account($domain, $userid, $username);
659 $person->setAccounts($accounts);
661 if (isset($fields['quotes']) || isset($fields['@all'])) {
663 $res2 = mysqli_query($db, "select quote from ".TABLE_PREFIX."person_quotes where person_id = " . $person_id);
664 while (list($data) = @mysqli_fetch_row($res2)) {
667 $person->setQuotes($strings);
669 if (isset($fields['sports']) || isset($fields['@all'])) {
671 $res2 = mysqli_query($db, "select sport from ".TABLE_PREFIX."person_sports where person_id = " . $person_id);
672 while (list($data) = @mysqli_fetch_row($res2)) {
675 $person->setSports($strings);
677 if (isset($fields['tags']) || isset($fields['@all'])) {
679 $res2 = mysqli_query($db, "select tag from ".TABLE_PREFIX."person_tags where person_id = " . $person_id);
680 while (list($data) = @mysqli_fetch_row($res2)) {
683 $person->setTags($strings);
686 if (isset($fields['turnOns']) || isset($fields['@all'])) {
688 $res2 = mysqli_query($db, "select turn_on from ".TABLE_PREFIX."person_turn_ons where person_id = " . $person_id);
689 while (list($data) = @mysqli_fetch_row($res2)) {
692 $person->setTurnOns($strings);
694 if (isset($fields['turnOffs']) || isset($fields['@all'])) {
696 $res2 = mysqli_query($db, "select turn_off from ".TABLE_PREFIX."person_turn_offs where person_id = " . $person_id);
697 while (list($data) = @mysqli_fetch_row($res2)) {
700 $person->setTurnOffs($strings);
702 if (isset($fields['urls']) || isset($fields['@all'])) {
704 $res2 = mysqli_query($db, "select url from ".TABLE_PREFIX."person_urls where person_id = " . $person_id);
705 while (list($data) = @mysqli_fetch_row($res2)) {
706 $strings[] = new Url($data, null, null);
708 $strings[] = new Url($this->url_prefix . '/profile/' . $member_id, null, 'profile'); // always include profile URL
709 $person->setUrls($strings);
711 $ret[$member_id] = $person;
716 $ret = $this->filterResults($ret, $options);
717 $ret['totalSize'] = count($ret);
718 } catch(Exception $e) {
719 $ret['totalSize'] = count($ret) - 1;
720 $ret['filtered'] = 'false';
722 if ($first !== false && $max !== false && is_numeric($first) && is_numeric($max) && $first >= 0 && $max > 0) {
725 foreach ($ret as $id => $person) {
726 if ($id == 'totalSize' || $id == 'filtered') {
727 $result[$id] = $person;
730 if ($count >= $first && $count < $first + $max) {
731 $result[$id] = $person;
741 private function filterResults($peopleById, $options) {
742 if (! $options->getFilterBy()) {
743 return $peopleById; // no filtering specified
745 $filterBy = $options->getFilterBy();
746 $op = $options->getFilterOperation();
748 $op = CollectionOptions::FILTER_OP_EQUALS; // use this container-specific default
750 $value = $options->getFilterValue();
751 $filteredResults = array();
752 $numFilteredResults = 0;
753 foreach ($peopleById as $id => $person) {
754 if ($person instanceof Person) {
755 if ($this->passesFilter($person, $filterBy, $op, $value)) {
756 $filteredResults[$id] = $person;
757 $numFilteredResults ++;
760 $filteredResults[$id] = $person; // copy extra metadata verbatim
763 if (! isset($filteredResults['totalSize'])) {
764 $filteredResults['totalSize'] = $numFilteredResults;
766 return $filteredResults;
769 private function passesFilter($person, $filterBy, $op, $value) {
770 $fieldValue = $person->getFieldByName($filterBy);
771 if ($fieldValue instanceof ComplexField) {
772 $fieldValue = $fieldValue->getPrimarySubValue();
774 if (! $fieldValue || (is_array($fieldValue) && ! count($fieldValue))) {
775 return false; // person is missing the field being filtered for
777 if ($op == CollectionOptions::FILTER_OP_PRESENT) {
778 return true; // person has a non-empty value for the requested field
781 return false; // can't do an equals/startswith/contains filter on an empty filter value
783 // grab string value for comparison
784 if (is_array($fieldValue)) {
785 // plural fields match if any instance of that field matches
786 foreach ($fieldValue as $field) {
787 if ($field instanceof ComplexField) {
788 $field = $field->getPrimarySubValue();
790 if ($this->passesStringFilter($field, $op, $value)) {
795 return $this->passesStringFilter($fieldValue, $op, $value);
800 private function passesStringFilter($fieldValue, $op, $filterValue) {
802 case CollectionOptions::FILTER_OP_EQUALS:
803 return $fieldValue == $filterValue;
804 case CollectionOptions::FILTER_OP_CONTAINS:
805 return stripos($fieldValue, $filterValue) !== false;
806 case CollectionOptions::FILTER_OP_STARTSWITH:
807 return stripos($fieldValue, $filterValue) === 0;
809 throw new Exception('unrecognized filterOp');