This commit is contained in:
Sebastian Egbers 2012-06-26 08:33:41 +02:00
commit 0f0fb2e2f3
27 changed files with 745 additions and 471 deletions

View file

@ -10,9 +10,9 @@ require_once('include/nav.php');
require_once('include/cache.php'); require_once('include/cache.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_VERSION', '3.0.1384' ); define ( 'FRIENDICA_VERSION', '3.0.1385' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1150 ); define ( 'DB_UPDATE_VERSION', 1151 );
define ( 'EOL', "<br />\r\n" ); define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );

View file

@ -254,6 +254,7 @@ CREATE TABLE IF NOT EXISTS `event` (
`edited` datetime NOT NULL, `edited` datetime NOT NULL,
`start` datetime NOT NULL, `start` datetime NOT NULL,
`finish` datetime NOT NULL, `finish` datetime NOT NULL,
`summary` text NOT NULL,
`desc` text NOT NULL, `desc` text NOT NULL,
`location` text NOT NULL, `location` text NOT NULL,
`type` char(255) NOT NULL, `type` char(255) NOT NULL,
@ -263,7 +264,14 @@ CREATE TABLE IF NOT EXISTS `event` (
`allow_gid` mediumtext NOT NULL, `allow_gid` mediumtext NOT NULL,
`deny_cid` mediumtext NOT NULL, `deny_cid` mediumtext NOT NULL,
`deny_gid` mediumtext NOT NULL, `deny_gid` mediumtext NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`),
KEY `uid` ( `uid` ),
KEY `cid` ( `cid` ),
KEY `uri` ( `uri` ),
KEY `type` ( `type` ),
KEY `start` ( `start` ),
KEY `finish` ( `finish` ),
KEY `adjust` ( `adjust` )
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- -------------------------------------------------------- -- --------------------------------------------------------

View file

@ -565,18 +565,19 @@
if(requestdata('lat') && requestdata('long')) if(requestdata('lat') && requestdata('long'))
$_REQUEST['coord'] = sprintf("%s %s",requestdata('lat'),requestdata('long')); $_REQUEST['coord'] = sprintf("%s %s",requestdata('lat'),requestdata('long'));
$_REQUEST['profile_uid'] = local_user(); $_REQUEST['profile_uid'] = local_user();
if(requestdata('parent'))
if($parent)
$_REQUEST['type'] = 'net-comment'; $_REQUEST['type'] = 'net-comment';
else { else {
$_REQUEST['type'] = 'wall'; $_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) { if(x($_FILES,'media')) {
// upload the image if we have one // upload the image if we have one
$_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo $_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_upload.php'); require_once('mod/wall_upload.php');
$media = wall_upload_post($a); $media = wall_upload_post($a);
if(strlen($media)>0) if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n".$media; $_REQUEST['body'] .= "\n\n".$media;
} }
} }
// set this so that the item_post() function is quiet and doesn't redirect or emit json // set this so that the item_post() function is quiet and doesn't redirect or emit json

View file

@ -109,20 +109,22 @@ function bb2diaspora($Text,$preserve_nl = false) {
// "<li>" into a deeper nested element until it crashes. So pre-format // "<li>" into a deeper nested element until it crashes. So pre-format
// the lists as Diaspora lists before sending the $Text to bbcode() // the lists as Diaspora lists before sending the $Text to bbcode()
// //
// Note that regular expressions are really not suitable for parsing // Note that to get nested lists to work for Diaspora, we would need
// text with opening and closing tags, so nested lists may make things // to define the closing tag for the list elements. So nested lists
// wonky // are going to be flattened out in Diaspora for now
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) && (++$endlessloop < 20)) { while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) &&
(strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false) &&
(strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false) && (++$endlessloop < 20)) {
$Text = preg_replace_callback("/\[list\](.*?)\[\/list\]/is", 'diaspora_ul', $Text); $Text = preg_replace_callback("/\[list\](.*?)\[\/list\]/is", 'diaspora_ul', $Text);
$Text = preg_replace_callback("/\[list=1\](.*?)\[\/list\]/is", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=1\](.*?)\[\/list\]/is", 'diaspora_ol', $Text);
$Text = preg_replace_callback("/\[list=i\](.*?)\[\/list\]/s",'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=i\](.*?)\[\/list\]/s",'diaspora_ol', $Text);
$Text = preg_replace_callback("/\[list=I\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=I\](.*?)\[\/list\]/s", 'diaspora_ol', $Text);
$Text = preg_replace_callback("/\[list=a\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=a\](.*?)\[\/list\]/s", 'diaspora_ol', $Text);
$Text = preg_replace_callback("/\[list=A\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=A\](.*?)\[\/list\]/s", 'diaspora_ol', $Text);
$Text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/is", 'diaspora_ul', $Text);
$Text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/is", 'diaspora_ol', $Text);
} }
$Text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/is", 'diaspora_ul', $Text);
$Text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/is", 'diaspora_ol', $Text);
// Convert it to HTML - don't try oembed // Convert it to HTML - don't try oembed
$Text = bbcode($Text, $preserve_nl, false); $Text = bbcode($Text, $preserve_nl, false);

View file

@ -162,7 +162,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
// handle nested lists // handle nested lists
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/list]") !== false) and (strpos($Text, "[list") !== false) and (++$endlessloop < 20)) {
while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) &&
(strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false) &&
(strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false) && (++$endlessloop < 20)) {
$Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text); $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
@ -170,11 +173,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>' ,$Text);
$Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>' ,$Text);
$Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>' ,$Text);
$Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
$Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
} }
$Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
$Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
$Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>' ,$Text); $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>' ,$Text);
$Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text); $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text);
$Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text); $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text);
@ -295,12 +297,16 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = oembed_bbcode2html($Text); $Text = oembed_bbcode2html($Text);
// If we found an event earlier, strip out all the event code and replace with a reformatted version. // If we found an event earlier, strip out all the event code and replace with a reformatted version.
// Replace the event-start section with the entire formatted event. The other bbcode is stripped.
// Summary (e.g. title) is required, earlier revisions only required description (in addition to
// start which is always required). Allow desc with a missing summary for compatibility.
if(x($ev,'desc') && x($ev,'start')) { if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
$sub = format_event_html($ev); $sub = format_event_html($ev);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",$sub,$Text); $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",'',$Text); $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text); $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text); $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text); $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);

View file

@ -447,11 +447,13 @@ function update_contact_birthdays() {
* *
*/ */
$bdtext = t('Birthday:') . ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]' ; $bdtext = sprintf( t('%s\'s birthday'), $rr['name']);
$bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]') ;
$r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`,`adjust`)
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%d' ) ", $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`,`adjust`)
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d' ) ",
intval($rr['uid']), intval($rr['uid']),
intval($rr['id']), intval($rr['id']),
dbesc(datetime_convert()), dbesc(datetime_convert()),
@ -459,6 +461,7 @@ function update_contact_birthdays() {
dbesc(datetime_convert('UTC','UTC', $nextbd)), dbesc(datetime_convert('UTC','UTC', $nextbd)),
dbesc(datetime_convert('UTC','UTC', $nextbd . ' + 1 day ')), dbesc(datetime_convert('UTC','UTC', $nextbd . ' + 1 day ')),
dbesc($bdtext), dbesc($bdtext),
dbesc($bdtext2),
dbesc('birthday'), dbesc('birthday'),
intval(0) intval(0)
); );

