Merge branch 'master' of git://github.com/friendika/friendika

This commit is contained in:
root 2010-12-12 10:34:34 +01:00
commit 2e9dca7c9f
18 changed files with 275 additions and 100 deletions

193
boot.php
View file

@ -7,8 +7,11 @@ define ( 'DFRN_PROTOCOL_VERSION', '2.0' );
define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
// log levels
define ( 'DOWN_ARROW', '&#x21e9;' );
/**
* log levels
*/
define ( 'LOGGER_NORMAL', 0 );
define ( 'LOGGER_TRACE', 1 );
@ -16,37 +19,49 @@ define ( 'LOGGER_DEBUG', 2 );
define ( 'LOGGER_DATA', 3 );
define ( 'LOGGER_ALL', 4 );
// registration policy
/**
* registration policies
*/
define ( 'REGISTER_CLOSED', 0 );
define ( 'REGISTER_APPROVE', 1 );
define ( 'REGISTER_OPEN', 2 );
// relationship types
/**
* relationship types
*/
define ( 'REL_VIP', 1);
define ( 'REL_FAN', 2);
define ( 'REL_BUD', 3);
// page/profile types
// PAGE_NORMAL is a typical personal profile account
// PAGE_SOAPBOX automatically approves all friend requests as REL_FAN, (readonly)
// PAGE_COMMUNITY automatically approves all friend requests as REL_FAN, but with
// write access to wall and comments (no email and not included in page owner's ACL lists)
// PAGE_FREELOVE automatically approves all friend requests as full friends (REL_BUD).
/**
*
* page/profile types
*
* PAGE_NORMAL is a typical personal profile account
* PAGE_SOAPBOX automatically approves all friend requests as REL_FAN, (readonly)
* PAGE_COMMUNITY automatically approves all friend requests as REL_FAN, but with
* write access to wall and comments (no email and not included in page owner's ACL lists)
* PAGE_FREELOVE automatically approves all friend requests as full friends (REL_BUD).
*
*/
define ( 'PAGE_NORMAL', 0 );
define ( 'PAGE_SOAPBOX', 1 );
define ( 'PAGE_COMMUNITY', 2 );
define ( 'PAGE_FREELOVE', 3 );
// Maximum number of "people who like (or don't like) this"
// that we will list by name
/**
* Maximum number of "people who like (or don't like) this" that we will list by name
*/
define ( 'MAX_LIKERS', 75);
// email notification options
/**
* email notification options
*/
define ( 'NOTIFY_INTRO', 0x0001 );
define ( 'NOTIFY_CONFIRM', 0x0002 );
@ -54,7 +69,9 @@ define ( 'NOTIFY_WALL', 0x0004 );
define ( 'NOTIFY_COMMENT', 0x0008 );
define ( 'NOTIFY_MAIL', 0x0010 );
// various namespaces we may need to parse
/**
* various namespaces we may need to parse
*/
define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' );
define ( 'NAMESPACE_THREAD' , 'http://purl.org/syndication/thread/1.0' );
@ -68,7 +85,9 @@ define ( 'NAMESPACE_GEORSS', 'http://www.georss.org/georss' );
define ( 'NAMESPACE_POCO', 'http://portablecontacts.net/spec/1.0' );
define ( 'NAMESPACE_FEED', 'http://schemas.google.com/g/2010#updates-from' );
// activity stream defines
/**
* activity stream defines
*/
define ( 'ACTIVITY_LIKE', NAMESPACE_ACTIVITY_SCHEMA . 'like' );
define ( 'ACTIVITY_DISLIKE', NAMESPACE_DFRN . '/dislike' );
@ -88,14 +107,21 @@ define ( 'ACTIVITY_OBJ_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'photo' );
define ( 'ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo' );
define ( 'ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' );
// item weight for query ordering
/**
* item weight for query ordering
*/
define ( 'GRAVITY_PARENT', 0);
define ( 'GRAVITY_LIKE', 3);
define ( 'GRAVITY_COMMENT', 6);
// Please disable magic_quotes_gpc so we don't have to do this.
// See http://php.net/manual/en/security.magicquotes.disabling.php
/**
*
* Reverse the effect of magic_quotes_gpc if it is enabled.
* Please disable magic_quotes_gpc so we don't have to do this.
* See http://php.net/manual/en/security.magicquotes.disabling.php
*
*/
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
@ -114,12 +140,18 @@ if (get_magic_quotes_gpc()) {
}
// Our main application structure for the life of this page
// Primarily deals with the URL that got us here
// and tries to make some sense of it, and
// stores our page contents and config storage
// and anything else that might need to be passed around
// before we spit the page out.
/**
*
* class: App
*
* Our main application structure for the life of this page
* Primarily deals with the URL that got us here
* and tries to make some sense of it, and
* stores our page contents and config storage
* and anything else that might need to be passed around
* before we spit the page out.
*
*/
if(! class_exists('App')) {
class App {
@ -169,10 +201,31 @@ class App {
if(x($_GET,'q'))
$this->cmd = trim($_GET['q'],'/');
/**
* Figure out if we are running at the top of a domain
* or in a sub-directory and adjust accordingly
*/
$path = trim(dirname($_SERVER['SCRIPT_NAME']),'/');
if(isset($path) && strlen($path) && ($path != $this->path))
$this->path = $path;
/**
*
* Break the URL path into C style argc/argv style arguments for our
* modules. Given "http://example.com/module/arg1/arg2", $this->argc
* will be 3 (integer) and $this->argv will contain:
* [0] => 'module'
* [1] => 'arg1'
* [2] => 'arg2'
*
*
* There will always be one argument. If provided a naked domain
* URL, $this->argv[0] is set to "home".
*
*/
$this->argv = explode('/',$this->cmd);
$this->argc = count($this->argv);
if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) {
@ -182,10 +235,20 @@ class App {
$this->module = 'home';
}
/**
* Special handling for the webfinger/lrdd host XRD file
* Just spit out the contents and exit.
*/
if($this->cmd === '.well-known/host-meta')
require_once('include/hostxrd.php');
/**
* See if there is any page number information, and initialise
* pagination
*/
$this->pager['page'] = ((x($_GET,'page')) ? $_GET['page'] : 1);
$this->pager['itemspage'] = 50;
$this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
@ -424,7 +487,10 @@ function fetch_url($url,$binary = false, &$redirects = 0) {
$a->set_curl_code(0);
$s = curl_exec($ch);
// don't let curl abort the entire application
// if it throws any errors.
$s = @curl_exec($ch);
$http_code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
$header = substr($s,0,strpos($s,"\r\n\r\n"));
@ -484,7 +550,10 @@ function post_url($url,$params, $headers = null, &$redirects = 0) {
$a->set_curl_code(0);
$s = curl_exec($ch);
// don't let curl abort the entire application
// if it throws any errors.
$s = @curl_exec($ch);
$http_code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
$header = substr($s,0,strpos($s,"\r\n\r\n"));
@ -1610,4 +1679,74 @@ function smilies($s) {
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" />',
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" />'
), $s);
}}
}}
/**
*
* Function : profile_load
* @parameter App $a
* @parameter string $nickname
* @parameter int $profile
*
* Summary: Loads a profile into the page sidebar.
* The function requires a writeable copy of the main App structure, and the nickname
* of a registered local account.
*
* If the viewer is an authenticated remote viewer, the profile displayed is the
* one that has been configured for his/her viewing in the Contact manager.
* Passing a non-zero profile ID can also allow a preview of a selected profile
* by the owner.
*
* Profile information is placed in the App structure for later retrieval.
* Honours the owner's chosen theme for display.
*
*/
if(! function_exists('profile_load')) {
function profile_load(&$a, $nickname, $profile = 0) {
if(remote_user()) {
$r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
intval($_SESSION['visitor_id']));
if(count($r))
$profile = $r[0]['profile-id'];
}
$r = null;
if($profile) {
$profile_int = intval($profile);
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `user`.* FROM `profile`
LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d LIMIT 1",
dbesc($nickname),
intval($profile_int)
);
}
if(! count($r)) {
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `user`.* FROM `profile`
LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 LIMIT 1",
dbesc($nickname)
);
}
if(($r === false) || (! count($r))) {
notice( t('No profile') . EOL );
$a->error = 404;
return;
}
$a->profile = $r[0];
$a->page['template'] = 'profile';
$a->page['title'] = $a->profile['name'];
$_SESSION['theme'] = $a->profile['theme'];
if(! (x($a->page,'aside')))
$a->page['aside'] = '';
$a->page['aside'] .= contact_block();
return;
}}

