function create_user($arr) { // Required: { username, nickname, email } or { openid_url } $a = get_app(); $result = array('success' => false, 'user' => null, 'password' => '', 'message' => ''); $using_invites = get_config('system', 'invitation_only'); $num_invites = get_config('system', 'number_invites'); $invite_id = x($arr, 'invite_id') ? notags(trim($arr['invite_id'])) : ''; $username = x($arr, 'username') ? notags(trim($arr['username'])) : ''; $nickname = x($arr, 'nickname') ? notags(trim($arr['nickname'])) : ''; $email = x($arr, 'email') ? notags(trim($arr['email'])) : ''; $openid_url = x($arr, 'openid_url') ? notags(trim($arr['openid_url'])) : ''; $photo = x($arr, 'photo') ? notags(trim($arr['photo'])) : ''; $password = x($arr, 'password') ? trim($arr['password']) : ''; $blocked = x($arr, 'blocked') ? intval($arr['blocked']) : 0; $verified = x($arr, 'verified') ? intval($arr['verified']) : 0; $publish = x($arr, 'profile_publish_reg') && intval($arr['profile_publish_reg']) ? 1 : 0; $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0; $tmp_str = $openid_url; if ($using_invites) { if (!$invite_id) { $result['message'] .= t('An invitation is required.') . EOL; return $result; } $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); if (!results($r)) { $result['message'] .= t('Invitation could not be verified.') . EOL; return $result; } } if (!x($username) || !x($email) || !x($nickname)) { if ($openid_url) { if (!validate_url($tmp_str)) { $result['message'] .= t('Invalid OpenID url') . EOL; return $result; } $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; require_once 'library/openid.php'; $openid = new LightOpenID(); $openid->identity = $openid_url; $openid->returnUrl = $a->get_baseurl() . '/openid'; $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default'); try { $authurl = $openid->authUrl(); } catch (Exception $e) { $result['message'] .= t("We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.") . EOL . EOL . t("The error message was:") . $e->getMessage() . EOL; return $result; } goaway($authurl); // NOTREACHED } notice(t('Please enter the required information.') . EOL); return; } if (!validate_url($tmp_str)) { $openid_url = ''; } $err = ''; // collapse multiple spaces in name $username = preg_replace('/ +/', ' ', $username); if (mb_strlen($username) > 48) { $result['message'] .= t('Please use a shorter name.') . EOL; } if (mb_strlen($username) < 3) { $result['message'] .= t('Name too short.') . EOL; } // I don't really like having this rule, but it cuts down // on the number of auto-registrations by Russian spammers // Using preg_match was completely unreliable, due to mixed UTF-8 regex support // $no_utf = get_config('system','no_utf'); // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); // So now we are just looking for a space in the full name. $loose_reg = get_config('system', 'no_regfullname'); if (!$loose_reg) { $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8'); if (!strpos($username, ' ')) { $result['message'] .= t("That doesn't appear to be your full (First Last) name.") . EOL; } } if (!allowed_email($email)) { $result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL; } if (!valid_email($email) || !validate_email($email)) { $result['message'] .= t('Not a valid email address.') . EOL; } // Disallow somebody creating an account using openid that uses the admin email address, // since openid bypasses email verification. We'll allow it if there is not yet an admin account. $adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email']))); //if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) { if (x($a->config, 'admin_email') && in_array(strtolower($email), $adminlist) && strlen($openid_url)) { $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email)); if (count($r)) { $result['message'] .= t('Cannot use that email.') . EOL; } } $nickname = $arr['nickname'] = strtolower($nickname); if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) { $result['message'] .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL; } $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; } // Check deleted accounts that had this nickname. Doesn't matter to us, // but could be a security issue for federated platforms. $r = q("SELECT * FROM `userd`\n \tWHERE `username` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL; } if (strlen($result['message'])) { return $result; } $new_password = strlen($password) ? $password : autoname(6) . mt_rand(100, 9999); $new_password_encoded = hash('whirlpool', $new_password); $result['password'] = $new_password; require_once 'include/crypto.php'; $keys = new_keypair(4096); if ($keys === false) { $result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL; return $result; } $default_service_class = get_config('system', 'default_service_class'); if (!$default_service_class) { $default_service_class = ''; } $prvkey = $keys['prvkey']; $pubkey = $keys['pubkey']; /** * * Create another keypair for signing/verifying * salmon protocol messages. We have to use a slightly * less robust key because this won't be using openssl * but the phpseclib. Since it is PHP interpreted code * it is not nearly as efficient, and the larger keys * will take several minutes each to process. * */ $sres = new_keypair(512); $sprvkey = $sres['prvkey']; $spubkey = $sres['pubkey']; $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `service_class`, `default-location` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '%s', '' )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked), dbesc($default_service_class)); if ($r) { $r = q("SELECT * FROM `user`\n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded)); if ($r !== false && count($r)) { $u = $r[0]; $newuid = intval($r[0]['uid']); } } else { $result['message'] .= t('An error occurred during registration. Please try again.') . EOL; return $result; } /** * if somebody clicked submit twice very quickly, they could end up with two accounts * due to race condition. Remove this one. */ $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' ", dbesc($nickname)); if (count($r) > 1 && $newuid) { $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return $result; } if (x($newuid) !== false) { $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), t('default'), 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish)); if ($r === false) { $result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL; // Start fresh next time. $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return $result; } $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert())); // Create a group with no members. This allows somebody to use it // right away as a default group for new contacts. require_once 'include/group.php'; group_add($newuid, t('Friends')); $r = q("SELECT id FROM `group` WHERE uid = %d AND name = '%s'", intval($newuid), dbesc(t('Friends'))); if ($r && count($r)) { $def_gid = $r[0]['id']; q("UPDATE user SET def_gid = %d WHERE uid = %d", intval($r[0]['id']), intval($newuid)); } if (get_config('system', 'newuser_private') && $def_gid) { q("UPDATE user SET allow_gid = '%s' WHERE uid = %d", dbesc("<" . $def_gid . ">"), intval($newuid)); } } // if we have no OpenID photo try to look up an avatar if (!strlen($photo)) { $photo = avatar_img($email); } // unless there is no avatar-plugin loaded if (strlen($photo)) { require_once 'include/Photo.php'; $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); // guess mimetype from headers or filename $type = guess_image_type($photo, true); $img = new Photo($img_str, $type); if ($img->is_valid()) { $img->scaleImageSquare(175); $hash = photo_new_resource(); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6); if ($r === false) { $photo_failure = true; } if (!$photo_failure) { q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash)); } } } call_hooks('register_account', $newuid); $result['success'] = true; $result['user'] = $u; return $result; }
function wall_upload_post(&$a) { if (!local_user()) { echo t('Permission denied.') . EOL; killme(); } if (!x($_FILES, 'userfile')) { killme(); } $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!($image = $ph->getImage())) { echo t('Unable to process image.') . EOL; @unlink($src); killme(); } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = hash('md5', uniqid(mt_rand(), true)); $smallest = 0; $r = $ph->store(0, $hash, $filename, t('Wall Photos'), 0); if (!$r) { echo t('Image upload failed.') . EOL; killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store(0, $hash, $filename, t('Wall Photos'), 1); if ($r) { $smallest = 1; } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store(0, $hash, $filename, t('Wall Photos'), 2); if ($r) { $smallest = 2; } } $basename = basename($filename); echo "<br /><br /><img src=\"" . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg\" alt=\"{$basename}\" /><br /><br />"; killme(); return; // NOTREACHED }
function privacy_image_cache_init() { $urlhash = 'pic:' . sha1($_REQUEST['url']); $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' LIMIT 1", $urlhash); if (count($r)) { $img_str = $r[0]['data']; $mime = $r[0]["desc"]; if ($mime == "") { $mime = "image/jpeg"; } } else { require_once "Photo.php"; $img_str = fetch_url($_REQUEST['url'], true); if (substr($img_str, 0, 6) == "GIF89a") { $mime = "image/gif"; $image = @imagecreatefromstring($img_str); if ($image === FALSE) { die; } q("INSERT INTO `photo`\n\t\t\t( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, `album`, `height`, `width`, `desc`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )\n\t\t\tVALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' )", 0, 0, get_guid(), dbesc($urlhash), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(basename(dbesc($_REQUEST["url"]))), dbesc(''), intval(imagesy($image)), intval(imagesx($image)), 'image/gif', dbesc($img_str), 100, intval(0), dbesc(''), dbesc(''), dbesc(''), dbesc('')); } else { $img = new Photo($img_str); if ($img->is_valid()) { $img->store(0, 0, $urlhash, $_REQUEST['url'], '', 100); $img_str = $img->imageString(); } $mime = "image/jpeg"; } } header("Content-type: {$mime}"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600 * 24) . " GMT"); header("Cache-Control: max-age=" . 3600 * 24); echo $img_str; killme(); }
function import_profile_photo($photo, $uid, $cid) { $a = get_app(); $r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1", intval($uid), intval($cid)); if (count($r) && strlen($r[0]['resource-id'])) { $hash = $r[0]['resource-id']; } else { $hash = photo_new_resource(); } $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); $type = guess_image_type($photo, true); $img = new Photo($img_str, $type); if ($img->is_valid()) { $img->scaleImageSquare(175); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6); if ($r === false) { $photo_failure = true; } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt(); $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt(); $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt(); } else { $photo_failure = true; } if ($photo_failure) { $photo = $a->get_baseurl() . '/images/person-175.jpg'; $thumb = $a->get_baseurl() . '/images/person-80.jpg'; $micro = $a->get_baseurl() . '/images/person-48.jpg'; } return array($photo, $thumb, $micro); }
function run_submit($url) { global $a; if (!strlen($url)) { return false; } logger('Updating: ' . $url); //First run a notice script for the site it is hosted on. $site_health = notice_site($url, true); $submit_start = microtime(true); $nurl = str_replace(array('https:', '//www.'), array('http:', '//'), $url); $profile_exists = false; $r = q("SELECT * FROM `profile` WHERE ( `homepage` = '%s' OR `nurl` = '%s' )", dbesc($url), dbesc($nurl)); if (count($r)) { $profile_exists = true; $profile_id = $r[0]['id']; } //Remove duplicates. if (count($r) > 1) { for ($i = 1; $i < count($r); $i++) { logger('Removed duplicate profile ' . intval($r[$i]['id'])); q("DELETE FROM `photo` WHERE `profile-id` = %d LIMIT 1", intval($r[$i]['id'])); q("DELETE FROM `profile` WHERE `id` = %d LIMIT 1", intval($r[$i]['id'])); } } require_once 'Scrape.php'; //Skip the scrape? :D $noscrape = $site_health && $site_health['no_scrape_url']; if ($noscrape) { //Find out who to look up. $which = str_replace($site_health['base_url'], '', $url); $noscrape = preg_match('~/profile/([^/]+)~', $which, $matches) === 1; //If that did not fail... if ($noscrape) { $parms = noscrape_dfrn($site_health['no_scrape_url'] . '/' . $matches[1]); $noscrape = !!$parms; //If the result was false, do a scrape after all. } } if (!$noscrape) { $parms = scrape_dfrn($url); } //Empty result is due to an offline site. if (!count($parms)) { //For large sites this could lower the health too quickly, so don't track health. //But for sites that are already in bad status. Do a cleanup now. if ($profile_exists && $site_health['health_score'] < $a->config['maintenance']['remove_profile_health_threshold']) { logger('Nuked bad health record.'); nuke_record($url); } return false; } elseif ($parms['explicit-hide'] && $profile_exists) { logger('User opted out of the directory.'); nuke_record($url); return true; //This is a good update. } elseif (validate_dfrn($parms)) { return false; } if (x($parms, 'hide') || !x($parms, 'fn') && x($parms, 'photo')) { if ($profile_exists) { nuke_record($url); } return true; //This is a good update. } $photo = $parms['photo']; dbesc_array($parms); if (x($parms, 'comm')) { $parms['comm'] = intval($parms['comm']); } if ($profile_exists) { $r = q("UPDATE `profile` SET \n\t\t\t`name` = '%s', \n\t\t\t`pdesc` = '%s',\n\t\t\t`locality` = '%s', \n\t\t\t`region` = '%s', \n\t\t\t`postal-code` = '%s', \n\t\t\t`country-name` = '%s', \n\t\t\t`gender` = '%s', \n\t\t\t`marital` = '%s', \n\t\t\t`homepage` = '%s',\n\t\t\t`nurl` = '%s',\n\t\t\t`comm` = %d,\n\t\t\t`tags` = '%s',\n\t\t\t`updated` = '%s' \n\t\t\tWHERE `id` = %d LIMIT 1", $parms['fn'], $parms['pdesc'], $parms['locality'], $parms['region'], $parms['postal-code'], $parms['country-name'], $parms['gender'], $parms['marital'], dbesc($url), dbesc($nurl), intval($parms['comm']), $parms['tags'], dbesc(datetime_convert()), intval($profile_id)); logger('Update returns: ' . $r); } else { $r = q("INSERT INTO `profile` ( `name`, `pdesc`, `locality`, `region`, `postal-code`, `country-name`, `gender`, `marital`, `homepage`, `nurl`, `comm`, `tags`, `created`, `updated` )\n\t\t\tVALUES ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s' )", $parms['fn'], $parms['pdesc'], $parms['locality'], $parms['region'], $parms['postal-code'], $parms['country-name'], $parms['gender'], $parms['marital'], dbesc($url), dbesc($nurl), intval($parms['comm']), $parms['tags'], dbesc(datetime_convert()), dbesc(datetime_convert())); logger('Insert returns: ' . $r); $r = q("SELECT `id` FROM `profile` WHERE ( `homepage` = '%s' or `nurl` = '%s' ) order by id asc", dbesc($url), dbesc($nurl)); if (count($r)) { $profile_id = $r[count($r) - 1]['id']; } if (count($r) > 1) { q("DELETE FROM `photo` WHERE `profile-id` = %d LIMIT 1", intval($r[0]['id'])); q("DELETE FROM `profile` WHERE `id` = %d LIMIT 1", intval($r[0]['id'])); } } if ($parms['tags']) { $arr = explode(' ', $parms['tags']); if (count($arr)) { foreach ($arr as $t) { $t = strip_tags(trim($t)); $t = substr($t, 0, 254); if (strlen($t)) { $r = q("SELECT `id` FROM `tag` WHERE `term` = '%s' and `nurl` = '%s' LIMIT 1", dbesc($t), dbesc($nurl)); if (!count($r)) { $r = q("INSERT INTO `tag` (`term`, `nurl`) VALUES ('%s', '%s') ", dbesc($t), dbesc($nurl)); } } } } } $submit_photo_start = microtime(true); require_once "Photo.php"; $photo_failure = false; $status = false; if ($profile_id) { $img_str = fetch_url($photo, true); $img = new Photo($img_str); if ($img) { $img->scaleImageSquare(80); $r = $img->store($profile_id); } $r = q("UPDATE `profile` SET `photo` = '%s' WHERE `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/photo/' . $profile_id . '.jpg'), intval($profile_id)); $status = true; } else { nuke_record($url); return false; } $submit_end = microtime(true); $photo_time = round(($submit_end - $submit_photo_start) * 1000); $time = round(($submit_end - $submit_start) * 1000); //Record the scrape speed in a scrapes table. if ($site_health && $status) { q("INSERT INTO `site-scrape` (`site_health_id`, `dt_performed`, `request_time`, `scrape_time`, `photo_time`, `total_time`)" . "VALUES (%u, NOW(), %u, %u, %u, %u)", $site_health['id'], $parms['_timings']['fetch'], $parms['_timings']['scrape'], $photo_time, $time); } return $status; }
function photos_post(&$a) { logger('mod-photos: photos_post: begin', LOGGER_DEBUG); logger('mod_photos: REQUEST ' . print_r($_REQUEST, true), LOGGER_DATA); logger('mod_photos: FILES ' . print_r($_FILES, true), LOGGER_DATA); $can_post = false; $visitor = 0; $page_owner_uid = $a->data['user']['uid']; $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $page_owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid)); if (count($r)) { $can_post = true; $visitor = remote_user(); } } } if (!$can_post) { notice(t('Permission denied.') . EOL); killme(); } $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` \n\t\tWHERE `user`.`uid` = %d AND `self` = 1 LIMIT 1", intval($page_owner_uid)); if (!count($r)) { notice(t('Contact information unavailable') . EOL); logger('photos_post: unable to locate contact record for page owner. uid=' . $page_owner_uid); killme(); } $owner_record = $r[0]; if ($a->argc > 3 && $a->argv[2] === 'album') { $album = hex2bin($a->argv[3]); if ($album === t('Profile Photos') || $album === 'Contact Photos' || $album === t('Contact Photos')) { goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $r = q("SELECT count(*) FROM `photo` WHERE `album` = '%s' AND `uid` = %d", dbesc($album), intval($page_owner_uid)); if (!count($r)) { notice(t('Album not found.') . EOL); goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $newalbum = notags(trim($_POST['albumname'])); if ($newalbum != $album) { q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d", dbesc($newalbum), dbesc($album), intval($page_owner_uid)); $newurl = str_replace(bin2hex($album), bin2hex($newalbum), $_SESSION['photo_return']); goaway($a->get_baseurl() . '/' . $newurl); return; // NOTREACHED } if ($_POST['dropalbum'] == t('Delete Album')) { $res = array(); // get the list of photos we are about to delete if ($visitor) { $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d AND `album` = '%s'", intval($visitor), intval($page_owner_uid), dbesc($album)); } else { $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = %d AND `album` = '%s'", intval(local_user()), dbesc($album)); } if (count($r)) { foreach ($r as $rr) { $res[] = "'" . dbesc($rr['rid']) . "'"; } } else { goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $str_res = implode(',', $res); // remove the associated photos q("DELETE FROM `photo` WHERE `resource-id` IN ( {$str_res} ) AND `uid` = %d", intval($page_owner_uid)); // find and delete the corresponding item with all the comments and likes/dislikes $r = q("SELECT `parent-uri` FROM `item` WHERE `resource-id` IN ( {$str_res} ) AND `uid` = %d", intval($page_owner_uid)); if (count($r)) { foreach ($r as $rr) { q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($rr['parent-uri']), intval($page_owner_uid)); $drop_id = intval($rr['id']); // send the notification upstream/downstream as the case may be if ($rr['visible']) { proc_run('php', "include/notifier.php", "drop", "{$drop_id}"); } } } } goaway($a->get_baseurl() . '/photos/' . $a->data['user']['nickname']); return; // NOTREACHED } if ($a->argc > 2 && x($_POST, 'delete') && $_POST['delete'] == t('Delete Photo')) { // same as above but remove single photo if ($visitor) { $r = q("SELECT `id`, `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d AND `resource-id` = '%s' LIMIT 1", intval($visitor), intval($page_owner_uid), dbesc($a->argv[2])); } else { $r = q("SELECT `id`, `resource-id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' LIMIT 1", intval(local_user()), dbesc($a->argv[2])); } if (count($r)) { q("DELETE FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'", intval($page_owner_uid), dbesc($r[0]['resource-id'])); $i = q("SELECT * FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1", dbesc($r[0]['resource-id']), intval($page_owner_uid)); if (count($i)) { q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($i[0]['uri']), intval($page_owner_uid)); $url = $a->get_baseurl(); $drop_id = intval($i[0]['id']); if ($i[0]['visible']) { proc_run('php', "include/notifier.php", "drop", "{$drop_id}"); } } } goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } if ($a->argc > 2 && (x($_POST, 'desc') !== false || x($_POST, 'newtag') !== false) || x($_POST, 'albname') !== false) { $desc = x($_POST, 'desc') ? notags(trim($_POST['desc'])) : ''; $rawtags = x($_POST, 'newtag') ? notags(trim($_POST['newtag'])) : ''; $item_id = x($_POST, 'item_id') ? intval($_POST['item_id']) : 0; $albname = x($_POST, 'albname') ? notags(trim($_POST['albname'])) : ''; $str_group_allow = perms2str($_POST['group_allow']); $str_contact_allow = perms2str($_POST['contact_allow']); $str_group_deny = perms2str($_POST['group_deny']); $str_contact_deny = perms2str($_POST['contact_deny']); $resource_id = $a->argv[2]; if (!strlen($albname)) { $albname = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); } if (x($_POST, 'rotate') !== false && intval($_POST['rotate']) == 1) { logger('rotate'); $r = q("select * from photo where `resource-id` = '%s' and uid = %d and scale = 0 limit 1", dbesc($resource_id), intval($page_owner_uid)); if (count($r)) { $ph = new Photo($r[0]['data']); if ($ph->is_valid()) { $ph->rotate(270); $width = $ph->getWidth(); $height = $ph->getHeight(); $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 0 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid)); if ($width > 640 || $height > 640) { $ph->scaleImage(640); $width = $ph->getWidth(); $height = $ph->getHeight(); $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 1 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid)); } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $width = $ph->getWidth(); $height = $ph->getHeight(); $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 2 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid)); } } } } $p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ORDER BY `scale` DESC", dbesc($resource_id), intval($page_owner_uid)); if (count($p)) { $r = q("UPDATE `photo` SET `desc` = '%s', `album` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource-id` = '%s' AND `uid` = %d", dbesc($desc), dbesc($albname), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), dbesc($resource_id), intval($page_owner_uid)); } /* Don't make the item visible if the only change was the album name */ $visibility = 0; if ($p[0]['desc'] !== $desc || strlen($rawtags)) { $visibility = 1; } if (!$item_id) { // Create item container $title = ''; $uri = item_new_uri($a->get_hostname(), $page_owner_uid); $arr = array(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; $arr['type'] = 'photo'; $arr['wall'] = 1; $arr['resource-id'] = $p[0]['resource-id']; $arr['contact-id'] = $owner_record['id']; $arr['owner-name'] = $owner_record['name']; $arr['owner-link'] = $owner_record['url']; $arr['owner-avatar'] = $owner_record['thumb']; $arr['author-name'] = $owner_record['name']; $arr['author-link'] = $owner_record['url']; $arr['author-avatar'] = $owner_record['thumb']; $arr['title'] = $title; $arr['allow_cid'] = $p[0]['allow_cid']; $arr['allow_gid'] = $p[0]['allow_gid']; $arr['deny_cid'] = $p[0]['deny_cid']; $arr['deny_gid'] = $p[0]['deny_gid']; $arr['last-child'] = 1; $arr['visible'] = $visibility; $arr['origin'] = 1; $arr['body'] = '[url=' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . $a->get_baseurl() . '/photo/' . $p[0]['resource-id'] . '-' . $p[0]['scale'] . '.jpg' . '[/img]' . '[/url]'; $item_id = item_store($arr); } if ($item_id) { $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item_id), intval($page_owner_uid)); } if (count($r)) { $old_tag = $r[0]['tag']; $old_inform = $r[0]['inform']; } if (strlen($rawtags)) { $str_tags = ''; $inform = ''; // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a hashtag $x = substr($rawtags, 0, 1); if ($x !== '@' && $x !== '#') { $rawtags = '#' . $rawtags; } $taginfo = array(); $tags = get_tags($rawtags); if (count($tags)) { foreach ($tags as $tag) { if (isset($profile)) { unset($profile); } if (strpos($tag, '@') === 0) { $name = substr($tag, 1); if (strpos($name, '@') || strpos($name, 'http://')) { $newname = $name; $links = @lrdd($name); if (count($links)) { foreach ($links as $link) { if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') { $profile = $link['@attributes']['href']; } if ($link['@attributes']['rel'] === 'salmon') { $salmon = '$url:' . str_replace(',', '%sc', $link['@attributes']['href']); if (strlen($inform)) { $inform .= ','; } $inform .= $salmon; } } } $taginfo[] = array($newname, $profile, $salmon); } else { $newname = $name; $alias = ''; $tagcid = 0; if (strrpos($newname, '+')) { $tagcid = intval(substr($newname, strrpos($newname, '+') + 1)); } if ($tagcid) { $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($tagcid), intval($profile_uid)); } elseif (strstr($name, '_') || strstr($name, ' ')) { $newname = str_replace('_', ' ', $name); $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", dbesc($newname), intval($page_owner_uid)); } else { $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", dbesc($name), dbesc($name), intval($page_owner_uid)); } if (count($r)) { $newname = $r[0]['name']; $profile = $r[0]['url']; $notify = 'cid:' . $r[0]['id']; if (strlen($inform)) { $inform .= ','; } $inform .= $notify; } } if ($profile) { if (substr($notify, 0, 4) === 'cid:') { $taginfo[] = array($newname, $profile, $notify, $r[0], '@[url=' . str_replace(',', '%2c', $profile) . ']' . $newname . '[/url]'); } else { $taginfo[] = array($newname, $profile, $notify, null, $str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]'); } if (strlen($str_tags)) { $str_tags .= ','; } $profile = str_replace(',', '%2c', $profile); $str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]'; } } } } $newtag = $old_tag; if (strlen($newtag) && strlen($str_tags)) { $newtag .= ','; } $newtag .= $str_tags; $newinform = $old_inform; if (strlen($newinform) && strlen($inform)) { $newinform .= ','; } $newinform .= $inform; $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($newtag), dbesc($newinform), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item_id), intval($page_owner_uid)); $best = 0; foreach ($p as $scales) { if (intval($scales['scale']) == 2) { $best = 2; break; } if (intval($scales['scale']) == 4) { $best = 4; break; } } if (count($taginfo)) { foreach ($taginfo as $tagged) { $uri = item_new_uri($a->get_hostname(), $page_owner_uid); $arr = array(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; $arr['type'] = 'activity'; $arr['wall'] = 1; $arr['contact-id'] = $owner_record['id']; $arr['owner-name'] = $owner_record['name']; $arr['owner-link'] = $owner_record['url']; $arr['owner-avatar'] = $owner_record['thumb']; $arr['author-name'] = $owner_record['name']; $arr['author-link'] = $owner_record['url']; $arr['author-avatar'] = $owner_record['thumb']; $arr['title'] = ''; $arr['allow_cid'] = $p[0]['allow_cid']; $arr['allow_gid'] = $p[0]['allow_gid']; $arr['deny_cid'] = $p[0]['deny_cid']; $arr['deny_gid'] = $p[0]['deny_gid']; $arr['last-child'] = 1; $arr['visible'] = 1; $arr['verb'] = ACTIVITY_TAG; $arr['object-type'] = ACTIVITY_OBJ_PERSON; $arr['target-type'] = ACTIVITY_OBJ_PHOTO; $arr['tag'] = $tagged[4]; $arr['inform'] = $tagged[2]; $arr['origin'] = 1; $arr['body'] = '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]' . ' ' . t('was tagged in a') . ' ' . '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . t('photo') . '[/url]' . ' ' . t('by') . ' ' . '[url=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/url]'; $arr['body'] .= "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . $a->get_baseurl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.jpg' . '[/img][/url]' . "\n"; $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>'; $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n"); if ($tagged[3]) { $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $tagged[3]['photo'] . '" />' . "\n"); } $arr['object'] .= '</link></object>' . "\n"; $arr['target'] = '<target><type>' . ACTIVITY_OBJ_PHOTO . '</type><title>' . $p[0]['desc'] . '</title><id>' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>'; $arr['target'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="image/jpeg" href="' . $a->get_baseurl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.jpg' . '" />') . '</link></target>'; $item_id = item_store($arr); if ($item_id) { q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), intval($page_owner_uid), intval($item_id)); proc_run('php', "include/notifier.php", "tag", "{$item_id}"); } } } } goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } /** * default post action - upload a photo */ call_hooks('photo_post_init', $_POST); /** * Determine the album to use */ $album = notags(trim($_REQUEST['album'])); $newalbum = notags(trim($_REQUEST['newalbum'])); logger('mod/photos.php: photos_post(): album= ' . $album . ' newalbum= ' . $newalbum, LOGGER_DEBUG); if (!strlen($album)) { if (strlen($newalbum)) { $album = $newalbum; } else { $album = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); } } /** * * We create a wall item for every photo, but we don't want to * overwhelm the data stream with a hundred newly uploaded photos. * So we will make the first photo uploaded to this album in the last several hours * visible by default, the rest will become visible over time when and if * they acquire comments, likes, dislikes, and/or tags * */ $r = q("SELECT * FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `created` > UTC_TIMESTAMP() - INTERVAL 3 HOUR ", dbesc($album), intval($page_owner_uid)); if (!count($r) || $album == t('Profile Photos')) { $visible = 1; } else { $visible = 0; } if (intval($_REQUEST['not_visible']) || $_REQUEST['not_visible'] === 'true') { $visible = 0; } $str_group_allow = perms2str(is_array($_REQUEST['group_allow']) ? $_REQUEST['group_allow'] : explode(',', $_REQUEST['group_allow'])); $str_contact_allow = perms2str(is_array($_REQUEST['contact_allow']) ? $_REQUEST['contact_allow'] : explode(',', $_REQUEST['contact_allow'])); $str_group_deny = perms2str(is_array($_REQUEST['group_deny']) ? $_REQUEST['group_deny'] : explode(',', $_REQUEST['group_deny'])); $str_contact_deny = perms2str(is_array($_REQUEST['contact_deny']) ? $_REQUEST['contact_deny'] : explode(',', $_REQUEST['contact_deny'])); $ret = array('src' => '', 'filename' => '', 'filesize' => 0); call_hooks('photo_post_file', $ret); if (x($ret, 'src') && x($ret, 'filesize')) { $src = $ret['src']; $filename = $ret['filename']; $filesize = $ret['filesize']; } else { $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); } logger('photos: upload: received file: ' . $filename . ' as ' . $src . ' ' . $filesize . ' bytes', LOGGER_DEBUG); $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { notice(t('Image exceeds size limit of ') . $maximagesize . EOL); @unlink($src); $foo = 0; call_hooks('photo_post_end', $foo); return; } if (!$filesize) { notice(t('Image file is empty.') . EOL); @unlink($src); $foo = 0; call_hooks('photo_post_end', $foo); return; } logger('mod/photos.php: photos_post(): loading the contents of ' . $src, LOGGER_DEBUG); $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!$ph->is_valid()) { logger('mod/photos.php: photos_post(): unable to process image', LOGGER_DEBUG); notice(t('Unable to process image.') . EOL); @unlink($src); $foo = 0; call_hooks('photo_post_end', $foo); killme(); } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); $smallest = 0; $photo_hash = photo_new_resource(); $r = $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 0, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); if (!$r) { logger('mod/photos.php: photos_post(): image store failed', LOGGER_DEBUG); notice(t('Image upload failed.') . EOL); killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 1; } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 2; } $basename = basename($filename); $uri = item_new_uri($a->get_hostname(), $page_owner_uid); // Create item container $arr = array(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; $arr['type'] = 'photo'; $arr['wall'] = 1; $arr['resource-id'] = $photo_hash; $arr['contact-id'] = $owner_record['id']; $arr['owner-name'] = $owner_record['name']; $arr['owner-link'] = $owner_record['url']; $arr['owner-avatar'] = $owner_record['thumb']; $arr['author-name'] = $owner_record['name']; $arr['author-link'] = $owner_record['url']; $arr['author-avatar'] = $owner_record['thumb']; $arr['title'] = ''; $arr['allow_cid'] = $str_contact_allow; $arr['allow_gid'] = $str_group_allow; $arr['deny_cid'] = $str_contact_deny; $arr['deny_gid'] = $str_group_deny; $arr['last-child'] = 1; $arr['visible'] = $visible; $arr['origin'] = 1; $arr['body'] = '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo_hash . ']' . '[img]' . $a->get_baseurl() . "/photo/{$photo_hash}-{$smallest}.jpg" . '[/img]' . '[/url]'; $item_id = item_store($arr); if ($item_id) { q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), intval($page_owner_uid), intval($item_id)); } if ($visible) { proc_run('php', "include/notifier.php", 'wall-new', $item_id); } call_hooks('photo_post_end', intval($item_id)); // addon uploaders should call "killme()" [e.g. exit] within the photo_post_end hook // if they do not wish to be redirected goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); // NOTREACHED }
function register_post(&$a) { global $lang; $verified = 0; $blocked = 1; switch ($a->config['register_policy']) { case REGISTER_OPEN: $blocked = 0; $verified = 1; break; case REGISTER_APPROVE: $blocked = 1; $verified = 0; break; default: case REGISTER_CLOSED: if (!x($_SESSION, 'authenticated') && !x($_SESSION, 'administrator')) { notice(t('Permission denied.') . EOL); return; } $blocked = 1; $verified = 0; break; } $using_invites = get_config('system', 'invitation_only'); $num_invites = get_config('system', 'number_invites'); $invite_id = x($_POST, 'invite_id') ? notags(trim($_POST['invite_id'])) : ''; $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : ''; $nickname = x($_POST, 'nickname') ? notags(trim($_POST['nickname'])) : ''; $email = x($_POST, 'email') ? notags(trim($_POST['email'])) : ''; $openid_url = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : ''; $photo = x($_POST, 'photo') ? notags(trim($_POST['photo'])) : ''; $publish = x($_POST, 'profile_publish_reg') && intval($_POST['profile_publish_reg']) ? 1 : 0; $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0; $tmp_str = $openid_url; if ($using_invites) { if (!$invite_id) { notice(t('An invitation is required.') . EOL); return; } $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); if (!results($r)) { notice(t('Invitation could not be verified.') . EOL); return; } } if (!x($username) || !x($email) || !x($nickname)) { if ($openid_url) { if (!validate_url($tmp_str)) { notice(t('Invalid OpenID url') . EOL); return; } $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; require_once 'library/openid.php'; $openid = new LightOpenID(); $openid->identity = $openid_url; $openid->returnUrl = $a->get_baseurl() . '/openid'; $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default'); goaway($openid->authUrl()); // NOTREACHED } notice(t('Please enter the required information.') . EOL); return; } if (!validate_url($tmp_str)) { $openid_url = ''; } $err = ''; // collapse multiple spaces in name $username = preg_replace('/ +/', ' ', $username); if (mb_strlen($username) > 48) { $err .= t('Please use a shorter name.') . EOL; } if (mb_strlen($username) < 3) { $err .= t('Name too short.') . EOL; } // I don't really like having this rule, but it cuts down // on the number of auto-registrations by Russian spammers // Using preg_match was completely unreliable, due to mixed UTF-8 regex support // $no_utf = get_config('system','no_utf'); // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); // So now we are just looking for a space in the full name. $loose_reg = get_config('system', 'no_regfullname'); if (!$loose_reg) { $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8'); if (!strpos($username, ' ')) { $err .= t("That doesn't appear to be your full (First Last) name.") . EOL; } } if (!allowed_email($email)) { $err .= t('Your email domain is not among those allowed on this site.') . EOL; } if (!valid_email($email) || !validate_email($email)) { $err .= t('Not a valid email address.') . EOL; } // Disallow somebody creating an account using openid that uses the admin email address, // since openid bypasses email verification. We'll allow it if there is not yet an admin account. if (x($a->config, 'admin_email') && strcasecmp($email, $a->config['admin_email']) == 0 && strlen($openid_url)) { $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email)); if (count($r)) { $err .= t('Cannot use that email.') . EOL; } } $nickname = $_POST['nickname'] = strtolower($nickname); if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) { $err .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL; } $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $err .= t('Nickname is already registered. Please choose another.') . EOL; } if (strlen($err)) { notice($err); return; } $new_password = autoname(6) . mt_rand(100, 9999); $new_password_encoded = hash('whirlpool', $new_password); $res = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 4096, 'encrypt_key' => false)); // Get private key if (empty($res)) { notice(t('SERIOUS ERROR: Generation of security keys failed.') . EOL); return; } $prvkey = ''; openssl_pkey_export($res, $prvkey); // Get public key $pkey = openssl_pkey_get_details($res); $pubkey = $pkey["key"]; /** * * Create another keypair for signing/verifying * salmon protocol messages. We have to use a slightly * less robust key because this won't be using openssl * but the phpseclib. Since it is PHP interpreted code * it is not nearly as efficient, and the larger keys * will take several minutes each to process. * */ $sres = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 512, 'encrypt_key' => false)); // Get private key $sprvkey = ''; openssl_pkey_export($sres, $sprvkey); // Get public key $spkey = openssl_pkey_get_details($sres); $spubkey = $spkey["key"]; $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked)); if ($r) { $r = q("SELECT `uid` FROM `user` \n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded)); if ($r !== false && count($r)) { $newuid = intval($r[0]['uid']); } } else { notice(t('An error occurred during registration. Please try again.') . EOL); return; } /** * if somebody clicked submit twice very quickly, they could end up with two accounts * due to race condition. Remove this one. */ $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' ", dbesc($nickname)); if (count($r) > 1 && $newuid) { $err .= t('Nickname is already registered. Please choose another.') . EOL; q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1", intval($newuid)); notice($err); return; } if (x($newuid) !== false) { $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), 'default', 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish)); if ($r === false) { notice(t('An error occurred creating your default profile. Please try again.') . EOL); // Start fresh next time. $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return; } $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert())); } $use_gravatar = get_config('system', 'no_gravatar') ? false : true; // if we have an openid photo use it. // otherwise unless it is disabled, use gravatar if ($use_gravatar || strlen($photo)) { require_once 'include/Photo.php'; if ($use_gravatar && !strlen($photo)) { $photo = gravatar_img($email); } $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); $img = new Photo($img_str); if ($img->is_valid()) { $img->scaleImageSquare(175); $hash = photo_new_resource(); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6); if ($r === false) { $photo_failure = true; } if (!$photo_failure) { q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash)); } } } if ($netpublish && $a->config['register_policy'] != REGISTER_APPROVE) { $url = $a->get_baseurl() . "/profile/{$nickname}"; proc_run('php', "include/directory.php", "{$url}"); } call_hooks('register_account', $newuid); if ($a->config['register_policy'] == REGISTER_OPEN) { if ($using_invites && $invite_id) { q("delete * from register where hash = '%s' limit 1", dbesc($invite_id)); set_pconfig($newuid, 'system', 'invites_remaining', $num_invites); } $email_tpl = get_intltext_template("register_open_eml.tpl"); $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid)); $res = mail($email, sprintf(t('Registration details for %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit'); if ($res) { info(t('Registration successful. Please check your email for further instructions.') . EOL); goaway(z_root()); } else { notice(t('Failed to send email message. Here is the message that failed.') . $email_tpl . EOL); } } elseif ($a->config['register_policy'] == REGISTER_APPROVE) { if (!strlen($a->config['admin_email'])) { notice(t('Your registration can not be processed.') . EOL); goaway(z_root()); } $hash = random_string(); $r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language` ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", dbesc($hash), dbesc(datetime_convert()), intval($newuid), dbesc($new_password), dbesc($lang)); $r = q("SELECT `language` FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($a->config['admin_email'])); if (count($r)) { push_lang($r[0]['language']); } else { push_lang('en'); } if ($using_invites && $invite_id) { q("delete * from register where hash = '%s' limit 1", dbesc($invite_id)); set_pconfig($newuid, 'system', 'invites_remaining', $num_invites); } $email_tpl = get_intltext_template("register_verify_eml.tpl"); $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid, '$hash' => $hash)); $res = mail($a->config['admin_email'], sprintf(t('Registration request at %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit'); pop_lang(); if ($res) { info(t('Your registration is pending approval by the site owner.') . EOL); goaway(z_root()); } } return; }
function import_account(&$a, $file) { logger("Start user import from " . $file['tmp_name']); /* STEPS 1. checks 2. replace old baseurl with new baseurl 3. import data (look at user id and contacts id) 4. archive non-dfrn contacts 5. send message to dfrn contacts */ $account = json_decode(file_get_contents($file['tmp_name']), true); if ($account === null) { notice(t("Error decoding account file")); return; } if (!x($account, 'version')) { notice(t("Error! No version data in file! This is not a Friendica account file?")); return; } /* // this is not required as we remove columns in json not in current db schema if ($account['schema'] != DB_UPDATE_VERSION) { notice(t("Error! I can't import this file: DB schema version is not compatible.")); return; } */ // check for username $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } // check if username matches deleted account $r = q("SELECT id FROM userd WHERE username='******'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } $oldbaseurl = $account['baseurl']; $newbaseurl = $a->get_baseurl(); $olduid = $account['user']['uid']; unset($account['user']['uid']); unset($account['user']['account_expired']); unset($account['user']['account_expires_on']); unset($account['user']['expire_notification_sent']); foreach ($account['user'] as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); } // import user $r = db_import_assoc('user', $account['user']); if ($r === false) { //echo "<pre>"; var_dump($r, $query, mysql_error()); killme(); logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL); notice(t("User creation error")); return; } $newuid = last_insert_id(); //~ $newuid = 1; foreach ($account['profile'] as &$profile) { foreach ($profile as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } $profile['uid'] = $newuid; $r = db_import_assoc('profile', $profile); if ($r === false) { logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); info(t("User profile creation error")); import_cleanup($newuid); return; } } $errorcount = 0; foreach ($account['contact'] as &$contact) { if ($contact['uid'] == $olduid && $contact['self'] == '1') { foreach ($contact as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar", "micro") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } } if ($contact['uid'] == $olduid && $contact['self'] == '0') { // set contacts 'avatar-date' to "0000-00-00 00:00:00" to let poller to update urls $contact["avatar-date"] = "0000-00-00 00:00:00"; switch ($contact['network']) { case NETWORK_DFRN: // send relocate message (below) break; case NETWORK_ZOT: // TODO handle zot network break; case NETWORK_MAIL2: // TODO ? break; case NETWORK_FEED: case NETWORK_MAIL: // Nothing to do break; default: // archive other contacts $contact['archive'] = "1"; } } $contact['uid'] = $newuid; $r = db_import_assoc('contact', $contact); if ($r === false) { logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL); $errorcount++; } else { $contact['newid'] = last_insert_id(); } } if ($errorcount > 0) { notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount)); } foreach ($account['group'] as &$group) { $group['uid'] = $newuid; $r = db_import_assoc('group', $group); if ($r === false) { logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } else { $group['newid'] = last_insert_id(); } } foreach ($account['group_member'] as &$group_member) { $group_member['uid'] = $newuid; $import = 0; foreach ($account['group'] as $group) { if ($group['id'] == $group_member['gid'] && isset($group['newid'])) { $group_member['gid'] = $group['newid']; $import++; break; } } foreach ($account['contact'] as $contact) { if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) { $group_member['contact-id'] = $contact['newid']; $import++; break; } } if ($import == 2) { $r = db_import_assoc('group_member', $group_member); if ($r === false) { logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } } foreach ($account['photo'] as &$photo) { $photo['uid'] = $newuid; $photo['data'] = hex2bin($photo['data']); $p = new Photo($photo['data'], $photo['type']); $r = $p->store($photo['uid'], $photo['contact-id'], $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']); if ($r === false) { logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } foreach ($account['pconfig'] as &$pconfig) { $pconfig['uid'] = $newuid; $r = db_import_assoc('pconfig', $pconfig); if ($r === false) { logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } // send relocate messages proc_run('php', 'include/notifier.php', 'relocate', $newuid); info(t("Done. You can now login with your username and password")); goaway($a->get_baseurl() . "/login"); }
function wall_upload_post(&$a) { if ($a->argc > 1) { if (!x($_FILES, 'media')) { $nick = $a->argv[1]; $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick)); if (!count($r)) { return; } } else { $user_info = api_get_user($a); $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name'])); } } else { return; } $can_post = false; $visitor = 0; $page_owner_uid = $r[0]['uid']; $default_cid = $r[0]['id']; $page_owner_nick = $r[0]['nickname']; $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $page_owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid)); if (count($r)) { $can_post = true; $visitor = remote_user(); $default_cid = $visitor; } } } if (!$can_post) { notice(t('Permission denied.') . EOL); killme(); } if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) { killme(); } if (x($_FILES, 'userfile')) { $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); } elseif (x($_FILES, 'media')) { $src = $_FILES['media']['tmp_name']; $filename = basename($_FILES['media']['name']); $filesize = intval($_FILES['media']['size']); } $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL; @unlink($src); killme(); } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!$ph->is_valid()) { echo t('Unable to process image.') . EOL; @unlink($src); killme(); } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = photo_new_resource(); $smallest = 0; $defperm = '<' . $default_cid . '>'; $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); if (!$r) { echo t('Image upload failed.') . EOL; killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); if ($r) { $smallest = 1; } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); if ($r) { $smallest = 2; } } $basename = basename($filename); /* mod Waitman Gobble NO WARRANTY */ //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post) if ($_REQUEST['hush'] != 'yeah') { /*existing code*/ if (local_user() && intval(get_pconfig(local_user(), 'system', 'plaintext'))) { echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg[/img][/url]\n\n"; } else { echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg\" alt=\"{$basename}\" /></a><br /><br />"; } /*existing code*/ } else { $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg[/img][/url]"; return $m; } /* mod Waitman Gobble NO WARRANTY */ killme(); // NOTREACHED }
function local_delivery($importer, $data) { $a = get_app(); logger(__FUNCTION__, LOGGER_TRACE); if ($importer['readonly']) { // We aren't receiving stuff from this person. But we will quietly ignore them // rather than a blatant "go away" message. logger('local_delivery: ignoring'); return 0; //NOTREACHED } // Consume notification feed. This may differ from consuming a public feed in several ways // - might contain email or friend suggestions // - might contain remote followup to our message // - in which case we need to accept it and then notify other conversants // - we may need to send various email notifications $feed = new SimplePie(); $feed->set_raw_data($data); $feed->enable_order_by_date(false); $feed->init(); if ($feed->error()) { logger('local_delivery: Error parsing XML: ' . $feed->error()); } // Check at the feed level for updated contact name and/or photo $name_updated = ''; $new_name = ''; $photo_timestamp = ''; $photo_url = ''; $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'owner'); // Fallback should not be needed here. If it isn't DFRN it won't have DFRN updated tags // if(! $rawtags) // $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']; $new_name = $elems['name'][0]['data']; } if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; } } if ($photo_timestamp && strlen($photo_url) && $photo_timestamp > $importer['avatar-date']) { logger('local_delivery: Updating photo for ' . $importer['name']); require_once "include/Photo.php"; $photo_failure = false; $have_photo = false; $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1", intval($importer['id']), intval($importer['importer_uid'])); if (count($r)) { $resource_id = $r[0]['resource-id']; $have_photo = true; } else { $resource_id = photo_new_resource(); } $img_str = fetch_url($photo_url, true); // guess mimetype from headers or filename $type = guess_image_type($photo_url, true); $img = new Photo($img_str, $type); if ($img->is_valid()) { if ($have_photo) { q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d", dbesc($resource_id), intval($importer['id']), intval($importer['importer_uid'])); } $img->scaleImageSquare(175); $hash = $resource_id; $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 4); $img->scaleImage(80); $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 5); $img->scaleImage(48); $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 6); $a = get_app(); q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'\n\t\t\t\tWHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt()), intval($importer['importer_uid']), intval($importer['id'])); } } if ($name_updated && strlen($new_name) && $name_updated > $importer['name-date']) { $r = q("select * from contact where uid = %d and id = %d limit 1", intval($importer['importer_uid']), intval($importer['id'])); $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($importer['importer_uid']), intval($importer['id'])); // do our best to update the name on content items if (count($r)) { q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", dbesc(notags(trim($new_name))), dbesc($r[0]['name']), dbesc($r[0]['url']), intval($importer['importer_uid'])); } } // Currently unsupported - needs a lot of work $reloc = $feed->get_feed_tags(NAMESPACE_DFRN, 'relocate'); if (isset($reloc[0]['child'][NAMESPACE_DFRN])) { $base = $reloc[0]['child'][NAMESPACE_DFRN]; $newloc = array(); $newloc['uid'] = $importer['importer_uid']; $newloc['cid'] = $importer['id']; $newloc['name'] = notags(unxmlify($base['name'][0]['data'])); $newloc['photo'] = notags(unxmlify($base['photo'][0]['data'])); $newloc['thumb'] = notags(unxmlify($base['thumb'][0]['data'])); $newloc['micro'] = notags(unxmlify($base['micro'][0]['data'])); $newloc['url'] = notags(unxmlify($base['url'][0]['data'])); $newloc['request'] = notags(unxmlify($base['request'][0]['data'])); $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data'])); $newloc['notify'] = notags(unxmlify($base['notify'][0]['data'])); $newloc['poll'] = notags(unxmlify($base['poll'][0]['data'])); $newloc['sitepubkey'] = notags(unxmlify($base['sitepubkey'][0]['data'])); /** relocated user must have original key pair */ /*$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data'])); $newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));*/ logger("items:relocate contact " . print_r($newloc, true) . print_r($importer, true), LOGGER_DEBUG); // update contact $r = q("SELECT photo, url FROM contact WHERE id=%d AND uid=%d;", intval($importer['id']), intval($importer['importer_uid'])); if ($r === false) { return 1; } $old = $r[0]; $x = q("UPDATE contact SET\n name = '%s',\n photo = '%s',\n thumb = '%s',\n micro = '%s',\n url = '%s',\n request = '%s',\n confirm = '%s',\n notify = '%s',\n poll = '%s',\n `site-pubkey` = '%s'\n WHERE id=%d AND uid=%d;", dbesc($newloc['name']), dbesc($newloc['photo']), dbesc($newloc['thumb']), dbesc($newloc['micro']), dbesc($newloc['url']), dbesc($newloc['request']), dbesc($newloc['confirm']), dbesc($newloc['notify']), dbesc($newloc['poll']), dbesc($newloc['sitepubkey']), intval($importer['id']), intval($importer['importer_uid'])); if ($x === false) { return 1; } // update items $fields = array('owner-link' => array($old['url'], $newloc['url']), 'author-link' => array($old['url'], $newloc['url']), 'owner-avatar' => array($old['photo'], $newloc['photo']), 'author-avatar' => array($old['photo'], $newloc['photo'])); foreach ($fields as $n => $f) { $x = q("UPDATE item SET `%s`='%s' WHERE `%s`='%s' AND uid=%d", $n, dbesc($f[1]), $n, dbesc($f[0]), intval($importer['importer_uid'])); if ($x === false) { return 1; } } // TODO // merge with current record, current contents have priority // update record, set url-updated // update profile photos // schedule a scan? return 0; } // handle friend suggestion notification $sugg = $feed->get_feed_tags(NAMESPACE_DFRN, 'suggest'); if (isset($sugg[0]['child'][NAMESPACE_DFRN])) { $base = $sugg[0]['child'][NAMESPACE_DFRN]; $fsugg = array(); $fsugg['uid'] = $importer['importer_uid']; $fsugg['cid'] = $importer['id']; $fsugg['name'] = notags(unxmlify($base['name'][0]['data'])); $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data'])); $fsugg['url'] = notags(unxmlify($base['url'][0]['data'])); $fsugg['request'] = notags(unxmlify($base['request'][0]['data'])); $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data'])); // Does our member already have a friend matching this description? $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc($fsugg['name']), dbesc(normalise_link($fsugg['url'])), intval($fsugg['uid'])); if (count($r)) { return 0; } // Do we already have an fcontact record for this person? $fid = 0; $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request'])); if (count($r)) { $fid = $r[0]['id']; // OK, we do. Do we already have an introduction for this person ? $r = q("select id from intro where uid = %d and fid = %d limit 1", intval($fsugg['uid']), intval($fid)); if (count($r)) { return 0; } } if (!$fid) { $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ", dbesc($fsugg['name']), dbesc($fsugg['url']), dbesc($fsugg['photo']), dbesc($fsugg['request'])); } $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request'])); if (count($r)) { $fid = $r[0]['id']; } else { return 0; } $hash = random_string(); $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )\n\t\t\tVALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), intval($fid), intval($fsugg['cid']), dbesc($fsugg['body']), dbesc($hash), dbesc(datetime_convert()), intval(0)); notification(array('type' => NOTIFY_SUGGEST, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $fsugg, 'link' => $a->get_baseurl() . '/notifications/intros', 'source_name' => $importer['name'], 'source_link' => $importer['url'], 'source_photo' => $importer['photo'], 'verb' => ACTIVITY_REQ_FRIEND, 'otype' => 'intro')); return 0; } $ismail = false; $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail'); if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) { logger('local_delivery: private message received'); $ismail = true; $base = $rawmail[0]['child'][NAMESPACE_DFRN]; $msg = array(); $msg['uid'] = $importer['importer_uid']; $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data'])); $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data'])); $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])); $msg['contact-id'] = $importer['id']; $msg['title'] = notags(unxmlify($base['subject'][0]['data'])); $msg['body'] = escape_tags(unxmlify($base['content'][0]['data'])); $msg['seen'] = 0; $msg['replied'] = 0; $msg['uri'] = notags(unxmlify($base['id'][0]['data'])); $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data'])); $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data']))); dbesc_array($msg); $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')"); // send notifications. require_once 'include/enotify.php'; $notif_params = array('type' => NOTIFY_MAIL, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $msg, 'source_name' => $msg['from-name'], 'source_link' => $importer['url'], 'source_photo' => $importer['thumb'], 'verb' => ACTIVITY_POST, 'otype' => 'mail'); notification($notif_params); return 0; // NOTREACHED } $community_page = 0; $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community'); if ($rawtags) { $community_page = intval($rawtags[0]['data']); } if (intval($importer['forum']) != $community_page) { q("update contact set forum = %d where id = %d limit 1", intval($community_page), intval($importer['id'])); $importer['forum'] = (string) $community_page; } logger('local_delivery: feed item count = ' . $feed->get_item_quantity()); // process any deleted entries $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); if (is_array($del_entries) && count($del_entries)) { foreach ($del_entries as $dentry) { $deleted = false; if (isset($dentry['attribs']['']['ref'])) { $uri = $dentry['attribs']['']['ref']; $deleted = true; if (isset($dentry['attribs']['']['when'])) { $when = $dentry['attribs']['']['when']; $when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s'); } else { $when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s'); } } if ($deleted) { // check for relayed deletes to our conversation $is_reply = false; $r = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($uri), intval($importer['importer_uid'])); if (count($r)) { $parent_uri = $r[0]['parent-uri']; if ($r[0]['id'] != $r[0]['parent']) { $is_reply = true; } } if ($is_reply) { $community = false; if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) { $sql_extra = ''; $community = true; logger('local_delivery: possible community delete'); } else { $sql_extra = " and contact.self = 1 and item.wall = 1 "; } // was the top-level post for this reply written by somebody on this site? // Specifically, the recipient? $is_a_remote_delete = false; // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used? $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, \n\t\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t\t\t{$sql_extra}\n\t\t\t\t\t\tLIMIT 1", dbesc($parent_uri), dbesc($parent_uri), dbesc($parent_uri), intval($importer['importer_uid'])); if ($r && count($r)) { $is_a_remote_delete = true; } // Does this have the characteristics of a community or private group comment? // If it's a reply to a wall post on a community/prvgroup page it's a // valid community comment. Also forum_mode makes it valid for sure. // If neither, it's not. if ($is_a_remote_delete && $community) { if (!$r[0]['forum_mode'] && !$r[0]['wall']) { $is_a_remote_delete = false; logger('local_delivery: not a community delete'); } } if ($is_a_remote_delete) { logger('local_delivery: received remote delete'); } } $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`\n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['importer_uid']), intval($importer['id'])); if (count($r)) { $item = $r[0]; if ($item['deleted']) { continue; } logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG); if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) { $xo = parse_xml_string($item['object'], false); $xt = parse_xml_string($item['target'], false); if ($xt->type === ACTIVITY_OBJ_NOTE) { $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid'])); if (count($i)) { // For tags, the owner cannot remove the tag on the author's copy of the post. $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false; $author_remove = $item['origin'] && $item['self'] ? true : false; $author_copy = $item['origin'] ? true : false; if ($owner_remove && $author_copy) { continue; } if ($author_remove || $owner_remove) { $tags = explode(',', $i[0]['tag']); $newtags = array(); if (count($tags)) { foreach ($tags as $tag) { if (trim($tag) !== trim($xo->body)) { $newtags[] = trim($tag); } } } q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id'])); create_tags_from_item($i[0]['id']); } } } } if ($item['uri'] == $item['parent-uri']) { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['importer_uid'])); create_tags_from_itemuri($item['uri'], $importer['importer_uid']); } else { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['importer_uid'])); create_tags_from_itemuri($uri, $importer['importer_uid']); if ($item['last-child']) { // ensure that last-child is set in case the comment that had it just got wiped. q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid'])); // who is the last child now? $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d\n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['importer_uid'])); if (count($r)) { q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id'])); } } // if this is a relayed delete, propagate it to other recipients if ($is_a_remote_delete) { proc_run('php', "include/notifier.php", "drop", $item['id']); } } } } } } foreach ($feed->get_items() as $item) { $is_reply = false; $item_id = $item->get_id(); $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to'); if (isset($rawthread[0]['attribs']['']['ref'])) { $is_reply = true; $parent_uri = $rawthread[0]['attribs']['']['ref']; } if ($is_reply) { $community = false; if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) { $sql_extra = ''; $community = true; logger('local_delivery: possible community reply'); } else { $sql_extra = " and contact.self = 1 and item.wall = 1 "; } // was the top-level post for this reply written by somebody on this site? // Specifically, the recipient? $is_a_remote_comment = false; $top_uri = $parent_uri; $r = q("select `item`.`parent-uri` from `item`\n\t\t\t\tWHERE `item`.`uri` = '%s'\n\t\t\t\tLIMIT 1", dbesc($parent_uri)); if ($r && count($r)) { $top_uri = $r[0]['parent-uri']; // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used? $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, \n\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\tLIMIT 1", dbesc($top_uri), dbesc($top_uri), dbesc($top_uri), intval($importer['importer_uid'])); if ($r && count($r)) { $is_a_remote_comment = true; } } // Does this have the characteristics of a community or private group comment? // If it's a reply to a wall post on a community/prvgroup page it's a // valid community comment. Also forum_mode makes it valid for sure. // If neither, it's not. if ($is_a_remote_comment && $community) { if (!$r[0]['forum_mode'] && !$r[0]['wall']) { $is_a_remote_comment = false; logger('local_delivery: not a community reply'); } } if ($is_a_remote_comment) { logger('local_delivery: received remote comment'); $is_like = false; // remote reply to our post. Import and then notify everybody else. $datarray = get_atom_elements($feed, $item); $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid'])); // Update content if 'updated' changes if (count($r)) { $iid = $r[0]['id']; if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { // do not accept (ignore) an earlier edit than one we currently have. if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) { continue; } logger('received updated comment', LOGGER_DEBUG); $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid'])); create_tags_from_itemuri($item_id, $importer['importer_uid']); proc_run('php', "include/notifier.php", "comment-import", $iid); } continue; } $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1", intval($importer['importer_uid'])); $datarray['type'] = 'remote-comment'; $datarray['wall'] = 1; $datarray['parent-uri'] = $parent_uri; $datarray['uid'] = $importer['importer_uid']; $datarray['owner-name'] = $own[0]['name']; $datarray['owner-link'] = $own[0]['url']; $datarray['owner-avatar'] = $own[0]['thumb']; $datarray['contact-id'] = $importer['id']; if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE) { $is_like = true; $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; $datarray['last-child'] = 0; // only one like or dislike per person $r = q("select id from item where uid = %d and `contact-id` = %d and verb = '%s' and (`thr-parent` = '%s' or `parent-uri` = '%s') and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($datarray['parent-uri']), dbesc($datarray['parent-uri'])); if ($r && count($r)) { continue; } } if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) { $xo = parse_xml_string($datarray['object'], false); $xt = parse_xml_string($datarray['target'], false); if ($xt->type == ACTIVITY_OBJ_NOTE && $xt->id) { // fetch the parent item $tagp = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid'])); if (!count($tagp)) { continue; } // extract tag, if not duplicate, and this user allows tags, add to parent item if ($xo->id && $xo->content) { $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]'; if (!stristr($tagp[0]['tag'], $newtag)) { $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1", intval($importer['importer_uid'])); if (count($i) && !intval($i[0]['blocktags'])) { q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1", dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag), intval($tagp[0]['id']), dbesc(datetime_convert())); create_tags_from_item($tagp[0]['id']); } } } } } $posted_id = item_store($datarray); $parent = 0; if ($posted_id) { $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid'])); if (count($r)) { $parent = $r[0]['parent']; $parent_uri = $r[0]['parent-uri']; } if (!$is_like) { $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($r[0]['parent'])); $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($posted_id)); } if ($posted_id && $parent) { proc_run('php', "include/notifier.php", "comment-import", "{$posted_id}"); if (!$is_like && !$importer['self']) { require_once 'include/enotify.php'; notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, 'parent_uri' => $parent_uri)); } } return 0; // NOTREACHED } } else { // regular comment that is part of this total conversation. Have we seen it? If not, import it. $item_id = $item->get_id(); $datarray = get_atom_elements($feed, $item); if ($importer['rel'] == CONTACT_IS_FOLLOWER) { continue; } $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid'])); // Update content if 'updated' changes if (count($r)) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { // do not accept (ignore) an earlier edit than one we currently have. if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) { continue; } $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid'])); create_tags_from_itemuri($item_id, $importer['importer_uid']); } // update last-child if it changes $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] != $r[0]['last-child']) { $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['importer_uid'])); $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid'])); } continue; } $datarray['parent-uri'] = $parent_uri; $datarray['uid'] = $importer['importer_uid']; $datarray['contact-id'] = $importer['id']; if ($datarray['verb'] == ACTIVITY_LIKE || $datarray['verb'] == ACTIVITY_DISLIKE) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; // only one like or dislike per person $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent-uri` = '%s' OR `thr-parent` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($parent_uri), dbesc($parent_uri)); if ($r && count($r)) { continue; } } if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) { $xo = parse_xml_string($datarray['object'], false); $xt = parse_xml_string($datarray['target'], false); if ($xt->type == ACTIVITY_OBJ_NOTE) { $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid'])); if (!count($r)) { continue; } // extract tag, if not duplicate, add to parent item if ($xo->content) { if (!stristr($r[0]['tag'], trim($xo->content))) { q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']' . $xo->content . '[/url]'), intval($r[0]['id'])); create_tags_from_item($r[0]['id']); } } } } $posted_id = item_store($datarray); // find out if our user is involved in this conversation and wants to be notified. if (!x($datarray['type']) || $datarray['type'] != 'activity') { $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", dbesc($top_uri), intval($importer['importer_uid'])); if (count($myconv)) { $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname']; // first make sure this isn't our own post coming back to us from a wall-to-wall event if (!link_compare($datarray['author-link'], $importer_url)) { foreach ($myconv as $conv) { // now if we find a match, it means we're in this conversation if (!link_compare($conv['author-link'], $importer_url)) { continue; } require_once 'include/enotify.php'; $conv_parent = $conv['parent']; notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent, 'parent_uri' => $parent_uri)); // only send one notification break; } } } } continue; } } else { // Head post of a conversation. Have we seen it? If not, import it. $item_id = $item->get_id(); $datarray = get_atom_elements($feed, $item); if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) { $ev = bbtoevent($datarray['body']); if (x($ev, 'desc') && x($ev, 'start')) { $ev['cid'] = $importer['id']; $ev['uid'] = $importer['uid']; $ev['uri'] = $item_id; $ev['edited'] = $datarray['edited']; $ev['private'] = $datarray['private']; $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid'])); if (count($r)) { $ev['id'] = $r[0]['id']; } $xyz = event_store($ev); continue; } } $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid'])); // Update content if 'updated' changes if (count($r)) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { // do not accept (ignore) an earlier edit than one we currently have. if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) { continue; } $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid'])); create_tags_from_itemuri($item_id, $importer['importer_uid']); } // update last-child if it changes $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] != $r[0]['last-child']) { $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid'])); } continue; } // This is my contact on another system, but it's really me. // Turn this into a wall post. if ($importer['remote_self']) { $datarray['wall'] = 1; } $datarray['parent-uri'] = $item_id; $datarray['uid'] = $importer['importer_uid']; $datarray['contact-id'] = $importer['id']; if (!link_compare($datarray['owner-link'], $importer['url'])) { // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, // but otherwise there's a possible data mixup on the sender's system. // the tgroup delivery code called from item_store will correct it if it's a forum, // but we're going to unconditionally correct it here so that the post will always be owned by our contact. logger('local_delivery: Correcting item owner.', LOGGER_DEBUG); $datarray['owner-name'] = $importer['senderName']; $datarray['owner-link'] = $importer['url']; $datarray['owner-avatar'] = $importer['thumb']; } if ($importer['rel'] == CONTACT_IS_FOLLOWER && !tgroup_check($importer['importer_uid'], $datarray)) { continue; } $posted_id = item_store($datarray); if (stristr($datarray['verb'], ACTIVITY_POKE)) { $verb = urldecode(substr($datarray['verb'], strpos($datarray['verb'], '#') + 1)); if (!$verb) { continue; } $xo = parse_xml_string($datarray['object'], false); if ($xo->type == ACTIVITY_OBJ_PERSON && $xo->id) { // somebody was poked/prodded. Was it me? $links = parse_xml_string("<links>" . unxmlify($xo->link) . "</links>", false); foreach ($links->link as $l) { $atts = $l->attributes(); switch ($atts['rel']) { case "alternate": $Blink = $atts['href']; break; default: break; } } if ($Blink && link_compare($Blink, $a->get_baseurl() . '/profile/' . $importer['nickname'])) { // send a notification require_once 'include/enotify.php'; notification(array('type' => NOTIFY_POKE, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => $datarray['verb'], 'otype' => 'person', 'activity' => $verb)); } } } continue; } } return 0; // NOTREACHED }
function proxy_init() { global $a, $_SERVER; // Pictures are stored in one of the following ways: // 1. If a folder "proxy" exists and is writeable, then use this for caching // 2. If a cache path is defined, use this // 3. If everything else failed, cache into the database // // Question: Do we really need these three methods? if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header('HTTP/1.1 304 Not Modified'); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header('Etag: ' . $_SERVER['HTTP_IF_NONE_MATCH']); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 31536000) . " GMT"); header("Cache-Control: max-age=31536000"); if (function_exists('header_remove')) { header_remove('Last-Modified'); header_remove('Expires'); header_remove('Cache-Control'); } exit; } if (function_exists('header_remove')) { header_remove('Pragma'); header_remove('pragma'); } $thumb = false; $size = 1024; // If the cache path isn't there, try to create it if (!is_dir($_SERVER["DOCUMENT_ROOT"] . "/proxy")) { if (is_writable($_SERVER["DOCUMENT_ROOT"])) { mkdir($_SERVER["DOCUMENT_ROOT"] . "/proxy"); } } // Checking if caching into a folder in the webroot is activated and working $direct_cache = (is_dir($_SERVER["DOCUMENT_ROOT"] . "/proxy") and is_writable($_SERVER["DOCUMENT_ROOT"] . "/proxy")); // Look for filename in the arguments if ((isset($a->argv[1]) or isset($a->argv[2]) or isset($a->argv[3])) and !isset($_REQUEST["url"])) { if (isset($a->argv[3])) { $url = $a->argv[3]; } elseif (isset($a->argv[2])) { $url = $a->argv[2]; } else { $url = $a->argv[1]; } if (isset($a->argv[3]) and $a->argv[3] == "thumb") { $size = 200; } // thumb, small, medium and large. if (substr($url, -6) == ":thumb") { $size = 150; } if (substr($url, -6) == ":small") { $size = 340; } if (substr($url, -7) == ":medium") { $size = 600; } if (substr($url, -6) == ":large") { $size = 1024; } $pos = strrpos($url, "=."); if ($pos) { $url = substr($url, 0, $pos + 1); } $url = str_replace(array(".jpg", ".jpeg", ".gif", ".png"), array("", "", "", ""), $url); $url = base64_decode(strtr($url, '-_', '+/'), true); if ($url) { $_REQUEST['url'] = $url; } } else { $direct_cache = false; } if (!$direct_cache) { $urlhash = 'pic:' . sha1($_REQUEST['url']); $cachefile = get_cachefile(hash("md5", $_REQUEST['url'])); if ($cachefile != '') { if (file_exists($cachefile)) { $img_str = file_get_contents($cachefile); $mime = image_type_to_mime_type(exif_imagetype($cachefile)); header("Content-type: {$mime}"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header('Etag: "' . md5($img_str) . '"'); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 31536000) . " GMT"); header("Cache-Control: max-age=31536000"); // reduce quality - if it isn't a GIF if ($mime != "image/gif") { $img = new Photo($img_str, $mime); if ($img->is_valid()) { $img_str = $img->imageString(); } } echo $img_str; killme(); } } } else { $cachefile = ""; } $valid = true; if (!$direct_cache and $cachefile == "") { $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' LIMIT 1", $urlhash); if (count($r)) { $img_str = $r[0]['data']; $mime = $r[0]["desc"]; if ($mime == "") { $mime = "image/jpeg"; } } } else { $r = array(); } if (!count($r)) { // It shouldn't happen but it does - spaces in URL $_REQUEST['url'] = str_replace(" ", "+", $_REQUEST['url']); $redirects = 0; $img_str = fetch_url($_REQUEST['url'], true, $redirects, 10); $tempfile = tempnam(get_temppath(), "cache"); file_put_contents($tempfile, $img_str); $mime = image_type_to_mime_type(exif_imagetype($tempfile)); unlink($tempfile); // If there is an error then return a blank image if (substr($a->get_curl_code(), 0, 1) == "4" or !$img_str) { $img_str = file_get_contents("images/blank.png"); $mime = "image/png"; $cachefile = ""; // Clear the cachefile so that the dummy isn't stored $valid = false; $img = new Photo($img_str, "image/png"); if ($img->is_valid()) { $img->scaleImage(10); $img_str = $img->imageString(); } } else { if ($mime != "image/jpeg" and !$direct_cache and $cachefile == "") { $image = @imagecreatefromstring($img_str); if ($image === FALSE) { die; } q("INSERT INTO `photo`\n\t\t\t( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, `album`, `height`, `width`, `desc`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )\n\t\t\tVALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' )", 0, 0, get_guid(), dbesc($urlhash), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(basename(dbesc($_REQUEST["url"]))), dbesc(''), intval(imagesy($image)), intval(imagesx($image)), $mime, dbesc($img_str), 100, intval(0), dbesc(''), dbesc(''), dbesc(''), dbesc('')); } else { $img = new Photo($img_str, $mime); if ($img->is_valid()) { if (!$direct_cache and $cachefile == "") { $img->store(0, 0, $urlhash, $_REQUEST['url'], '', 100); } } } } } // reduce quality - if it isn't a GIF if ($mime != "image/gif") { $img = new Photo($img_str, $mime); if ($img->is_valid()) { $img->scaleImage($size); $img_str = $img->imageString(); } } // If there is a real existing directory then put the cache file there // advantage: real file access is really fast // Otherwise write in cachefile if ($valid and $direct_cache) { file_put_contents($_SERVER["DOCUMENT_ROOT"] . "/proxy/" . proxy_url($_REQUEST['url'], true), $img_str); } elseif ($cachefile != '') { file_put_contents($cachefile, $img_str); } header("Content-type: {$mime}"); // Only output the cache headers when the file is valid if ($valid) { header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header('Etag: "' . md5($img_str) . '"'); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 31536000) . " GMT"); header("Cache-Control: max-age=31536000"); } echo $img_str; killme(); }
function dfrn_confirm_post(&$a) { if ($a->argc > 1) { $node = $a->argv[1]; } if (x($_POST, 'source_url')) { // We are processing an external confirmation to an introduction created by our user. $public_key = $_POST['public_key']; $dfrn_id = $_POST['dfrn_id']; $source_url = $_POST['source_url']; $aes_key = $_POST['aes_key']; $duplex = $_POST['duplex']; $version_id = $_POST['dfrn_version']; // Find our user's account $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1", dbesc($node)); if (!count($r)) { xml_status(3); // failure return; // NOTREACHED } $my_prvkey = $r[0]['prvkey']; $local_uid = $r[0]['uid']; // verify everything $decrypted_source_url = ""; openssl_private_decrypt($source_url, $decrypted_source_url, $my_prvkey); $ret = q("SELECT * FROM `contact` WHERE `url` = '%s' LIMIT 1", dbesc($decrypted_source_url)); if (!count($ret)) { // this is either a bogus confirmation or we deleted the original introduction. xml_status(3); return; // NOTREACHED } $relation = $ret[0]['rel']; // Decrypt all this stuff we just received $foreign_pubkey = $ret[0]['site-pubkey']; $dfrn_record = $ret[0]['id']; $decrypted_dfrn_id = ""; openssl_public_decrypt($dfrn_id, $decrypted_dfrn_id, $foreign_pubkey); if (strlen($aes_key)) { $decrypted_aes_key = ""; openssl_private_decrypt($aes_key, $decrypted_aes_key, $my_prvkey); $dfrn_pubkey = openssl_decrypt($public_key, 'AES-256-CBC', $decrypted_aes_key); } else { $dfrn_pubkey = $public_key; } $r = q("SELECT * FROM `contact` WHERE `dfrn-id` = '%s' LIMIT 1", dbesc($decrypted_dfrn_id), intval($local_uid)); if (count($r)) { xml_status(1); // Birthday paradox - duplicate dfrn-id return; // NOTREACHED } $r = q("UPDATE `contact` SET `dfrn-id` = '%s', `pubkey` = '%s' WHERE `id` = %d LIMIT 1", dbesc($decrypted_dfrn_id), dbesc($dfrn_pubkey), intval($dfrn_record)); if ($r) { // We're good but now we have to scrape the profile photo and send notifications. require_once "Photo.php"; $photo_failure = false; $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1", intval($dfrn_record)); if (count($r)) { $filename = basename($r[0]['photo']); $img_str = fetch_url($r[0]['photo'], true); $img = new Photo($img_str); if ($img) { $img->scaleImageSquare(175); $hash = hash('md5', uniqid(mt_rand(), true)); $r = $img->store($dfrn_record, $hash, $filename, t('Contact Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($dfrn_record, $hash, $filename, t('Contact Photos'), 5); if ($r === false) { $photo_failure = true; } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg'; $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg'; } else { $photo_failure = true; } } else { $photo_failure = true; } if ($photo_failure) { $photo = $a->get_baseurl() . '/images/default-profile.jpg'; $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg'; } $new_relation = DIRECTION_OUT; if ($relation == DIRECTION_IN || $duplex) { $new_relation = DIRECTION_BOTH; } $r = q("UPDATE `contact` SET \n\t\t\t\t`photo` = '%s',\n\t\t\t\t`thumb` = '%s',\n\t\t\t\t`rel` = %d,\n\t\t\t\t`name-date` = '%s',\n\t\t\t\t`uri-date` = '%s',\n\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t`blocked` = 0,\n\t\t\t\t`pending` = 0,\n\t\t\t\t`duplex` = %d\n\t\t\t\t`network` = 'dfrn' WHERE `id` = %d LIMIT 1\n\t\t\t", dbesc($photo), dbesc($thumb), intval($newrelation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($duplex), intval($dfrn_record)); if ($r === false) { notice(t("Unable to set contact photo info.") . EOL); } // Otherwise everything seems to have worked and we are almost done. Yay! // Send an email notification $r = q("SELECT * FROM `contact` LEFT JOIN `user` ON `user`.`uid` = 1\n\t\t\t\tWHERE `contact`.`id` = %d LIMIT 1", intval($dfrn_record)); if (count($r) && $r[0]['notify-flags'] & NOTIFY_CONFIRM) { $tpl = file_get_contents('view/intro_complete_eml.tpl'); $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $r[0]['username'], '$email' => $r[0]['email'], '$fn' => $r[0]['name'], '$dfrn_url' => $r[0]['url'])); $res = mail($r[0]['email'], t("Introduction accepted at ") . $a->config['sitename'], $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER[SERVER_NAME]); if (!$res) { notice(t("Email notification failed.") . EOL); } } xml_status(0); // Success return; // NOTREACHED } else { xml_status(2); // Hopefully temporary problem that can be retried. } return; // NOTREACHED ////////////////////// End of this scenario /////////////////////////////////////////////// } else { // We are processing a local confirmation initiated on this system by our user to an external introduction. $uid = get_uid(); if (!$uid) { notice(t("Permission denied.") . EOL); return; } $dfrn_id = x($_POST, 'dfrn_id') ? notags(trim($_POST['dfrn_id'])) : ""; $intro_id = intval($_POST['intro_id']); $duplex = intval($_POST['duplex']); $r = q("SELECT * FROM `contact` WHERE `issued-id` = '%s' LIMIT 1", dbesc($dfrn_id)); if (!count($r)) { notice(t('Node does not exist.') . EOL); return; } $contact_id = $r[0]['id']; $relation = $r[0]['rel']; $site_pubkey = $r[0]['site-pubkey']; $dfrn_confirm = $r[0]['confirm']; $aes_allow = $r[0]['aes_allow']; $res = openssl_pkey_new(array('digest_alg' => 'whirlpool', 'private_key_bits' => 4096, 'encrypt_key' => false)); $private_key = ''; openssl_pkey_export($res, $private_key); $pubkey = openssl_pkey_get_details($res); $public_key = $pubkey["key"]; $r = q("UPDATE `contact` SET `issued-pubkey` = '%s', `prvkey` = '%s' WHERE `id` = %d LIMIT 1", dbesc($public_key), dbesc($private_key), intval($contact_id)); $params = array(); $src_aes_key = random_string(); $result = ''; openssl_private_encrypt($dfrn_id, $result, $a->user['prvkey']); $params['dfrn_id'] = $result; $params['public_key'] = $public_key; openssl_public_encrypt($_SESSION['my_url'], $params['source_url'], $site_pubkey); if ($aes_allow && function_exists('openssl_encrypt')) { openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey); $params['public_key'] = openssl_encrypt($public_key, 'AES-256-CBC', $src_aes_key); } $params['dfrn_version'] = '2.0'; if ($duplex == 1) { $params['duplex'] = 1; } $res = post_url($dfrn_confirm, $params); // uncomment the following two lines and comment the following xml/status lines // to debug the remote confirmation section (when both confirmations // and responses originate on this system) // echo $res; // $status = 0; $xml = simplexml_load_string($res); $status = (int) $xml->status; switch ($status) { case 0: notice(t("Confirmation completed successfully") . EOL); break; case 1: // birthday paradox - generate new dfrn-id and fall through. $new_dfrn_id = random_string(); $r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d LIMIT 1", dbesc($new_dfrn_id), intval($contact_id)); case 2: notice(t("Temporary failure. Please wait and try again.") . EOL); break; case 3: notice(t("Introduction failed or was revoked. Cannot complete.") . EOL); break; } if (($status == 0 || $status == 3) && $intro_id) { //delete the notification $r = q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($intro_id)); } if ($status != 0) { return; } require_once "Photo.php"; $photo_failure = false; $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1", intval($contact_id)); if (count($r)) { $filename = basename($r[0]['photo']); $img_str = fetch_url($r[0]['photo'], true); $img = new Photo($img_str); if ($img) { $img->scaleImageSquare(175); $hash = hash('md5', uniqid(mt_rand(), true)); $r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 5); if ($r === false) { $photo_failure = true; } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg'; $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg'; } else { $photo_failure = true; } } else { $photo_failure = true; } if ($photo_failure) { $photo = $a->get_baseurl() . '/images/default-profile.jpg'; $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg'; } $new_relation = DIRECTION_IN; if ($relation == DIRECTION_OUT || $duplex) { $new_relation = DIRECTION_BOTH; } $r = q("UPDATE `contact` SET \n\t\t\t`photo` = '%s', \n\t\t\t`thumb` = '%s', \n\t\t\t`rel` = %d, \n\t\t\t`name-date` = '%s', \n\t\t\t`uri-date` = '%s', \n\t\t\t`avatar-date` = '%s', \n\t\t\t`blocked` = 0, \n\t\t\t`pending` = 0, \n\t\t\t`duplex` = %d,\n\t\t\t`network` = 'dfrn' WHERE `id` = %d LIMIT 1\n\t\t", dbesc($photo), dbesc($thumb), intval($newrelation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($duplex), intval($contact_id)); if ($r === false) { notice(t('Unable to set contact photo.') . EOL); } goaway($a->get_baseurl() . '/contacts/' . intval($contact_id)); return; //NOTREACHED } return; }
function photos_post(&$a) { if (!local_user()) { notice(t('Permission denied.') . EOL); killme(); } $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = 1 WHERE `self` = 1 LIMIT 1"); $contact_record = $r[0]; if ($a->argc > 2 && $a->argv[1] == 'album') { $album = hex2bin($a->argv[2]); if ($album == t('Profile Photos') || $album == t('Contact Photos')) { goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $r = q("SELECT count(*) FROM `photo` WHERE `album` = '%s' ", dbesc($album)); if (!count($r)) { notice(t('Album not found.') . EOL); goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $newalbum = notags(trim($_POST['albumname'])); if ($newalbum != $album) { q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' ", dbesc($newalbum), dbesc($album)); $newurl = str_replace(bin2hex($album), bin2hex($newalbum), $_SESSION['photo_return']); goaway($a->get_baseurl() . '/' . $newurl); return; // NOTREACHED } if ($_POST['dropalbum'] == t('Delete Album')) { $res = array(); $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `album` = '%s'", dbesc($album)); if (count($r)) { foreach ($r as $rr) { $res[] = "'" . dbesc($rr['rid']) . "'"; } } else { goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } $str_res = implode(',', $res); q("DELETE FROM `photo` WHERE `resource-id` IN ( {$str_res} ) "); $r = q("SELECT `parent-uri` FROM `item` WHERE `resource-id` IN ( {$str_res} ) "); if (count($r)) { foreach ($r as $rr) { q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `parent-uri` = '%s' ", dbesc(datetime_convert()), dbesc($rr['parent-uri'])); $drop_id = intval($rr['id']); $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php'; // send the notification upstream/downstream as the case may be if ($rr['visible']) { proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"drop\" \"{$drop_id}\" & ", array(), $foo)); } } } } goaway($a->get_baseurl() . '/photos/' . $a->data['user']['nickname']); return; // NOTREACHED } if ($a->argc > 1 && x($_POST, 'delete') && $_POST['delete'] == t('Delete Photo')) { $r = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' LIMIT 1", dbesc($a->argv[1])); if (count($r)) { q("DELETE FROM `photo` WHERE `resource-id` = '%s'", dbesc($r[0]['resource-id'])); $i = q("SELECT * FROM `item` WHERE `resource-id` = '%s' LIMIT 1", dbesc($r[0]['resource-id'])); if (count($i)) { q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' ", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($i[0]['uri'])); $drop_id = intval($i[0]['id']); $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php'; // send the notification upstream/downstream as the case may be if ($i[0]['visible']) { proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"drop\" \"{$drop_id}\" & ", array(), $foo)); } } } goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } if ($a->argc > 1 && x($_POST, 'desc') !== false) { $desc = notags(trim($_POST['desc'])); $tags = notags(trim($_POST['tags'])); $item_id = intval($_POST['item_id']); $resource_id = $a->argv[1]; $p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' ORDER BY `scale` DESC", dbesc($resource_id)); if (count($r)) { $r = q("UPDATE `photo` SET `desc` = '%s' WHERE `resource-id` = '%s' ", dbesc($desc), dbesc($resource_id)); } if (!$item_id) { $title = ''; $basename = basename($filename); // Create item container $body = '[url=' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . $a->get_baseurl() . '/photo/' . $p[0]['resource-id'] . '-' . $p[0]['scale'] . '.jpg' . '[/img]' . '[/url]'; $uri = item_new_uri($a->get_hostname(), get_uid()); $r = q("INSERT INTO `item` (`type`, `wall`, `resource-id`, `contact-id`,\n\t\t\t\t`owner-name`,`owner-link`,`owner-avatar`, `created`,\n\t\t\t\t`edited`, `changed`, `uri`, `parent-uri`, `title`, `body`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`)\n\t\t\t\tVALUES( '%s', %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc('photo'), intval(1), dbesc($p[0]['resource-id']), intval($contact_record['id']), dbesc($contact_record['name']), dbesc($contact_record['url']), dbesc($contact_record['thumb']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($uri), dbesc($uri), dbesc($title), dbesc($body), dbesc($p[0]['allow_cid']), dbesc($p[0]['allow_gid']), dbesc($p[0]['deny_cid']), dbesc($p[0]['deny_gid'])); if ($r) { $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri)); if (count($r)) { $item_id = $r[0]['id']; } q("UPDATE `item` SET `parent` = %d, `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']), intval($r[0]['id'])); } } $r = q("UPDATE `item` SET `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc($tags), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item_id)); goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } if (!x($_FILES, 'userfile')) { killme(); } if ($_POST['partitionCount']) { $java_upload = true; } else { $java_upload = false; } $album = notags(trim($_POST['album'])); $newalbum = notags(trim($_POST['newalbum'])); if (!strlen($album)) { if (strlen($newalbum)) { $album = $newalbum; } else { $album = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); } } $r = q("SELECT * FROM `photo` WHERE `album` = '%s' ", dbesc($album)); if (!count($r) || $album == t('Profile Photos')) { $visible = 1; } else { $visibile = 0; } $str_group_allow = perms2str($_POST['group_allow']); $str_contact_allow = perms2str($_POST['contact_allow']); $str_group_deny = perms2str($_POST['group_deny']); $str_contact_deny = perms2str($_POST['contact_deny']); $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!($image = $ph->getImage())) { notice(t('Unable to process image.') . EOL); @unlink($src); killme(); } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); $smallest = 0; $photo_hash = hash('md5', uniqid(mt_rand(), true)); $r = $ph->store(0, $photo_hash, $filename, $album, 0, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); if (!$r) { notice(t('Image upload failed.') . EOL); killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $ph->store(0, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 1; } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $ph->store(0, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 2; } $basename = basename($filename); // Create item container $body = '[url=' . $a->get_baseurl() . '/photos/' . $contact_record['nickname'] . '/image/' . $photo_hash . ']' . '[img]' . $a->get_baseurl() . "/photo/{$photo_hash}-{$smallest}.jpg" . '[/img]' . '[/url]'; $uri = item_new_uri($a->get_hostname(), get_uid()); $r = q("INSERT INTO `item` (`type`, `wall`, `resource-id`, `contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `created`,\n\t\t`edited`, `changed`, `uri`, `parent-uri`, `title`, `body`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `visible`)\n\t\tVALUES( '%s', %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )", dbesc('photo'), intval(1), dbesc($photo_hash), intval($contact_record['id']), dbesc($contact_record['name']), dbesc($contact_record['url']), dbesc($contact_record['thumb']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($uri), dbesc($uri), dbesc($title), dbesc($body), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), intval($visible)); if ($r) { $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri)); if (count($r)) { q("UPDATE `item` SET `parent` = %d, `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']), intval($r[0]['id'])); } } if (!$java_upload) { goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED } killme(); return; // NOTREACHED }
function profile_photo_post(&$a) { if (!local_user()) { notice(t('Permission denied.') . EOL); return; } if (x($_POST, 'cropfinal') && $_POST['cropfinal'] == 1) { // phase 2 - we have finished cropping if ($a->argc != 2) { notice(t('Image uploaded but image cropping failed.') . EOL); return; } $image_id = $a->argv[1]; if (substr($image_id, -2, 1) == '-') { $scale = substr($image_id, -1, 1); $image_id = substr($image_id, 0, -2); } $srcX = $_POST['xstart']; $srcY = $_POST['ystart']; $srcW = $_POST['xfinal'] - $srcX; $srcH = $_POST['yfinal'] - $srcY; $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` = %d LIMIT 1", dbesc($image_id), intval($scale)); if (count($r)) { $base_image = $r[0]; $im = new Photo($base_image['data']); $im->cropImage(175, $srcX, $srcY, $srcW, $srcH); $r = $im->store(0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 4, 1); if ($r === false) { notice(t('Image size reduction (175) failed.') . EOL); } $im->scaleImage(80); $r = $im->store(0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 5, 1); if ($r === false) { notice(t('Image size reduction (80) failed.') . EOL); } // Unset the profile photo flag from any other photos I own $r = q("UPDATE `photo` SET `profile` = 0 WHERE `profile` = 1 AND `resource-id` != '%s' ", dbesc($base_image['resource-id'])); $r = q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `self` = 1 LIMIT 1", dbesc(datetime_convert())); // Update global directory in background $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php'; $url = $_SESSION['my_url']; if ($url && strlen(get_config('system', 'directory_submit_url'))) { proc_close(proc_open("\"{$php_path}\" \"include/directory.php\" \"{$url}\" &", array(), $foo)); } } goaway($a->get_baseurl() . '/profiles'); return; // NOTREACHED } $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!($image = $ph->getImage())) { notice(t('Unable to process image.') . EOL); @unlink($src); return; } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); if ($width < 175 || $height < 175) { $ph->scaleImageUp(200); $width = $ph->getWidth(); $height = $ph->getHeight(); } $hash = hash('md5', uniqid(mt_rand(), true)); $smallest = 0; $r = $ph->store(0, $hash, $filename, t('Profile Photos'), 0); if ($r) { notice(t('Image uploaded successfully.') . EOL); } else { notice(t('Image upload failed.') . EOL); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store(0, $hash, $filename, t('Profile Photos'), 1); if ($r === false) { notice(t('Image size reduction (640) failed.') . EOL); } else { $smallest = 1; } } $a->config['imagecrop'] = $hash; $a->config['imagecrop_resolution'] = $smallest; $a->page['htmlhead'] .= file_get_contents("view/crophead.tpl"); return; }
public function updateProfilePhoto() { if (isset($_POST['profile-photo'])) { $photo = new Photo('profil'); $replace = $this->userPhotoExist($_SESSION['auth']->id); if ($replace) { if ($photo->store('photo', true, $replace)) { $this->executerRequete("UPDATE photo SET nom = ? WHERE id_utilisateur = ?", [$photo->path, $_SESSION['auth']->id]); } } else { if ($photo->store('photo')) { $this->executerRequete("INSERT INTO photo SET nom = ?, id_utilisateur = ?", [$photo->path, $_SESSION['auth']->id]); } } } }
function profile_photo_post(&$a) { if (!local_user()) { notice(t('Permission denied.') . EOL); return; } check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); if (x($_POST, 'cropfinal') && $_POST['cropfinal'] == 1) { // phase 2 - we have finished cropping if ($a->argc != 2) { notice(t('Image uploaded but image cropping failed.') . EOL); return; } $image_id = $a->argv[1]; if (substr($image_id, -2, 1) == '-') { $scale = substr($image_id, -1, 1); $image_id = substr($image_id, 0, -2); } $srcX = $_POST['xstart']; $srcY = $_POST['ystart']; $srcW = $_POST['xfinal'] - $srcX; $srcH = $_POST['yfinal'] - $srcY; $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = %d LIMIT 1", dbesc($image_id), dbesc(local_user()), intval($scale)); if (count($r)) { $base_image = $r[0]; $im = new Photo($base_image['data']); if ($im->is_valid()) { $im->cropImage(175, $srcX, $srcY, $srcW, $srcH); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 4, 1); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "175") . EOL); } $im->scaleImage(80); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 5, 1); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "80") . EOL); } $im->scaleImage(48); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 6, 1); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "48") . EOL); } // Unset the profile photo flag from any other photos I own $r = q("UPDATE `photo` SET `profile` = 0 WHERE `profile` = 1 AND `resource-id` != '%s' AND `uid` = %d", dbesc($base_image['resource-id']), intval(local_user())); $r = q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `self` = 1 AND `uid` = %d LIMIT 1", dbesc(datetime_convert()), intval(local_user())); info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); // Update global directory in background $url = $a->get_baseurl() . '/profile/' . $a->user['nickname']; if ($url && strlen(get_config('system', 'directory_submit_url'))) { proc_run('php', "include/directory.php", "{$url}"); } require_once 'include/profile_update.php'; profile_change(); } else { notice(t('Unable to process image') . EOL); } } goaway($a->get_baseurl() . '/profiles'); return; // NOTREACHED } $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { notice(sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL); @unlink($src); return; } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!$ph->is_valid()) { notice(t('Unable to process image.') . EOL); @unlink($src); return; } @unlink($src); return profile_photo_crop_ui_head($a, $ph); }
/** * * consume_feed - process atom feed and update anything/everything we might need to update * * $xml = the (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. * * $importer = the contact_record (joined to user_record) of the local user who owns this relationship. * It is this person's stuff that is going to be updated. * $contact = the person who is sending us stuff. If not set, we MAY be processing a "follow" activity * from an external network and MAY create an appropriate contact record. Otherwise, we MUST * have a contact record. * $hub = should we find a hub declation in the feed, pass it back to our calling process, who might (or * might not) try and subscribe to it. * $datedir sorts in reverse order * $pass - by default ($pass = 0) we cannot guarantee that a parent item has been * imported prior to its children being seen in the stream unless we are certain * of how the feed is arranged/ordered. * With $pass = 1, we only pull parent items out of the stream. * With $pass = 2, we only pull children (comments/likes). * * So running this twice, first with pass 1 and then with pass 2 will do the right * thing regardless of feed ordering. This won't be adequate in a fully-threaded * model where comments can have sub-threads. That would require some massive sorting * to get all the feed items into a mostly linear ordering, and might still require * recursion. */ function consume_feed($xml, $importer, &$contact, &$hub, $datedir = 0, $pass = 0) { require_once 'library/simplepie/simplepie.inc'; if (!strlen($xml)) { logger('consume_feed: empty input'); return; } $feed = new SimplePie(); $feed->set_raw_data($xml); if ($datedir) { $feed->enable_order_by_date(true); } else { $feed->enable_order_by_date(false); } $feed->init(); if ($feed->error()) { logger('consume_feed: Error parsing XML: ' . $feed->error()); } $permalink = $feed->get_permalink(); // Check at the feed level for updated contact name and/or photo $name_updated = ''; $new_name = ''; $photo_timestamp = ''; $photo_url = ''; $birthday = ''; $hubs = $feed->get_links('hub'); if (count($hubs)) { $hub = implode(',', $hubs); } $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'owner'); if (!$rawtags) { $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); } if ($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']; $new_name = $elems['name'][0]['data']; } if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; } if (x($rawtags[0]['child'], NAMESPACE_DFRN) && x($rawtags[0]['child'][NAMESPACE_DFRN], 'birthday')) { $birthday = datetime_convert('UTC', 'UTC', $rawtags[0]['child'][NAMESPACE_DFRN]['birthday'][0]['data']); } } if (is_array($contact) && $photo_timestamp && strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) { logger('consume_feed: Updating photo for ' . $contact['name']); require_once "Photo.php"; $photo_failure = false; $have_photo = false; $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1", intval($contact['id']), intval($contact['uid'])); if (count($r)) { $resource_id = $r[0]['resource-id']; $have_photo = true; } else { $resource_id = photo_new_resource(); } $img_str = fetch_url($photo_url, true); $img = new Photo($img_str); if ($img->is_valid()) { if ($have_photo) { q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d", dbesc($resource_id), intval($contact['id']), intval($contact['uid'])); } $img->scaleImageSquare(175); $hash = $resource_id; $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4); $img->scaleImage(80); $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5); $img->scaleImage(48); $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6); $a = get_app(); q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' \n\t\t\t\tWHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.jpg'), dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.jpg'), dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.jpg'), intval($contact['uid']), intval($contact['id'])); } } if (is_array($contact) && $name_updated && strlen($new_name) && $name_updated > $contact['name-date']) { $r = q("select * from contact where uid = %d and id = %d limit 1", intval($contact['uid']), intval($contact['id'])); $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($contact['uid']), intval($contact['id'])); // do our best to update the name on content items if (count($r)) { q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", dbesc(notags(trim($new_name))), dbesc($r[0]['name']), dbesc($r[0]['url']), intval($contact['uid'])); } } if (strlen($birthday)) { if (substr($birthday, 0, 4) != $contact['bdyear']) { logger('consume_feed: updating birthday: ' . $birthday); /** * * Add new birthday event for this person * * $bdtext is just a readable placeholder in case the event is shared * with others. We will replace it during presentation to our $importer * to contain a sparkle link and perhaps a photo. * */ $bdtext = t('Birthday:') . ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`)\n\t\t\t\tVALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($contact['uid']), intval($contact['id']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert('UTC', 'UTC', $birthday)), dbesc(datetime_convert('UTC', 'UTC', $birthday . ' + 1 day ')), dbesc($bdtext), dbesc('birthday')); // update bdyear q("UPDATE `contact` SET `bdyear` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(substr($birthday, 0, 4)), intval($contact['uid']), intval($contact['id'])); // This function is called twice without reloading the contact // Make sure we only create one event. This is why &$contact // is a reference var in this function $contact['bdyear'] = substr($birthday, 0, 4); } } $community_page = 0; $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community'); if ($rawtags) { $community_page = intval($rawtags[0]['data']); } if (is_array($contact) && intval($contact['forum']) != $community_page) { q("update contact set forum = %d where id = %d limit 1", intval($community_page), intval($contact['id'])); $contact['forum'] = (string) $community_page; } // process any deleted entries $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); if (is_array($del_entries) && count($del_entries) && $pass != 2) { foreach ($del_entries as $dentry) { $deleted = false; if (isset($dentry['attribs']['']['ref'])) { $uri = $dentry['attribs']['']['ref']; $deleted = true; if (isset($dentry['attribs']['']['when'])) { $when = $dentry['attribs']['']['when']; $when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s'); } else { $when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s'); } } if ($deleted && is_array($contact)) { $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join `contact` on `item`.`contact-id` = `contact`.`id` \n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['uid']), intval($contact['id'])); if (count($r)) { $item = $r[0]; if (!$item['deleted']) { logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG); } if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) { $xo = parse_xml_string($item['object'], false); $xt = parse_xml_string($item['target'], false); if ($xt->type === ACTIVITY_OBJ_NOTE) { $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid'])); if (count($i)) { // For tags, the owner cannot remove the tag on the author's copy of the post. $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false; $author_remove = $item['origin'] && $item['self'] ? true : false; $author_copy = $item['origin'] ? true : false; if ($owner_remove && $author_copy) { continue; } if ($author_remove || $owner_remove) { $tags = explode(',', $i[0]['tag']); $newtags = array(); if (count($tags)) { foreach ($tags as $tag) { if (trim($tag) !== trim($xo->body)) { $newtags[] = trim($tag); } } } q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id'])); } } } } if ($item['uri'] == $item['parent-uri']) { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['uid'])); } else { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = '' \n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['uid'])); if ($item['last-child']) { // ensure that last-child is set in case the comment that had it just got wiped. q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid'])); // who is the last child now? $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `moderated` = 0 AND `uid` = %d \n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['uid'])); if (count($r)) { q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id'])); } } } } } } } // Now process the feed if ($feed->get_item_quantity()) { logger('consume_feed: feed item count = ' . $feed->get_item_quantity()); // in inverse date order if ($datedir) { $items = array_reverse($feed->get_items()); } else { $items = $feed->get_items(); } foreach ($items as $item) { $is_reply = false; $item_id = $item->get_id(); $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to'); if (isset($rawthread[0]['attribs']['']['ref'])) { $is_reply = true; $parent_uri = $rawthread[0]['attribs']['']['ref']; } if ($is_reply && is_array($contact)) { if ($pass == 1) { continue; } // Have we seen it? If not, import it. $item_id = $item->get_id(); $datarray = get_atom_elements($feed, $item); if (!x($datarray, 'author-name') && $contact['network'] != NETWORK_DFRN) { $datarray['author-name'] = $contact['name']; } if (!x($datarray, 'author-link') && $contact['network'] != NETWORK_DFRN) { $datarray['author-link'] = $contact['url']; } if (!x($datarray, 'author-avatar') && $contact['network'] != NETWORK_DFRN) { $datarray['author-avatar'] = $contact['thumb']; } if (!x($datarray, 'author-name') || !x($datarray, 'author-link')) { logger('consume_feed: no author information! ' . print_r($datarray, true)); continue; } $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid'])); // Update content if 'updated' changes if (count($r)) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['uid'])); } // update last-child if it changes $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] != $r[0]['last-child']) { $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['uid'])); $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['uid'])); } continue; } $force_parent = false; if ($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'], 'twitter.com')) { if ($contact['network'] === NETWORK_OSTATUS) { $force_parent = true; } if (strlen($datarray['title'])) { unset($datarray['title']); } $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['uid'])); $datarray['last-child'] = 1; } if ($contact['network'] === NETWORK_FEED || !strlen($contact['notify'])) { // one way feed - no remote comment ability $datarray['last-child'] = 0; } $datarray['parent-uri'] = $parent_uri; $datarray['uid'] = $importer['uid']; $datarray['contact-id'] = $contact['id']; if (activity_match($datarray['verb'], ACTIVITY_LIKE) || activity_match($datarray['verb'], ACTIVITY_DISLIKE)) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; // only one like or dislike per person $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb'])); if ($r && count($r)) { continue; } } if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) { $xo = parse_xml_string($datarray['object'], false); $xt = parse_xml_string($datarray['target'], false); if ($xt->type == ACTIVITY_OBJ_NOTE) { $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid'])); if (!count($r)) { continue; } // extract tag, if not duplicate, add to parent item if ($xo->id && $xo->content) { $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]'; if (!stristr($r[0]['tag'], $newtag)) { q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag), intval($r[0]['id'])); } } } } $r = item_store($datarray, $force_parent); continue; } else { // Head post of a conversation. Have we seen it? If not, import it. $item_id = $item->get_id(); $datarray = get_atom_elements($feed, $item); if (is_array($contact)) { if (!x($datarray, 'author-name') && $contact['network'] != NETWORK_DFRN) { $datarray['author-name'] = $contact['name']; } if (!x($datarray, 'author-link') && $contact['network'] != NETWORK_DFRN) { $datarray['author-link'] = $contact['url']; } if (!x($datarray, 'author-avatar') && $contact['network'] != NETWORK_DFRN) { $datarray['author-avatar'] = $contact['thumb']; } } if (!x($datarray, 'author-name') || !x($datarray, 'author-link')) { logger('consume_feed: no author information! ' . print_r($datarray, true)); continue; } // special handling for events if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) { $ev = bbtoevent($datarray['body']); if (x($ev, 'desc') && x($ev, 'start')) { $ev['uid'] = $importer['uid']; $ev['uri'] = $item_id; $ev['edited'] = $datarray['edited']; $ev['private'] = $datarray['private']; if (is_array($contact)) { $ev['cid'] = $contact['id']; } $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid'])); if (count($r)) { $ev['id'] = $r[0]['id']; } $xyz = event_store($ev); continue; } } $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid'])); // Update content if 'updated' changes if (count($r)) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['uid'])); } // update last-child if it changes $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] != $r[0]['last-child']) { $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['uid'])); } continue; } if (activity_match($datarray['verb'], ACTIVITY_FOLLOW)) { logger('consume-feed: New follower'); new_follower($importer, $contact, $datarray, $item); return; } if (activity_match($datarray['verb'], ACTIVITY_UNFOLLOW)) { lose_follower($importer, $contact, $datarray, $item); return; } if (activity_match($datarray['verb'], ACTIVITY_REQ_FRIEND)) { logger('consume-feed: New friend request'); new_follower($importer, $contact, $datarray, $item, true); return; } if (activity_match($datarray['verb'], ACTIVITY_UNFRIEND)) { lose_sharer($importer, $contact, $datarray, $item); return; } if (!is_array($contact)) { return; } if ($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'], 'twitter.com')) { if (strlen($datarray['title'])) { unset($datarray['title']); } $datarray['last-child'] = 1; } if ($contact['network'] === NETWORK_FEED || !strlen($contact['notify'])) { // one way feed - no remote comment ability $datarray['last-child'] = 0; } // This is my contact on another system, but it's really me. // Turn this into a wall post. if ($contact['remote_self']) { $datarray['wall'] = 1; } $datarray['parent-uri'] = $item_id; $datarray['uid'] = $importer['uid']; $datarray['contact-id'] = $contact['id']; if (!link_compare($datarray['owner-link'], $contact['url'])) { // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, // but otherwise there's a possible data mixup on the sender's system. // the tgroup delivery code called from item_store will correct it if it's a forum, // but we're going to unconditionally correct it here so that the post will always be owned by our contact. logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); $datarray['owner-name'] = $contact['name']; $datarray['owner-link'] = $contact['url']; $datarray['owner-avatar'] = $contact['thumb']; } $r = item_store($datarray); continue; } } } }
if (($status == 0 || $status == 3) && $intro_id) { // delete the notification $r = q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($intro_id)); } if ($status != 0) { killme(); } require_once "Photo.php"; $photo_failure = false; $filename = basename($intro['photo']); $img_str = fetch_url($intro['photo'], true); $img = new Photo($img_str); if ($img) { $img->scaleImageSquare(175); $hash = hash('md5', uniqid(mt_rand(), true)); $r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 5); if ($r === false) { $photo_failure = true; } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg'; $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg'; } else { $photo_failure = true; } if ($photo_failure) { $photo = $a->get_baseurl() . '/images/default-profile.jpg';
function store_photo($a, $uid, $imagedata = "", $url = "") { $r = q("SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`\n\t\tWHERE `user`.`uid` = %d AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", intval($uid)); if (!count($r)) { logger("Can't detect user data for uid " . $uid, LOGGER_DEBUG); return array(); } $page_owner_nick = $r[0]['nickname']; // To-Do: // $default_cid = $r[0]['id']; // $community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false); if (strlen($imagedata) == 0 and $url == "") { logger("No image data and no url provided", LOGGER_DEBUG); return array(); } elseif (strlen($imagedata) == 0) { logger("Uploading picture from " . $url, LOGGER_DEBUG); $imagedata = @file_get_contents($url); } $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && strlen($imagedata) > $maximagesize) { logger("Image exceeds size limit of " . $maximagesize, LOGGER_DEBUG); return array(); } /* $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($uid) ); $limit = service_class_fetch($uid,'photo_upload_limit'); if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { logger("Image exceeds personal limit of uid ".$uid, LOGGER_DEBUG); return(array()); } */ $tempfile = tempnam(get_temppath(), "cache"); file_put_contents($tempfile, $imagedata); $data = getimagesize($tempfile); if (!isset($data["mime"])) { unlink($tempfile); logger("File is no picture", LOGGER_DEBUG); return array(); } $ph = new Photo($imagedata, $data["mime"]); if (!$ph->is_valid()) { unlink($tempfile); logger("Picture is no valid picture", LOGGER_DEBUG); return array(); } $ph->orient($tempfile); unlink($tempfile); $max_length = get_config('system', 'max_image_length'); if (!$max_length) { $max_length = MAX_IMAGE_LENGTH; } if ($max_length > 0) { $ph->scaleImage($max_length); } $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = photo_new_resource(); $smallest = 0; // Pictures are always public by now //$defperm = '<'.$default_cid.'>'; $defperm = ""; $visitor = 0; $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm); if (!$r) { logger("Picture couldn't be stored", LOGGER_DEBUG); return array(); } $image = array("page" => $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash, "full" => $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt()); if ($width > 800 || $height > 800) { $image["large"] = $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm); if ($r) { $image["medium"] = $a->get_baseurl() . "/photo/{$hash}-1." . $ph->getExt(); } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm); if ($r) { $image["small"] = $a->get_baseurl() . "/photo/{$hash}-2." . $ph->getExt(); } } if ($width > 160 and $height > 160) { $x = 0; $y = 0; $min = $ph->getWidth(); if ($min > 160) { $x = ($min - 160) / 2; } if ($ph->getHeight() < $min) { $min = $ph->getHeight(); if ($min > 160) { $y = ($min - 160) / 2; } } $min = 160; $ph->cropImage(160, $x, $y, $min, $min); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm); if ($r) { $image["thumb"] = $a->get_baseurl() . "/photo/{$hash}-3." . $ph->getExt(); } } // Set the full image as preview image. This will be overwritten, if the picture is larger than 640. $image["preview"] = $image["full"]; // Deactivated, since that would result in a cropped preview, if the picture wasn't larger than 320 //if (isset($image["thumb"])) // $image["preview"] = $image["thumb"]; // Unsure, if this should be activated or deactivated //if (isset($image["small"])) // $image["preview"] = $image["small"]; if (isset($image["medium"])) { $image["preview"] = $image["medium"]; } return $image; }
function import_profile_photo($photo, $uid, $cid) { $a = get_app(); $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); $img = new Photo($img_str); if ($img->is_valid()) { $img->scaleImageSquare(175); $hash = photo_new_resource(); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6); if ($r === false) { $photo_failure = true; } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg'; $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg'; $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.jpg'; } else { $photo_failure = true; } if ($photo_failure) { $photo = $a->get_baseurl() . '/images/default-profile.jpg'; $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg'; $micro = $a->get_baseurl() . '/images/default-profile-mm.jpg'; } return array($photo, $thumb, $micro); }
$photo_url = $feed->get_image_url(); } } if ($photo_timestamp && strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) { require_once "Photo.php"; $photo_failure = false; $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d LIMIT 1", intval($contact['id'])); if (count($r)) { $resource_id = $r[0]['resource-id']; $img_str = fetch_url($photo_url, true); $img = new Photo($img_str); if ($img) { q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND contact-id` = %d ", dbesc($resource_id), intval($contact['id'])); $img->scaleImageSquare(175); $hash = $resource_id; $r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos'), 4); $img->scaleImage(80); $r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos'), 5); if ($r) { q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($contact['id'])); } } } } if ($name_updated && strlen($new_name) && $name_updated > $contact['name-date']) { q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `id` = %d LIMIT 1", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($contact['id'])); } // Now process the feed foreach ($feed->get_items() as $item) { $deleted = false; $rawdelete = $item->get_item_tags("http://purl.org/atompub/tombstones/1.0", 'deleted-entry');
function wall_upload_post(&$a) { logger("wall upload: starting new upload", LOGGER_DEBUG); if ($a->argc > 1) { if (!x($_FILES, 'media')) { $nick = $a->argv[1]; $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick)); if (!count($r)) { return; } } else { $user_info = api_get_user($a); $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name'])); } } else { return; } $can_post = false; $visitor = 0; $page_owner_uid = $r[0]['uid']; $default_cid = $r[0]['id']; $page_owner_nick = $r[0]['nickname']; $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $page_owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { $cid = 0; if (is_array($_SESSION['remote'])) { foreach ($_SESSION['remote'] as $v) { if ($v['uid'] == $page_owner_uid) { $cid = $v['cid']; break; } } } if ($cid) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($cid), intval($page_owner_uid)); if (count($r)) { $can_post = true; $visitor = $cid; } } } } if (!$can_post) { notice(t('Permission denied.') . EOL); killme(); } if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) { killme(); } if (x($_FILES, 'userfile')) { $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $filetype = $_FILES['userfile']['type']; } elseif (x($_FILES, 'media')) { $src = $_FILES['media']['tmp_name']; $filename = basename($_FILES['media']['name']); $filesize = intval($_FILES['media']['size']); $filetype = $_FILES['media']['type']; } if ($filetype == "") { $filetype = guess_image_type($filename); } $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL; @unlink($src); killme(); } $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($page_owner_uid)); $limit = service_class_fetch($page_owner_uid, 'photo_upload_limit'); if ($limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) { echo upgrade_message(true) . EOL; @unlink($src); killme(); } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata, $filetype); if (!$ph->is_valid()) { echo t('Unable to process image.') . EOL; @unlink($src); killme(); } $ph->orient($src); @unlink($src); $max_length = get_config('system', 'max_image_length'); if (!$max_length) { $max_length = MAX_IMAGE_LENGTH; } if ($max_length > 0) { $ph->scaleImage($max_length); } $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = photo_new_resource(); $smallest = 0; $defperm = '<' . $default_cid . '>'; $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); if (!$r) { echo t('Image upload failed.') . EOL; killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); if ($r) { $smallest = 1; } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); if ($r) { $smallest = 2; } } $basename = basename($filename); /* mod Waitman Gobble NO WARRANTY */ //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post) if ($_REQUEST['hush'] != 'yeah') { if (local_user() && (!feature_enabled(local_user(), 'richtext') || x($_REQUEST['nomce']))) { echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]\n\n"; } else { echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "\" alt=\"{$basename}\" /></a><br /><br />"; } } else { $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]"; return $m; } /* mod Waitman Gobble NO WARRANTY */ killme(); // NOTREACHED }
function update_1014() { require_once 'include/Photo.php'; q("ALTER TABLE `contact` ADD `micro` TEXT NOT NULL AFTER `thumb` "); $r = q("SELECT * FROM `photo` WHERE `scale` = 4"); if (count($r)) { foreach ($r as $rr) { $ph = new Photo($rr['data']); if ($ph->is_valid()) { $ph->scaleImage(48); $ph->store($rr['uid'], $rr['contact-id'], $rr['resource-id'], $rr['filename'], $rr['album'], 6, $rr['profile'] ? 1 : 0); } } } $r = q("SELECT * FROM `contact` WHERE 1"); if (count($r)) { foreach ($r as $rr) { if (stristr($rr['thumb'], 'avatar')) { q("UPDATE `contact` SET `micro` = '%s' WHERE `id` = %d LIMIT 1", dbesc(str_replace('avatar', 'micro', $rr['thumb'])), intval($rr['id'])); } else { q("UPDATE `contact` SET `micro` = '%s' WHERE `id` = %d LIMIT 1", dbesc(str_replace('5.jpg', '6.jpg', $rr['thumb'])), intval($rr['id'])); } } } }
function wall_upload_post(&$a) { if ($a->argc > 1) { $nick = $a->argv[1]; $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 LIMIT 1", dbesc($nick)); if (!count($r)) { return; } } else { return; } $can_post = false; $visitor = 0; $page_owner_uid = $r[0]['uid']; $page_owner_nick = $r[0]['nickname']; $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $page_owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid)); if (count($r)) { $can_post = true; $visitor = remote_user(); } } } if (!$can_post) { notice(t('Permission denied.') . EOL); killme(); } if (!x($_FILES, 'userfile')) { killme(); } $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL; @unlink($src); killme(); } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata); if (!$ph->is_valid()) { echo t('Unable to process image.') . EOL; @unlink($src); killme(); } @unlink($src); $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = photo_new_resource(); $smallest = 0; $defperm = '<' . $page_owner_uid . '>'; $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); if (!$r) { echo t('Image upload failed.') . EOL; killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); if ($r) { $smallest = 1; } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); if ($r) { $smallest = 2; } } $basename = basename($filename); echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg\" alt=\"{$basename}\" /></a><br /><br />"; killme(); // NOTREACHED }
function profile_photo_post(&$a) { if (!local_user()) { notice(t('Permission denied.') . EOL); return; } check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); if (x($_POST, 'cropfinal') && $_POST['cropfinal'] == 1) { // unless proven otherwise $is_default_profile = 1; if ($_REQUEST['profile']) { $r = q("select id, `is-default` from profile where id = %d and uid = %d limit 1", intval($_REQUEST['profile']), intval(local_user())); if (count($r) && !intval($r[0]['is-default'])) { $is_default_profile = 0; } } // phase 2 - we have finished cropping if ($a->argc != 2) { notice(t('Image uploaded but image cropping failed.') . EOL); return; } $image_id = $a->argv[1]; if (substr($image_id, -2, 1) == '-') { $scale = substr($image_id, -1, 1); $image_id = substr($image_id, 0, -2); } $srcX = $_POST['xstart']; $srcY = $_POST['ystart']; $srcW = $_POST['xfinal'] - $srcX; $srcH = $_POST['yfinal'] - $srcY; $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = %d LIMIT 1", dbesc($image_id), dbesc(local_user()), intval($scale)); if (count($r)) { $base_image = $r[0]; $im = new Photo($base_image['data'], $base_image['type']); if ($im->is_valid()) { $im->cropImage(175, $srcX, $srcY, $srcW, $srcH); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 4, $is_default_profile); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "175") . EOL); } $im->scaleImage(80); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 5, $is_default_profile); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "80") . EOL); } $im->scaleImage(48); $r = $im->store(local_user(), 0, $base_image['resource-id'], $base_image['filename'], t('Profile Photos'), 6, $is_default_profile); if ($r === false) { notice(sprintf(t('Image size reduction [%s] failed.'), "48") . EOL); } // If setting for the default profile, unset the profile photo flag from any other photos I own if ($is_default_profile) { $r = q("UPDATE `photo` SET `profile` = 0 WHERE `profile` = 1 AND `resource-id` != '%s' AND `uid` = %d", dbesc($base_image['resource-id']), intval(local_user())); $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `self` AND `uid` = %d", dbesc($a->get_baseurl() . '/photo/' . $base_image['resource-id'] . '-4.' . $im->getExt()), dbesc($a->get_baseurl() . '/photo/' . $base_image['resource-id'] . '-5.' . $im->getExt()), dbesc($a->get_baseurl() . '/photo/' . $base_image['resource-id'] . '-6.' . $im->getExt()), intval(local_user())); } else { $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", dbesc($a->get_baseurl() . '/photo/' . $base_image['resource-id'] . '-4.' . $im->getExt()), dbesc($a->get_baseurl() . '/photo/' . $base_image['resource-id'] . '-5.' . $im->getExt()), intval($_REQUEST['profile']), intval(local_user())); } // we'll set the updated profile-photo timestamp even if it isn't the default profile, // so that browsers will do a cache update unconditionally $r = q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `self` = 1 AND `uid` = %d", dbesc(datetime_convert()), intval(local_user())); info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); // Update global directory in background $url = $a->get_baseurl() . '/profile/' . $a->user['nickname']; if ($url && strlen(get_config('system', 'directory'))) { proc_run('php', "include/directory.php", "{$url}"); } require_once 'include/profile_update.php'; profile_change(); } else { notice(t('Unable to process image') . EOL); } } goaway($a->get_baseurl() . '/profiles'); return; // NOTREACHED } $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $filetype = $_FILES['userfile']['type']; if ($filetype == "") { $filetype = guess_image_type($filename); } $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { notice(sprintf(t('Image exceeds size limit of %s'), formatBytes($maximagesize)) . EOL); @unlink($src); return; } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata, $filetype); if (!$ph->is_valid()) { notice(t('Unable to process image.') . EOL); @unlink($src); return; } $ph->orient($src); @unlink($src); return profile_photo_crop_ui_head($a, $ph); }
public function addPhoto($id) { $photo = new Photo('groupe'); if ($photo->store('photo')) { $this->executerRequete("INSERT INTO photo SET nom = ?, id_groupe = ?", [$photo->path, $id]); } }
function wall_upload_post(&$a, $desktopmode = true) { logger("wall upload: starting new upload", LOGGER_DEBUG); $r_json = x($_GET, 'response') && $_GET['response'] == 'json'; if ($a->argc > 1) { if (!x($_FILES, 'media')) { $nick = $a->argv[1]; $r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick)); if (!count($r)) { if ($r_json) { echo json_encode(['error' => t('Invalid request.')]); killme(); } return; } } else { $user_info = api_get_user($a); $r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name'])); } } else { if ($r_json) { echo json_encode(['error' => t('Invalid request.')]); killme(); } return; } $can_post = false; $visitor = 0; $page_owner_uid = $r[0]['uid']; $default_cid = $r[0]['id']; $page_owner_nick = $r[0]['nickname']; $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $page_owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { $cid = 0; if (is_array($_SESSION['remote'])) { foreach ($_SESSION['remote'] as $v) { if ($v['uid'] == $page_owner_uid) { $cid = $v['cid']; break; } } } if ($cid) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($cid), intval($page_owner_uid)); if (count($r)) { $can_post = true; $visitor = $cid; } } } } if (!$can_post) { if ($r_json) { echo json_encode(['error' => t('Permission denied.')]); killme(); } notice(t('Permission denied.') . EOL); killme(); } if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) { if ($r_json) { echo json_encode(['error' => t('Invalid request.')]); killme(); } killme(); } $src = ""; if (x($_FILES, 'userfile')) { $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $filetype = $_FILES['userfile']['type']; } elseif (x($_FILES, 'media')) { if (is_array($_FILES['media']['tmp_name'])) { $src = $_FILES['media']['tmp_name'][0]; } else { $src = $_FILES['media']['tmp_name']; } if (is_array($_FILES['media']['name'])) { $filename = basename($_FILES['media']['name'][0]); } else { $filename = basename($_FILES['media']['name']); } if (is_array($_FILES['media']['size'])) { $filesize = intval($_FILES['media']['size'][0]); } else { $filesize = intval($_FILES['media']['size']); } if (is_array($_FILES['media']['type'])) { $filetype = $_FILES['media']['type'][0]; } else { $filetype = $_FILES['media']['type']; } } if ($src == "") { if ($r_json) { echo json_encode(['error' => t('Invalid request.')]); killme(); } notice(t('Invalid request.') . EOL); killme(); } // This is a special treatment for picture upload from Twidere if ($filename == "octet-stream" and $filetype != "") { $filename = $filetype; $filetype = ""; } if ($filetype == "") { $filetype = guess_image_type($filename); } // If there is a temp name, then do a manual check // This is more reliable than the provided value $imagedata = getimagesize($src); if ($imagedata) { $filetype = $imagedata['mime']; } logger("File upload src: " . $src . " - filename: " . $filename . " - size: " . $filesize . " - type: " . $filetype, LOGGER_DEBUG); $maximagesize = get_config('system', 'maximagesize'); if ($maximagesize && $filesize > $maximagesize) { $msg = sprintf(t('Image exceeds size limit of %s'), formatBytes($maximagesize)); if ($r_json) { echo json_encode(['error' => $msg]); } else { echo $msg . EOL; } @unlink($src); killme(); } $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($page_owner_uid)); $limit = service_class_fetch($page_owner_uid, 'photo_upload_limit'); if ($limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) { $msg = upgrade_message(true); if ($r_json) { echo json_encode(['error' => $msg]); } else { echo $msg . EOL; } @unlink($src); killme(); } $imagedata = @file_get_contents($src); $ph = new Photo($imagedata, $filetype); if (!$ph->is_valid()) { $msg = t('Unable to process image.'); if ($r_json) { echo json_encode(['error' => $msg]); } else { echo $msg . EOL; } @unlink($src); killme(); } $ph->orient($src); @unlink($src); $max_length = get_config('system', 'max_image_length'); if (!$max_length) { $max_length = MAX_IMAGE_LENGTH; } if ($max_length > 0) { $ph->scaleImage($max_length); logger("File upload: Scaling picture to new size " . $max_length, LOGGER_DEBUG); } $width = $ph->getWidth(); $height = $ph->getHeight(); $hash = photo_new_resource(); $smallest = 0; $defperm = '<' . $default_cid . '>'; $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); if (!$r) { $msg = t('Image upload failed.'); if ($r_json) { echo json_encode(['error' => $msg]); } else { echo $msg . EOL; } killme(); } if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); if ($r) { $smallest = 1; } } if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); if ($r and $smallest == 0) { $smallest = 2; } } $basename = basename($filename); if (!$desktopmode) { $r = q("SELECT `id`, `datasize`, `width`, `height`, `type` FROM `photo` WHERE `resource-id` = '%s' ORDER BY `width` DESC LIMIT 1", $hash); if (!$r) { if ($r_json) { echo json_encode(['error' => '']); killme(); } return false; } $picture = array(); $picture["id"] = $r[0]["id"]; $picture["size"] = $r[0]["datasize"]; $picture["width"] = $r[0]["width"]; $picture["height"] = $r[0]["height"]; $picture["type"] = $r[0]["type"]; $picture["albumpage"] = $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash; $picture["picture"] = $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt(); $picture["preview"] = $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt(); if ($r_json) { echo json_encode(['picture' => $picture]); killme(); } return $picture; } if ($r_json) { echo json_encode(['ok' => true]); killme(); } /* mod Waitman Gobble NO WARRANTY */ //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post) if ($_REQUEST['hush'] != 'yeah') { if (local_user() && (!feature_enabled(local_user(), 'richtext') || x($_REQUEST['nomce']))) { echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]\n\n"; } else { echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "\" alt=\"{$basename}\" /></a><br /><br />"; } } else { $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]"; return $m; } /* mod Waitman Gobble NO WARRANTY */ killme(); // NOTREACHED }
$userId = npadmin_loginData()->getUser()->userId; $contestId = $_POST['contest_id'] !== null ? $_POST['contest_id'] : $_GET['contest_id']; $contest = Contest::loadContest($contestId); npadmin_security($contest->getAllowedGroups(), false, _("You are not invited to this contest") . " (ID: " . $contestId . ")", true); if ($_POST['op'] == 'upload') { if ($_FILES['photoFile']['error'] === 0) { if ($contest->status === STATUS_OPEN) { $photos = $contest->photosOfUser($userId); if (count($photos) < $contest->numberPhotos) { $photo = new Photo(); $photo->userId = $userId; $photo->contestId = $contestId; $photo->title = $_POST['title']; $photo->description = $_POST['description']; $photo->exif = read_exif_data($_FILES['photoFile']['tmp_name']); if ($photo->store()) { $photo_filename = "../" . $photo->getUrl(); $photo_filename_thumb = "../" . $photo->getThumbUrl(); if (move_uploaded_file($_FILES['photoFile']['tmp_name'], $photo_filename)) { $image = new NP_Image($photo_filename); $image_resized = $image->resizeMaxSize(1024); $image_resized->save($photo_filename); $image_thumb = $image->resizeMaxSize(240); if ($image_thumb->save($photo_filename_thumb)) { echo "OK: " . $photo_filename; } else { echo _("ERROR: Could not create thumbnail"); } $image->close(); $image_resized->close(); $image_thumb->close();