View file

@ -113,7 +113,7 @@ function delivery_run($argv, $argc){
$uid = $r[0]['uid']; $uid = $r[0]['uid'];
$updated = $r[0]['edited']; $updated = $r[0]['edited'];
// The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up // POSSIBLE CLEANUP --> The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up
if(! $parent_id) if(! $parent_id)
continue; continue;

View file

@ -12,6 +12,9 @@ function format_event_html($ev) {
$o = '<div class="vevent">' . "\r\n"; $o = '<div class="vevent">' . "\r\n";
$o .= '<p class="summary event-summary">' . bbcode($ev['summary']) . '</p>' . "\r\n";
$o .= '<p class="description event-description">' . bbcode($ev['desc']) . '</p>' . "\r\n"; $o .= '<p class="description event-description">' . bbcode($ev['desc']) . '</p>' . "\r\n";
$o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="' $o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="'
@ -114,6 +117,9 @@ function format_event_bbcode($ev) {
$o = ''; $o = '';
if($ev['summary'])
$o .= '[event-summary]' . $ev['summary'] . '[/event-summary]';
if($ev['desc']) if($ev['desc'])
$o .= '[event-description]' . $ev['desc'] . '[/event-description]'; $o .= '[event-description]' . $ev['desc'] . '[/event-description]';
@ -147,6 +153,9 @@ function bbtoevent($s) {
$ev = array(); $ev = array();
$match = '';
if(preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is",$s,$match))
$ev['summary'] = $match[1];
$match = ''; $match = '';
if(preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is",$s,$match)) if(preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is",$s,$match))
$ev['desc'] = $match[1]; $ev['desc'] = $match[1];
@ -244,6 +253,7 @@ function event_store($arr) {
`edited` = '%s', `edited` = '%s',
`start` = '%s', `start` = '%s',
`finish` = '%s', `finish` = '%s',
`summary` = '%s',
`desc` = '%s', `desc` = '%s',
`location` = '%s', `location` = '%s',
`type` = '%s', `type` = '%s',
@ -258,6 +268,7 @@ function event_store($arr) {
dbesc($arr['edited']), dbesc($arr['edited']),
dbesc($arr['start']), dbesc($arr['start']),
dbesc($arr['finish']), dbesc($arr['finish']),
dbesc($arr['summary']),
dbesc($arr['desc']), dbesc($arr['desc']),
dbesc($arr['location']), dbesc($arr['location']),
dbesc($arr['type']), dbesc($arr['type']),
@ -306,9 +317,9 @@ function event_store($arr) {
// New event. Store it. // New event. Store it.
$r = q("INSERT INTO `event` ( `uid`,`cid`,`uri`,`created`,`edited`,`start`,`finish`,`desc`,`location`,`type`, $r = q("INSERT INTO `event` ( `uid`,`cid`,`uri`,`created`,`edited`,`start`,`finish`,`summary`, `desc`,`location`,`type`,
`adjust`,`nofinish`,`allow_cid`,`allow_gid`,`deny_cid`,`deny_gid`) `adjust`,`nofinish`,`allow_cid`,`allow_gid`,`deny_cid`,`deny_gid`)
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' ) ", VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' ) ",
intval($arr['uid']), intval($arr['uid']),
intval($arr['cid']), intval($arr['cid']),
dbesc($arr['uri']), dbesc($arr['uri']),
@ -316,6 +327,7 @@ function event_store($arr) {
dbesc($arr['edited']), dbesc($arr['edited']),
dbesc($arr['start']), dbesc($arr['start']),
dbesc($arr['finish']), dbesc($arr['finish']),
dbesc($arr['summary']),
dbesc($arr['desc']), dbesc($arr['desc']),
dbesc($arr['location']), dbesc($arr['location']),
dbesc($arr['type']), dbesc($arr['type']),

View file

@ -1457,11 +1457,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
* *
*/ */
$bdtext = t('Birthday:') . ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]' ; $bdtext = sprintf( t('%s\'s birthday'), $contact['name']);
$bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]' ) ;
$r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`) $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`)
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s' ) ", VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($contact['uid']), intval($contact['uid']),
intval($contact['id']), intval($contact['id']),
dbesc(datetime_convert()), dbesc(datetime_convert()),
@ -1469,6 +1470,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
dbesc(datetime_convert('UTC','UTC', $birthday)), dbesc(datetime_convert('UTC','UTC', $birthday)),
dbesc(datetime_convert('UTC','UTC', $birthday . ' + 1 day ')), dbesc(datetime_convert('UTC','UTC', $birthday . ' + 1 day ')),
dbesc($bdtext), dbesc($bdtext),
dbesc($bdtext2),
dbesc('birthday') dbesc('birthday')
); );
@ -2148,6 +2150,67 @@ function local_delivery($importer,$data) {
} }
if($deleted) { 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;
$r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,
`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`
LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')
AND `item`.`uid` = %d
$sql_extra
LIMIT 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` $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`
WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
dbesc($uri), dbesc($uri),
@ -2235,7 +2298,11 @@ function local_delivery($importer,$data) {
); );
} }
} }
} // 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']);
}
} }
} }
} }
@ -2268,6 +2335,7 @@ function local_delivery($importer,$data) {
$is_a_remote_comment = false; $is_a_remote_comment = 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`, $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,
`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` `contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`
LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
@ -3359,40 +3427,8 @@ function drop_item($id,$interactive = true) {
); );
} }
// Add a relayable_retraction signature for Diaspora. Note that we can't add a target_author_signature // Add a relayable_retraction signature for Diaspora.
// if the comment was deleted by a remote user. That should be ok, because if a remote user is deleting store_diaspora_retract_sig($item, $a->user, $a->get_baseurl());
// the comment, that means we're the home of the post, and Diaspora will only
// check the parent_author_signature of retractions that it doesn't have to relay further
//
// I don't think this function gets called for an "unlike," but I'll check anyway
$signed_text = $item['guid'] . ';' . ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
if(local_user() == $item['uid']) {
$handle = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
$authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha256'));
}
else {
$r = q("SELECT `nick`, `url` FROM `contact` WHERE `id` = '%d' LIMIT 1",
$item['contact-id']
);
if(count($r)) {
// The below handle only works for NETWORK_DFRN. I think that's ok, because this function
// only handles DFRN deletes
$handle_baseurl_start = strpos($r['url'],'://') + 3;
$handle_baseurl_length = strpos($r['url'],'/profile') - $handle_baseurl_start;
$handle = $r['nick'] . '@' . substr($r['url'], $handle_baseurl_start, $handle_baseurl_length);
$authorsig = '';
}
}
if(isset($handle))
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($item['id']),
dbesc($signed_text),
dbesc($authorsig),
dbesc($handle)
);
} }
$drop_id = intval($item['id']); $drop_id = intval($item['id']);
@ -3479,4 +3515,53 @@ function posted_date_widget($url,$uid,$wall) {
'$dates' => $ret '$dates' => $ret
)); ));
return $o; return $o;
} }
function store_diaspora_retract_sig($item, $user, $baseurl) {
// Note that we can't add a target_author_signature
// if the comment was deleted by a remote user. That should be ok, because if a remote user is deleting
// the comment, that means we're the home of the post, and Diaspora will only
// check the parent_author_signature of retractions that it doesn't have to relay further
//
// I don't think this function gets called for an "unlike," but I'll check anyway
$enabled = intval(get_config('system','diaspora_enabled'));
if(! $enabled) {
logger('drop_item: diaspora support disabled, not storing retraction signature', LOGGER_DEBUG);
return;
}
logger('drop_item: storing diaspora retraction signature');
$signed_text = $item['guid'] . ';' . ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
if(local_user() == $item['uid']) {
$handle = $user['nickname'] . '@' . substr($baseurl, strpos($baseurl,'://') + 3);
$authorsig = base64_encode(rsa_sign($signed_text,$user['prvkey'],'sha256'));
}
else {
$r = q("SELECT `nick`, `url` FROM `contact` WHERE `id` = '%d' LIMIT 1",
$item['contact-id']
);
if(count($r)) {
// The below handle only works for NETWORK_DFRN. I think that's ok, because this function
// only handles DFRN deletes
$handle_baseurl_start = strpos($r['url'],'://') + 3;
$handle_baseurl_length = strpos($r['url'],'/profile') - $handle_baseurl_start;
$handle = $r['nick'] . '@' . substr($r['url'], $handle_baseurl_start, $handle_baseurl_length);
$authorsig = '';
}
}
if(isset($handle))
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($item['id']),
dbesc($signed_text),
dbesc($authorsig),
dbesc($handle)
);
return;
}

View file

@ -125,7 +125,7 @@ function notifier_run($argv, $argc){
$uid = $r[0]['uid']; $uid = $r[0]['uid'];
$updated = $r[0]['edited']; $updated = $r[0]['edited'];
// The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up // POSSIBLE CLEANUP --> The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up
if(! $parent_id) if(! $parent_id)
return; return;

View file

@ -449,7 +449,7 @@ function onepoll_run($argv, $argc){
if($xml) { if($xml) {
logger('poller: received xml : ' . $xml, LOGGER_DATA); logger('poller: received xml : ' . $xml, LOGGER_DATA);
if((! strstr($xml,'<?xml')) && (! strstr($xml,'<rss'))) { if((! strstr($xml,'<?xml')) && (! strstr($xml,'<rss'))) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.'); logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1", $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()), dbesc(datetime_convert()),

View file

@ -380,20 +380,23 @@ function service_class_fetch($uid,$property) {
} }
function upgrade_link() { function upgrade_link($bbcode = false) {
$l = get_config('service_class','upgrade_link'); $l = get_config('service_class','upgrade_link');
$t = sprintf('<a href="%s">' . t('Click here to upgrade.') . '</div>', $l); if(! $l)
if($l) return '';
return $t; if($bbcode)
return ''; $t = sprintf('[url=%s]' . t('Click here to upgrade.') . '[/url]', $l);
else
$t = sprintf('<a href="%s">' . t('Click here to upgrade.') . '</div>', $l);
return $t;
} }
function upgrade_message() { function upgrade_message($bbcode = false) {
$x = upgrade_link(); $x = upgrade_link($bbcode);
return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ; return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ;
} }
function upgrade_bool_message() { function upgrade_bool_message($bbcode = false) {
$x = upgrade_link(); $x = upgrade_link($bbcode);
return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ; return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ;
} }

View file

@ -57,12 +57,13 @@ function events_post(&$a) {
if(strcmp($finish,$start) < 0) if(strcmp($finish,$start) < 0)
$finish = $start; $finish = $start;
$summary = escape_tags(trim($_POST['summary']));
$desc = escape_tags(trim($_POST['desc'])); $desc = escape_tags(trim($_POST['desc']));
$location = escape_tags(trim($_POST['location'])); $location = escape_tags(trim($_POST['location']));
$type = 'event'; $type = 'event';
if((! $desc) || (! $start)) { if((! $summary) || (! $start)) {
notice( t('Event description and start time are required.') . EOL); notice( t('Event title and start time are required.') . EOL);
goaway($a->get_baseurl() . '/events/new'); goaway($a->get_baseurl() . '/events/new');
} }
@ -107,6 +108,7 @@ function events_post(&$a) {
$datarray = array(); $datarray = array();
$datarray['start'] = $start; $datarray['start'] = $start;
$datarray['finish'] = $finish; $datarray['finish'] = $finish;
$datarray['summary'] = $summary;
$datarray['desc'] = $desc; $datarray['desc'] = $desc;
$datarray['location'] = $location; $datarray['location'] = $location;
$datarray['type'] = $type; $datarray['type'] = $type;
@ -278,9 +280,11 @@ function events_content(&$a) {
$last_date = $d; $last_date = $d;
$edit = ((! $rr['cid']) ? array($a->get_baseurl().'/events/event/'.$rr['id'],t('Edit event'),'','') : null); $edit = ((! $rr['cid']) ? array($a->get_baseurl().'/events/event/'.$rr['id'],t('Edit event'),'','') : null);
$title = strip_tags(bbcode($rr['summary']));
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2); if(! $title) {
$title = strip_tags($title); list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
$title = strip_tags($title);
}
$html = format_event_html($rr); $html = format_event_html($rr);
$rr['desc'] = bbcode($rr['desc']); $rr['desc'] = bbcode($rr['desc']);
$rr['location'] = bbcode($rr['location']); $rr['location'] = bbcode($rr['location']);
@ -351,6 +355,7 @@ function events_content(&$a) {
$n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : '');
$a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : '');
$t_orig = ((x($orig_event)) ? $orig_event['summary'] : '');
$d_orig = ((x($orig_event)) ? $orig_event['desc'] : ''); $d_orig = ((x($orig_event)) ? $orig_event['desc'] : '');
$l_orig = ((x($orig_event)) ? $orig_event['location'] : ''); $l_orig = ((x($orig_event)) ? $orig_event['location'] : '');
$eid = ((x($orig_event)) ? $orig_event['id'] : 0); $eid = ((x($orig_event)) ? $orig_event['id'] : 0);
@ -405,10 +410,11 @@ function events_content(&$a) {
'$eid' => $eid, '$eid' => $eid,
'$cid' => $cid, '$cid' => $cid,
'$uri' => $uri, '$uri' => $uri,
'$title' => t('Event details'), '$title' => t('Event details'),
'$desc' => sprintf( t('Format is %s %s. Starting date and Description are required.'),$dateformat,$timeformat), '$desc' => sprintf( t('Format is %s %s. Starting date and Title are required.'),$dateformat,$timeformat),
'$s_text' => t('Event Starts:') . ' <span class="required">*</span> ', '$s_text' => t('Event Starts:') . ' <span class="required" title="' . t('Required') . '">*</span>',
'$s_dsel' => datesel($f,'start',$syear+5,$syear,false,$syear,$smonth,$sday), '$s_dsel' => datesel($f,'start',$syear+5,$syear,false,$syear,$smonth,$sday),
'$s_tsel' => timesel('start',$shour,$sminute), '$s_tsel' => timesel('start',$shour,$sminute),
'$n_text' => t('Finish date/time is not known or not relevant'), '$n_text' => t('Finish date/time is not known or not relevant'),
@ -418,10 +424,12 @@ function events_content(&$a) {
'$f_tsel' => timesel('finish',$fhour,$fminute), '$f_tsel' => timesel('finish',$fhour,$fminute),
'$a_text' => t('Adjust for viewer timezone'), '$a_text' => t('Adjust for viewer timezone'),
'$a_checked' => $a_checked, '$a_checked' => $a_checked,
'$d_text' => t('Description:') . ' <span class="required">*</span>', '$d_text' => t('Description:'),
'$d_orig' => $d_orig, '$d_orig' => $d_orig,
'$l_text' => t('Location:'), '$l_text' => t('Location:'),
'$l_orig' => $l_orig, '$l_orig' => $l_orig,
'$t_text' => t('Title:') . ' <span class="required" title="' . t('Required') . '">*</span>',
'$t_orig' => $t_orig,
'$sh_text' => t('Share this event'), '$sh_text' => t('Share this event'),
'$sh_checked' => $sh_checked, '$sh_checked' => $sh_checked,
'$acl' => (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user),false)), '$acl' => (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user),false)),

View file

@ -108,7 +108,7 @@ function item_post(&$a) {
} }
} }
if($parent) logger('mod_post: parent=' . $parent); if($parent) logger('mod_item: item_post parent=' . $parent);
$profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); $profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0);
$post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0);
@ -728,26 +728,10 @@ function item_post(&$a) {
} }
// We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key
if($self) { // Store the comment signature information in case we need to relay to Diaspora
require_once('include/bb2diaspora.php'); store_diaspora_comment_sig($datarray, $author, ($self ? $a->user['prvkey'] : false), $parent_item, $post_id);
$signed_body = html_entity_decode(bb2diaspora($datarray['body']));
$myaddr = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
if($datarray['verb'] === ACTIVITY_LIKE)
$signed_text = $datarray['guid'] . ';' . 'Post' . ';' . $parent_item['guid'] . ';' . 'true' . ';' . $myaddr;
else
$signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $myaddr;
$authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha256'));
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($post_id),
dbesc($signed_text),
dbesc(base64_encode($authorsig)),
dbesc($myaddr)
);
}
} }
else { else {
$parent = $post_id; $parent = $post_id;
@ -1038,3 +1022,47 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
return array('replaced' => $replaced, 'contact' => $r[0]); return array('replaced' => $replaced, 'contact' => $r[0]);
} }
function store_diaspora_comment_sig($datarray, $author, $uprvkey, $parent_item, $post_id) {
// We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key
$enabled = intval(get_config('system','diaspora_enabled'));
if(! $enabled) {
logger('mod_item: diaspora support disabled, not storing comment signature', LOGGER_DEBUG);
return;
}
logger('mod_item: storing diaspora comment signature');
require_once('include/bb2diaspora.php');
$signed_body = html_entity_decode(bb2diaspora($datarray['body']));
// $myaddr = $user['nickname'] . '@' . substr($baseurl, strpos($baseurl,'://') + 3);
// if( $author['network'] === NETWORK_DIASPORA)
// $diaspora_handle = $author['addr'];
// else {
// Only works for NETWORK_DFRN
$contact_baseurl_start = strpos($author['url'],'://') + 3;
$contact_baseurl_length = strpos($author['url'],'/profile') - $contact_baseurl_start;
$contact_baseurl = substr($author['url'], $contact_baseurl_start, $contact_baseurl_length);
$diaspora_handle = $author['nick'] . '@' . $contact_baseurl;
// }
$signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $diaspora_handle;
if( $uprvkey !== false )
$authorsig = base64_encode(rsa_sign($signed_text,$uprvkey,'sha256'));
else
$authorsig = '';
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($post_id),
dbesc($signed_text),
dbesc(base64_encode($authorsig)),
dbesc($diaspora_handle)
);
return;
}

View file

@ -121,57 +121,16 @@ function like_content(&$a) {
intval($like_item['id']) intval($like_item['id'])
); );
// Clean up the `sign` table
// Clean up the Diaspora signatures for this like
// Go ahead and do it even if Diaspora support is disabled. We still want to clean up
// if it had been enabled in the past
$r = q("DELETE FROM `sign` WHERE `iid` = %d", $r = q("DELETE FROM `sign` WHERE `iid` = %d",
intval($like_item['id']) intval($like_item['id'])
); );
// Save the author information for the unlike in case we need to relay to Diaspora // Save the author information for the unlike in case we need to relay to Diaspora
// Note that we can only create a signature for a user of the local server. We don't have store_diaspora_like_retract_sig($activity, $item, $like_item, $contact);
// a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
// means we are the relay, and for relayable_retractions, Diaspora
// only checks the parent_author_signature if it doesn't have to relay further
//
// If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support
// likes on photos, so don't bother.
if(($activity === ACTIVITY_LIKE) && (! $item['resource-id'])) {
$signed_text = $like_item['guid'] . ';' . 'Like';
if( $contact['network'] === NETWORK_DIASPORA)
$diaspora_handle = $contact['addr'];
else { // Only works for NETWORK_DFRN
$contact_baseurl_start = strpos($contact['url'],'://') + 3;
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
// Get contact's private key if he's a user of the local Friendica server
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
dbesc($contact['url'])
);
if( $r) {
$contact_uid = $r['uid'];
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
intval($contact_uid)
);
if( $r)
$authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256'));
}
}
if(! isset($authorsig))
$authorsig = '';
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($like_item['id']),
dbesc($signed_text),
dbesc($authorsig),
dbesc($diaspora_handle)
);
}
// proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here! // proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here!
@ -252,35 +211,118 @@ EOT;
// Save the author information for the like in case we need to relay to Diaspora // Save the author information for the like in case we need to relay to Diaspora
store_diaspora_like_sig($activity, $post_type, $contact, $post_id);
$arr['id'] = $post_id;
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
killme();
// return; // NOTREACHED
}
function store_diaspora_like_retract_sig($activity, $item, $like_item, $contact) {
// Note that we can only create a signature for a user of the local server. We don't have
// a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
// means we are the relay, and for relayable_retractions, Diaspora
// only checks the parent_author_signature if it doesn't have to relay further
//
// If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support
// likes on photos, so don't bother.
$enabled = intval(get_config('system','diaspora_enabled'));
if(! $enabled) {
logger('mod_like: diaspora support disabled, not storing like retraction signature', LOGGER_DEBUG);
return;
}
logger('mod_like: storing diaspora like retraction signature');
if(($activity === ACTIVITY_LIKE) && (! $item['resource-id'])) {
$signed_text = $like_item['guid'] . ';' . 'Like';
// if( $contact['network'] === NETWORK_DIASPORA)
// $diaspora_handle = $contact['addr'];
// else {
// Only works for NETWORK_DFRN
$contact_baseurl_start = strpos($contact['url'],'://') + 3;
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
// Get contact's private key if he's a user of the local Friendica server
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
dbesc($contact['url'])
);
if( $r) {
$contact_uid = $r['uid'];
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
intval($contact_uid)
);
if( $r)
$authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256'));
}
// }
if(! isset($authorsig))
$authorsig = '';
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($like_item['id']),
dbesc($signed_text),
dbesc($authorsig),
dbesc($diaspora_handle)
);
}
return;
}
function store_diaspora_like_sig($activity, $post_type, $contact, $post_id) {
// Note that we can only create a signature for a user of the local server. We don't have // Note that we can only create a signature for a user of the local server. We don't have
// a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
// means we are the relay, and for relayable_retractions, Diaspora // means we are the relay, and for relayable_retractions, Diaspora
// only checks the parent_author_signature if it doesn't have to relay further // only checks the parent_author_signature if it doesn't have to relay further
if(($activity === ACTIVITY_LIKE) && ($post_type === t('status'))) { $enabled = intval(get_config('system','diaspora_enabled'));
if( $contact['network'] === NETWORK_DIASPORA) if(! $enabled) {
$diaspora_handle = $contact['addr']; logger('mod_like: diaspora support disabled, not storing like signature', LOGGER_DEBUG);
else { // Only works for NETWORK_DFRN return;
$contact_baseurl_start = strpos($contact['url'],'://') + 3; }
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
// Get contact's private key if he's a user of the local Friendica server logger('mod_like: storing diaspora like signature');
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
dbesc($contact['url']) if(($activity === ACTIVITY_LIKE) && ($post_type === t('status'))) {
// if( $contact['network'] === NETWORK_DIASPORA)
// $diaspora_handle = $contact['addr'];
// else {
// Only works for NETWORK_DFRN
$contact_baseurl_start = strpos($contact['url'],'://') + 3;
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
// Get contact's private key if he's a user of the local Friendica server
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
dbesc($contact['url'])
);
if( $r) {
$contact_uid = $r['uid'];
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
intval($contact_uid)
); );
if( $r) { if( $r)
$contact_uid = $r['uid']; $contact_uprvkey = $r['prvkey'];
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
intval($contact_uid)
);
if( $r)
$contact_uprvkey = $r['prvkey'];
}
} }
// }
$r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1", $r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1",
intval($post_id) intval($post_id)
@ -308,13 +350,5 @@ EOT;
} }
} }
return;
$arr['id'] = $post_id;
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
killme();
// return; // NOTREACHED
} }

View file

@ -60,6 +60,19 @@ function wall_attach_post(&$a) {
return; return;
} }
$r = q("select sum(octet_length(data)) as total from attach where uid = %d ",
intval($page_owner_uid)
);
$limit = service_class_fetch($page_owner_uid,'attach_upload_limit');
if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) {
echo upgrade_message(true) . EOL ;
@unlink($src);
killme();
}
$filedata = @file_get_contents($src); $filedata = @file_get_contents($src);
$mimetype = z_mime_content_type($filename); $mimetype = z_mime_content_type($filename);
$hash = random_string(); $hash = random_string();

View file

@ -79,6 +79,19 @@ function wall_upload_post(&$a) {
killme(); 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); $imagedata = @file_get_contents($src);
$ph = new Photo($imagedata, $filetype); $ph = new Photo($imagedata, $filetype);

View file

@ -1,6 +1,6 @@
<?php <?php
define( 'UPDATE_VERSION' , 1150 ); define( 'UPDATE_VERSION' , 1151 );
/** /**
* *
@ -1298,3 +1298,12 @@ function update_1149() {
return UPDATE_FAILED; return UPDATE_FAILED;
return UPDATE_SUCCESS; return UPDATE_SUCCESS;
} }
function update_1150() {
$r = q("ALTER TABLE event ADD summary text NOT NULL after finish, add index ( uid ), add index ( cid ), add index ( uri ), add index ( `start` ), add index ( finish ), add index ( `type` ), add index ( adjust ) ");
if(! $r)
return UPDATE_FAILED;
return UPDATE_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,10 @@ $f_dsel $f_tsel
<div id="event-adjust-break"></div> <div id="event-adjust-break"></div>
<div id="event-summary-text">$t_text</div>
<input type="text" id="event-summary" name="summary" value="$t_orig" />
<div id="event-desc-text">$d_text</div> <div id="event-desc-text">$d_text</div>
<textarea id="event-desc-textarea" name="desc">$d_orig</textarea> <textarea id="event-desc-textarea" name="desc">$d_orig</textarea>

View file

@ -70,7 +70,7 @@
<div style="display: none;"> <div style="display: none;">
<div id="profile-jot-acl-wrapper" style="width:auto;height:auto;overflow:auto;"> <div id="profile-jot-acl-wrapper" style="width:auto;height:auto;overflow:auto;">
$acl $acl
<hr style="clear:both"/> <hr style="clear:both;"/>
<div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle" /> <div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle" />
<div id="profile-jot-email-end"></div> <div id="profile-jot-email-end"></div>
$jotnets $jotnets

View file

@ -528,7 +528,7 @@ if ($color=="dark") $color_path = "/diabook-dark/";
$entry = replace_macros($tpl,array( $entry = replace_macros($tpl,array(
'$id' => $rr['id'], '$id' => $rr['id'],
'$profile-link' => $profile_link, '$profile-link' => $profile_link,
'$photo' => $rr[$photo], '$photo' => $a->get_cached_avatar_image($rr[$photo]),
'$alt-text' => $rr['name'], '$alt-text' => $rr['name'],
)); ));
$aside['$lastusers_items'][] = $entry; $aside['$lastusers_items'][] = $entry;

View file

@ -59,7 +59,7 @@ h6{font-size:xx-small;}
.button{color:#eeeecc;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;padding:5px;cursor:pointer;}.button a{color:#eeeecc;font-weight:bold;} .button{color:#eeeecc;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;padding:5px;cursor:pointer;}.button a{color:#eeeecc;font-weight:bold;}
#profile-listing-desc a{color:#eeeecc;font-weight:bold;} #profile-listing-desc a{color:#eeeecc;font-weight:bold;}
[class$="-desc"],[id$="-desc"]{color:#eeeecc;background:#2e2f2e;border:2px outset #d4d580;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;margin:3px 10px 7px 0;padding:5px;font-weight:bold;font-size:smaller;} [class$="-desc"],[id$="-desc"]{color:#eeeecc;background:#2e2f2e;border:2px outset #d4d580;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;margin:3px 10px 7px 0;padding:5px;font-weight:bold;font-size:smaller;}
#item-delete-selected-desc{float:left;margin-right:5px;}#item-delete-selected-desc:hover{text-decoration:underline;} #item-delete-selected-desc{float:left;font-size:smaller;margin-right:5px;}#item-delete-selected-desc:hover{text-decoration:underline;}
.intro-approve-as-friend-desc{margin-top:10px;} .intro-approve-as-friend-desc{margin-top:10px;}
.intro-desc{margin-bottom:20px;font-weight:bold;} .intro-desc{margin-bottom:20px;font-weight:bold;}
#group-edit-desc{margin:10px 0px;} #group-edit-desc{margin:10px 0px;}
@ -214,7 +214,7 @@ nav #nav-notifications-linkmenu.on .icon.s22.notify,nav #nav-notifications-linkm
.wall-item-subtools1{width:30px;height:30px;list-style:none outside none;margin:18px 0 30px -20px;padding:0;} .wall-item-subtools1{width:30px;height:30px;list-style:none outside none;margin:18px 0 30px -20px;padding:0;}
.wall-item-subtools2{width:25px;height:25px;list-style:none outside none;margin:-78px 0 0 5px;padding:0;} .wall-item-subtools2{width:25px;height:25px;list-style:none outside none;margin:-78px 0 0 5px;padding:0;}
.wall-item-title{font-size:1.2em;font-weight:bold;margin-bottom:1.4em;} .wall-item-title{font-size:1.2em;font-weight:bold;margin-bottom:1.4em;}
.wall-item-body{margin:15px 10px 10px 0px;text-align:left;overflow-x:auto;} .wall-item-body{margin:1em;text-align:left;overflow-x:auto;}
.wall-item-lock-wrapper{float:right;width:22px;height:22px;margin:0 -5px 0 0;opacity:1;} .wall-item-lock-wrapper{float:right;width:22px;height:22px;margin:0 -5px 0 0;opacity:1;}
.wall-item-dislike,.wall-item-like{clear:left;font-size:0.8em;color:#888b85;margin:5px 0 5px 10.2em;-webkit-transition:all 0.75s ease-in-out;-moz-transition:all 0.75s ease-in-out;-o-transition:all 0.75s ease-in-out;-ms-transition:all 0.75s ease-in-out;transition:all 0.75s ease-in-out;opacity:0.5;}.wall-item-dislike:hover,.wall-item-like:hover{opacity:1;} .wall-item-dislike,.wall-item-like{clear:left;font-size:0.8em;color:#888b85;margin:5px 0 5px 10.2em;-webkit-transition:all 0.75s ease-in-out;-moz-transition:all 0.75s ease-in-out;-o-transition:all 0.75s ease-in-out;-ms-transition:all 0.75s ease-in-out;transition:all 0.75s ease-in-out;opacity:0.5;}.wall-item-dislike:hover,.wall-item-like:hover{opacity:1;}
.wall-item-author,.wall-item-actions-author,.wall-item-ago{color:#eeeecc;line-height:1;display:inline-block;font-size:x-small;margin:0.5em auto;font-weight:bold;} .wall-item-author,.wall-item-actions-author,.wall-item-ago{color:#eeeecc;line-height:1;display:inline-block;font-size:x-small;margin:0.5em auto;font-weight:bold;}
@ -226,7 +226,6 @@ nav #nav-notifications-linkmenu.on .icon.s22.notify,nav #nav-notifications-linkm
.wallwall .wall-item-photo-end{clear:both;} .wallwall .wall-item-photo-end{clear:both;}
.wall-item-arrowphoto-wrapper{position:absolute;left:35px;top:80px;z-index:10002;} .wall-item-arrowphoto-wrapper{position:absolute;left:35px;top:80px;z-index:10002;}
.wall-item-photo-menu{min-width:92px;font-size:0.75em;border:2px solid #555753;border-top:0px;background:#555753;position:absolute;left:-2px;top:101px;display:none;z-index:10003;-o-border-radius:0 5px 5px 5px;-webkit-border-radius:0 5px 5px 5px;-moz-border-radius:0 5px 5px 5px;-ms-border-radius:0 5px 5px 5px;border-radius:0 5px 5px 5px;}.wall-item-photo-menu li a{white-space:nowrap;display:block;padding:5px 6px;color:#eeeeee;}.wall-item-photo-menu li a:hover{color:#555753;background:#eeeeee;} .wall-item-photo-menu{min-width:92px;font-size:0.75em;border:2px solid #555753;border-top:0px;background:#555753;position:absolute;left:-2px;top:101px;display:none;z-index:10003;-o-border-radius:0 5px 5px 5px;-webkit-border-radius:0 5px 5px 5px;-moz-border-radius:0 5px 5px 5px;-ms-border-radius:0 5px 5px 5px;border-radius:0 5px 5px 5px;}.wall-item-photo-menu li a{white-space:nowrap;display:block;padding:5px 6px;color:#eeeeee;}.wall-item-photo-menu li a:hover{color:#555753;background:#eeeeee;}
#item-delete-selected{overflow:auto;width:100%;}
#connect-services-header,#extra-help-header{margin:1.5em 0 0 0;} #connect-services-header,#extra-help-header{margin:1.5em 0 0 0;}
#connect-services,#extra-help{margin:0px;padding:0px;list-style:none;list-style-position:inside;margin:1em 0 0 0;}#connect-services li,#extra-help li{display:inline;} #connect-services,#extra-help{margin:0px;padding:0px;list-style:none;list-style-position:inside;margin:1em 0 0 0;}#connect-services li,#extra-help li{display:inline;}
.ccollapse-wrapper{font-size:0.9em;margin-left:5em;} .ccollapse-wrapper{font-size:0.9em;margin-left:5em;}
@ -390,10 +389,8 @@ div[id$="wrapper"]{height:100%;}div[id$="wrapper"] br{clear:left;}
.filesavetags:hover,.categorytags:hover{margin:20px 0;opacity:1.0 !important;} .filesavetags:hover,.categorytags:hover{margin:20px 0;opacity:1.0 !important;}
.item-select{opacity:0.1;margin:5px 0 0 6px !important;}.item-select:hover{opacity:1;} .item-select{opacity:0.1;margin:5px 0 0 6px !important;}.item-select:hover{opacity:1;}
.checkeditem{opacity:1;} .checkeditem{opacity:1;}
#item-delete-selected{margin-top:30px;} #item-delete-selected{margin-top:30px;position:absolute;left:35px;width:15em;overflow:auto;}
#item-delete-selected{position:absolute;left:35px;margin-top:20px;} #item-delete-selected-icon{float:left;margin:11px 5px;}
#item-delete-selected-icon{float:left;margin-right:5px;}
#item-delete-selected-desc{font-size:smaller;}
.fc-state-highlight{background:#eeeecc;color:#2e2f2e;} .fc-state-highlight{background:#eeeecc;color:#2e2f2e;}
.directory-item{float:left;margin:0 5px 4px 0;padding:3px;width:180px;height:250px;position:relative;} .directory-item{float:left;margin:0 5px 4px 0;padding:3px;width:180px;height:250px;position:relative;}
#group-sidebar{margin-bottom:10px;} #group-sidebar{margin-bottom:10px;}

View file

@ -325,6 +325,7 @@ h6 {
} }
#item-delete-selected-desc { #item-delete-selected-desc {
float: left; float: left;
font-size: smaller;
margin-right: 5px; margin-right: 5px;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
@ -1428,7 +1429,7 @@ nav #nav-notifications-linkmenu {
margin-bottom: 1.4em; margin-bottom: 1.4em;
} }
.wall-item-body { .wall-item-body {
margin: 15px 10px 10px 0px; margin: 1em;
text-align: left; text-align: left;
overflow-x: auto; overflow-x: auto;
} }
@ -1533,10 +1534,6 @@ nav #nav-notifications-linkmenu {
} }
} }
} }
#item-delete-selected {
overflow: auto;
width: 100%;
}
#connect-services-header, #connect-services-header,
#extra-help-header { #extra-help-header {
margin: 1.5em 0 0 0; margin: 1.5em 0 0 0;
@ -2370,20 +2367,14 @@ div {
} }
#item-delete-selected { #item-delete-selected {
margin-top: 30px; margin-top: 30px;
}
/* was tired of having no way of moving it around, so
* here's a little 'hook' to do so */
#item-delete-selected {
position: absolute; position: absolute;
left: 35px; left: 35px;
margin-top: 20px; width: 15em;
overflow: auto;
} }
#item-delete-selected-icon { #item-delete-selected-icon {
float: left; float: left;
margin-right: 5px; margin: 11px 5px;
}
#item-delete-selected-desc {
font-size: smaller;
} }
.fc-state-highlight { .fc-state-highlight {
background: @main_colour; background: @main_colour;

View file

@ -59,7 +59,7 @@ h6{font-size:xx-small;}
.button{color:#111111;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;padding:5px;cursor:pointer;}.button a{color:#111111;font-weight:bold;} .button{color:#111111;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;padding:5px;cursor:pointer;}.button a{color:#111111;font-weight:bold;}
#profile-listing-desc a{color:#eeeeec;font-weight:bold;} #profile-listing-desc a{color:#eeeeec;font-weight:bold;}
[class$="-desc"],[id$="-desc"]{color:#eeeeec;background:#2e3436;border:2px outset #111111;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;margin:3px 10px 7px 0;padding:5px;font-weight:bold;font-size:smaller;} [class$="-desc"],[id$="-desc"]{color:#eeeeec;background:#2e3436;border:2px outset #111111;-o-border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;border-radius:5px;margin:3px 10px 7px 0;padding:5px;font-weight:bold;font-size:smaller;}
#item-delete-selected-desc{float:left;margin-right:5px;}#item-delete-selected-desc:hover{text-decoration:underline;} #item-delete-selected-desc{float:left;font-size:smaller;margin-right:5px;}#item-delete-selected-desc:hover{text-decoration:underline;}
.intro-approve-as-friend-desc{margin-top:10px;} .intro-approve-as-friend-desc{margin-top:10px;}
.intro-desc{margin-bottom:20px;font-weight:bold;} .intro-desc{margin-bottom:20px;font-weight:bold;}
#group-edit-desc{margin:10px 0px;} #group-edit-desc{margin:10px 0px;}
@ -214,7 +214,7 @@ nav #nav-notifications-linkmenu.on .icon.s22.notify,nav #nav-notifications-linkm
.wall-item-subtools1{width:30px;height:30px;list-style:none outside none;margin:18px 0 30px -20px;padding:0;} .wall-item-subtools1{width:30px;height:30px;list-style:none outside none;margin:18px 0 30px -20px;padding:0;}
.wall-item-subtools2{width:25px;height:25px;list-style:none outside none;margin:-78px 0 0 5px;padding:0;} .wall-item-subtools2{width:25px;height:25px;list-style:none outside none;margin:-78px 0 0 5px;padding:0;}
.wall-item-title{font-size:1.2em;font-weight:bold;margin-bottom:1.4em;} .wall-item-title{font-size:1.2em;font-weight:bold;margin-bottom:1.4em;}
.wall-item-body{margin:15px 10px 10px 0px;text-align:left;overflow-x:auto;} .wall-item-body{margin:1em;text-align:left;overflow-x:auto;}
.wall-item-lock-wrapper{float:right;width:22px;height:22px;margin:0 -5px 0 0;opacity:1;} .wall-item-lock-wrapper{float:right;width:22px;height:22px;margin:0 -5px 0 0;opacity:1;}
.wall-item-dislike,.wall-item-like{clear:left;font-size:0.8em;color:#111111;margin:5px 0 5px 10.2em;-webkit-transition:all 0.75s ease-in-out;-moz-transition:all 0.75s ease-in-out;-o-transition:all 0.75s ease-in-out;-ms-transition:all 0.75s ease-in-out;transition:all 0.75s ease-in-out;opacity:0.5;}.wall-item-dislike:hover,.wall-item-like:hover{opacity:1;} .wall-item-dislike,.wall-item-like{clear:left;font-size:0.8em;color:#111111;margin:5px 0 5px 10.2em;-webkit-transition:all 0.75s ease-in-out;-moz-transition:all 0.75s ease-in-out;-o-transition:all 0.75s ease-in-out;-ms-transition:all 0.75s ease-in-out;transition:all 0.75s ease-in-out;opacity:0.5;}.wall-item-dislike:hover,.wall-item-like:hover{opacity:1;}
.wall-item-author,.wall-item-actions-author,.wall-item-ago{color:#111111;line-height:1;display:inline-block;font-size:x-small;margin:0.5em auto;font-weight:bold;} .wall-item-author,.wall-item-actions-author,.wall-item-ago{color:#111111;line-height:1;display:inline-block;font-size:x-small;margin:0.5em auto;font-weight:bold;}
@ -226,7 +226,6 @@ nav #nav-notifications-linkmenu.on .icon.s22.notify,nav #nav-notifications-linkm
.wallwall .wall-item-photo-end{clear:both;} .wallwall .wall-item-photo-end{clear:both;}
.wall-item-arrowphoto-wrapper{position:absolute;left:35px;top:80px;z-index:10002;} .wall-item-arrowphoto-wrapper{position:absolute;left:35px;top:80px;z-index:10002;}
.wall-item-photo-menu{min-width:92px;font-size:0.75em;border:2px solid #555753;border-top:0px;background:#555753;position:absolute;left:-2px;top:101px;display:none;z-index:10003;-o-border-radius:0 5px 5px 5px;-webkit-border-radius:0 5px 5px 5px;-moz-border-radius:0 5px 5px 5px;-ms-border-radius:0 5px 5px 5px;border-radius:0 5px 5px 5px;}.wall-item-photo-menu li a{white-space:nowrap;display:block;padding:5px 6px;color:#eeeeec;}.wall-item-photo-menu li a:hover{color:#555753;background:#eeeeec;} .wall-item-photo-menu{min-width:92px;font-size:0.75em;border:2px solid #555753;border-top:0px;background:#555753;position:absolute;left:-2px;top:101px;display:none;z-index:10003;-o-border-radius:0 5px 5px 5px;-webkit-border-radius:0 5px 5px 5px;-moz-border-radius:0 5px 5px 5px;-ms-border-radius:0 5px 5px 5px;border-radius:0 5px 5px 5px;}.wall-item-photo-menu li a{white-space:nowrap;display:block;padding:5px 6px;color:#eeeeec;}.wall-item-photo-menu li a:hover{color:#555753;background:#eeeeec;}
#item-delete-selected{overflow:auto;width:100%;}
#connect-services-header,#extra-help-header{margin:1.5em 0 0 0;} #connect-services-header,#extra-help-header{margin:1.5em 0 0 0;}
#connect-services,#extra-help{margin:0px;padding:0px;list-style:none;list-style-position:inside;margin:1em 0 0 0;}#connect-services li,#extra-help li{display:inline;} #connect-services,#extra-help{margin:0px;padding:0px;list-style:none;list-style-position:inside;margin:1em 0 0 0;}#connect-services li,#extra-help li{display:inline;}
.ccollapse-wrapper{font-size:0.9em;margin-left:5em;} .ccollapse-wrapper{font-size:0.9em;margin-left:5em;}
@ -390,10 +389,8 @@ div[id$="wrapper"]{height:100%;}div[id$="wrapper"] br{clear:left;}
.filesavetags:hover,.categorytags:hover{margin:20px 0;opacity:1.0 !important;} .filesavetags:hover,.categorytags:hover{margin:20px 0;opacity:1.0 !important;}
.item-select{opacity:0.1;margin:5px 0 0 6px !important;}.item-select:hover{opacity:1;} .item-select{opacity:0.1;margin:5px 0 0 6px !important;}.item-select:hover{opacity:1;}
.checkeditem{opacity:1;} .checkeditem{opacity:1;}
#item-delete-selected{margin-top:30px;} #item-delete-selected{margin-top:30px;position:absolute;left:35px;width:15em;overflow:auto;}
#item-delete-selected{position:absolute;left:35px;margin-top:20px;} #item-delete-selected-icon{float:left;margin:11px 5px;}
#item-delete-selected-icon{float:left;margin-right:5px;}
#item-delete-selected-desc{font-size:smaller;}
.fc-state-highlight{background:#eeeeec;color:#111111;} .fc-state-highlight{background:#eeeeec;color:#111111;}
.directory-item{float:left;margin:0 5px 4px 0;padding:3px;width:180px;height:250px;position:relative;} .directory-item{float:left;margin:0 5px 4px 0;padding:3px;width:180px;height:250px;position:relative;}
#group-sidebar{margin-bottom:10px;} #group-sidebar{margin-bottom:10px;}

View file

@ -326,6 +326,7 @@ h6 {
} }
#item-delete-selected-desc { #item-delete-selected-desc {
float: left; float: left;
font-size: smaller;
margin-right: 5px; margin-right: 5px;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
@ -1429,7 +1430,7 @@ nav #nav-notifications-linkmenu {
margin-bottom: 1.4em; margin-bottom: 1.4em;
} }
.wall-item-body { .wall-item-body {
margin: 15px 10px 10px 0px; margin: 1em;
text-align: left; text-align: left;
overflow-x: auto; overflow-x: auto;
} }
@ -1534,10 +1535,6 @@ nav #nav-notifications-linkmenu {
} }
} }
} }
#item-delete-selected {
overflow: auto;
width: 100%;
}
#connect-services-header, #connect-services-header,
#extra-help-header { #extra-help-header {
margin: 1.5em 0 0 0; margin: 1.5em 0 0 0;
@ -2371,20 +2368,14 @@ div {
} }
#item-delete-selected { #item-delete-selected {
margin-top: 30px; margin-top: 30px;
}
/* was tired of having no way of moving it around, so
* here's a little 'hook' to do so */
#item-delete-selected {
position: absolute; position: absolute;
left: 35px; left: 35px;
margin-top: 20px; width: 15em;
overflow: auto;
} }
#item-delete-selected-icon { #item-delete-selected-icon {
float: left; float: left;
margin-right: 5px; margin: 11px 5px;
}
#item-delete-selected-desc {
font-size: smaller;
} }
.fc-state-highlight { .fc-state-highlight {
background: @bg_colour; background: @bg_colour;

View file

@ -2421,9 +2421,40 @@ aside input[type='text'] {
font-size: 20px; font-size: 20px;
} }
#event-summary-text {
margin-top: 15px;
}
#event-share-checkbox {
float: left;
margin-top: 10px;
}
#event-share-text {
float: left;
margin-top: 10px;
margin-left: 5px;
}
#event-share-break {
clear: both;
margin-bottom: 10px;
}
#event-summary {
width: 400px;
}
.vevent { .vevent {
border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;
} }
.vevent .event-summary {
margin-left: 10px;
margin-right: 10px;
font-weight: bold;
}
.vevent .event-description, .vevent .event-location { .vevent .event-description, .vevent .event-location {
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;