View file

@ -52,6 +52,7 @@ $a->config['php_path'] = 'php';
// Location of global directory submission page.
$a->config['system']['directory_submit_url'] = 'http://dir.friendika.com/submit';
$a->config['system']['directory_search_url'] = 'http://dir.friendika.com/directory?search=';
// PuSH - aka pubsubhubbub URL. This makes delivery of public posts as fast as private posts

View file

@ -80,7 +80,7 @@ function bbcode($Text) {
// Youtube extensions
$Text = preg_replace("/\[youtube\]http:\/\/www.youtube.com\/watch\?v\=(.+?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\](.+?)\[\/youtube\]/", '<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
$Text = preg_replace("/\[youtube\](.+?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
return $Text;
}

View file

@ -201,7 +201,15 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
logger('dfrn_confirm: Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params,true), LOGGER_DATA);
// POST all this stuff to the other site.
/**
*
* POST all this stuff to the other site.
* Temporarily raise the network timeout to 120 seconds because the default 60
* doesn't always give the other side quite enough time to decrypt everything.
*
*/
$a->config['system']['curl_timeout'] = 120;
$res = post_url($dfrn_confirm,$params);

View file

@ -353,6 +353,8 @@ function dfrn_poll_content(&$a) {
}
else {
$status = 1;
$challenge = '';
$encrypted_id = '';
}
if(($type === 'profile') && (strlen($sec))) {

View file

@ -6,7 +6,6 @@ function dfrn_request_init(&$a) {
if($a->argc > 1)
$which = $a->argv[1];
require_once('mod/profile.php');
profile_init($a,$which);
return;

View file

@ -5,7 +5,6 @@ function display_content(&$a) {
$o = '<div id="live-display"></div>' . "\r\n";
require_once('mod/profile.php');
profile_init($a);
$item_id = (($a->argc > 2) ? intval($a->argv[2]) : 0);

View file

@ -1,15 +1,22 @@
<?php
/**
* module: invite.php
*
* send email invitations to join social network
*
*/
function invite_post(&$a) {
if(! local_user()) {
notice( t('Permission denied.') . EOL);
return;
}
$recips = explode("\n",$_POST['recipients']);
$message = $_POST['message'];
$recips = ((x($_POST,'recipients')) ? explode("\n",$_POST['recipients']) : array());
$message = ((x($_POST,'message')) ? notags(trim($_POST['message'])) : '');
$total = 0;
@ -38,6 +45,7 @@ function invite_post(&$a) {
function invite_content(&$a) {
if(! local_user()) {
notice( t('Permission denied.') . EOL);
return;
@ -51,7 +59,7 @@ function invite_content(&$a) {
'$msg_text' => t('Your message:'),
'$default_message' => t('Please join my social network on ') . $a->config['sitename'] . t("\r\n") . t("\r\n")
. t('To accept this invitation, please visit:') . t("\r\n") . t("\r\n") . $a->get_baseurl()
. t("\r\n") . t("\r\n") . t('Once you have registered, please make an introduction via my profile page at:')
. t("\r\n") . t("\r\n") . t('Once you have registered, please connect with me via my profile page at:')
. t("\r\n") . t("\r\n") . $a->get_baseurl() . '/profile/' . $a->user['nickname'] ,
'$submit' => t('Submit')
));

View file

@ -1,53 +1,5 @@
<?php
if(! function_exists('profile_load')) {
function profile_load(&$a, $username, $profile = 0) {
if(remote_user()) {
$r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
intval($_SESSION['visitor_id']));
if(count($r))
$profile = $r[0]['profile-id'];
}
$r = null;
if($profile) {
$profile_int = intval($profile);
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `user`.* FROM `profile`
LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d LIMIT 1",
dbesc($username),
intval($profile_int)
);
}
if(! count($r)) {
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `user`.* FROM `profile`
LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 LIMIT 1",
dbesc($username)
);
}
if(($r === false) || (! count($r))) {
notice( t('No profile') . EOL );
$a->error = 404;
return;
}
$a->profile = $r[0];
$a->page['template'] = 'profile';
$a->page['title'] = $a->profile['name'];
$_SESSION['theme'] = $a->profile['theme'];
if(! (x($a->page,'aside')))
$a->page['aside'] = '';
$a->page['aside'] .= contact_block();
return;
}}
function profile_init(&$a) {
if($a->argc > 1)

View file

@ -8,7 +8,6 @@ function profile_photo_init(&$a) {
return;
}
require_once("mod/profile.php");
profile_load($a,$a->user['nickname']);
}

View file

@ -327,7 +327,6 @@ function profiles_content(&$a) {
return;
}
require_once('mod/profile.php');
profile_load($a,$a->user['nickname'],$r[0]['id']);
require_once('include/profile_selectors.php');

View file

@ -3,7 +3,6 @@
function settings_init(&$a) {
if(local_user()) {
require_once("mod/profile.php");
profile_load($a,$a->user['nickname']);
}
}

View file

@ -1,7 +1,11 @@
<?php
// This page is fetched via ajax to update the profile page with
// new content while you are viewing it.
/**
* Module: update_profile
* Purpose: AJAX synchronisation of profile page
*
*/
require_once('mod/profile.php');
@ -11,19 +15,34 @@ function update_profile_content(&$a) {
header("Content-type: text/html");
echo "<!DOCTYPE html><html><body>\r\n";
/**
* We can remove this hack once Internet Explorer recognises HTML5 natively
*/
echo (($_GET['msie'] == 1) ? '<div>' : '<section>');
// Grab the page inner contents, but move any image src attributes to another attribute name.
// Some browsers will prefetch all the images for the page even if we don't need them.
// The only ones we need to fetch are those for new page additions, which we'll discover
// on the client side and then swap the image back.
/**
*
* Grab the page inner contents by calling the content function from the profile module directly,
* but move any image src attributes to another attribute name. This is because
* some browsers will prefetch all the images for the page even if we don't need them.
* The only ones we need to fetch are those for new page additions, which we'll discover
* on the client side and then swap the image back.
*
*/
$text = profile_content($a,$profile_uid);
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
$replace = "<img\${1} dst=\"\${2}\"";
$text = preg_replace($pattern, $replace, $text);
$text = profile_content($a,$profile_uid);
echo str_replace("\t",' ',$text);
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
$replace = "<img\${1} dst=\"\${2}\"";
$text = preg_replace($pattern, $replace, $text);
/**
* reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
*/
echo str_replace("\t",' ',$text);
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
echo "</body></html>\r\n";
killme();

View file

@ -2,7 +2,6 @@
function viewcontacts_init(&$a) {
require_once("mod/profile.php");
profile_load($a,$a->argv[1]);
}

View file

@ -19,8 +19,9 @@ function wall_upload_post(&$a) {
$can_post = false;
$visitor = 0;
$page_owner_uid = $r[0]['uid'];
$community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
$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;
@ -97,7 +98,7 @@ function wall_upload_post(&$a) {
}
$basename = basename($filename);
echo "<br /><br /><img src=\"".$a->get_baseurl(). "/photo/{$hash}-{$smallest}.jpg\" alt=\"$basename\" /><br /><br />";
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();
return; // NOTREACHED

View file

@ -1,5 +1,20 @@
<?php
/**
*
* File: testargs.php
*
* Purpose:
* During installation we need to check if register_argc_argv is
* enabled for the command line PHP processor, because otherwise
* deliveries will fail. So we will do a shell exec of php and
* execute this file with a command line argument, and see if it
* echoes the argument back to us. Otherwise notify the person
* that their installation doesn't meet the system requirements.
*
*/
if(($argc > 1) && isset($argv[1]))
echo $argv[1];
else

View file

@ -1,5 +1,40 @@
<?php
/**
*
* update.php - automatic system update
*
* Automatically update database schemas and any other development changes such that
* copying the latest files from the source code repository will always perform a clean
* and painless upgrade.
*
* Each function in this file is named update_nnnn() where nnnn is an increasing number
* which began counting at 1000.
*
* At the top of the file "boot.php" is a define for BUILD_ID. Any time there is a change
* to the database schema or one which requires an upgrade path from the existing application,
* the BUILD_ID is incremented.
*
* The current BUILD_ID is stored in the config area of the database. If the application starts up
* and BUILD_ID is greater than the last stored build number, we will process every update function
* in order from the currently stored value to the new BUILD_ID. This is expected to bring the system
* up to current without requiring re-installation or manual intervention.
*
* Once the upgrade functions have completed, the current BUILD_ID is stored as the current value.
* The BUILD_ID will always be one greater than the last numbered script in this file.
*
* If you change the database schema, the following are required:
* 1. Update the file database.sql to match the new schema.
* 2. Update this file by adding a new function at the end with the number of the current BUILD_ID.
* This function should modify the current database schema and perform any other steps necessary
* to ensure that upgrade is silent and free from requiring interaction.
* 3. Increment the BUILD_ID in boot.php
* 4. TEST the upgrade prior to checkin and filing a pull request.
*
*/
function update_1000() {
q("ALTER TABLE `item` DROP `like`, DROP `dislike` ");

View file

@ -50,6 +50,7 @@ $a->config['php_path'] = '$phpath';
// Location of global directory submission page.
$a->config['system']['directory_submit_url'] = 'http://dir.friendika.com/submit';
$a->config['system']['directory_search_url'] = 'http://dir.friendika.com/directory?search=';
// PuSH - aka pubsubhubbub URL. This makes delivery of public posts as fast as private posts