]> git.mxchange.org Git - friendica.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorMichael Vogel <icarus@dabo.de>
Sun, 20 Jan 2013 13:07:57 +0000 (14:07 +0100)
committerMichael Vogel <icarus@dabo.de>
Sun, 20 Jan 2013 13:07:57 +0000 (14:07 +0100)
Conflicts:
boot.php
include/items.php
update.php

1  2 
boot.php
database.sql
include/bbcode.php
include/conversation.php
include/items.php
include/text.php
object/Item.php
update.php

diff --combined boot.php
index 6864e533d8872cc924020822cf8b57586c0b3a2c,015dfb55e8baa3e11ecfd9bcce4f803214511c42..cd7fa03b59cd6b338b07468e9c53929d0c3a2d93
+++ b/boot.php
@@@ -12,10 -12,10 +12,9 @@@ require_once('library/Mobile_Detect/Mob
  require_once('include/features.php');
  
  define ( 'FRIENDICA_PLATFORM',     'Friendica');
- define ( 'FRIENDICA_VERSION',      '3.1.1572' );
+ define ( 'FRIENDICA_VERSION',      '3.1.1589' );
  define ( 'DFRN_PROTOCOL_VERSION',  '2.23'    );
 -define ( 'DB_UPDATE_VERSION',      1158      );
 -
 +define ( 'DB_UPDATE_VERSION',      1159      );
  define ( 'EOL',                    "<br />\r\n"     );
  define ( 'ATOM_TIME',              'Y-m-d\TH:i:s\Z' );
  
@@@ -204,11 -204,10 +203,11 @@@ define ( 'NOTIFY_SYSTEM',   0x8000 )
  
  define ( 'TERM_UNKNOWN',   0 );
  define ( 'TERM_HASHTAG',   1 );
 -define ( 'TERM_MENTION',   2 );   
 +define ( 'TERM_MENTION',   2 );
  define ( 'TERM_CATEGORY',  3 );
  define ( 'TERM_PCATEGORY', 4 );
  define ( 'TERM_FILE',      5 );
 +define ( 'TERM_SAVEDSEARCH', 6 );
  
  define ( 'TERM_OBJ_POST',  1 );
  define ( 'TERM_OBJ_PHOTO', 2 );
@@@ -385,8 -384,14 +384,14 @@@ if(! class_exists('App')) 
                        'template_engine' => 'internal',
                );
  
-               public $smarty3_ldelim = '{{';
-               public $smarty3_rdelim = '}}';
+               private $ldelim = array(
+                       'internal' => '',
+                       'smarty3' => '{{'
+               );
+               private $rdelim = array(
+                       'internal' => '',
+                       'smarty3' => '}}'
+               );
  
                private $scheme;
                private $hostname;
                         */
                        if(!isset($this->page['htmlhead']))
                                $this->page['htmlhead'] = '';
-                       $tpl = get_markup_template('head.tpl');
  
                        // If we're using Smarty, then doing replace_macros() will replace
                        // any unrecognized variables with a blank string. Since we delay
                        // replacing $stylesheet until later, we need to replace it now
                        // with another variable name
                        if($this->theme['template_engine'] === 'smarty3')
-                               $stylesheet = $this->smarty3_ldelim . '$stylesheet' . $this->smarty3_rdelim;
+                               $stylesheet = $this->get_template_ldelim('smarty3') . '$stylesheet' . $this->get_template_rdelim('smarty3');
                        else
                                $stylesheet = '$stylesheet';
  
+                       $tpl = get_markup_template('head.tpl');
                        $this->page['htmlhead'] = replace_macros($tpl,array(
                                '$baseurl' => $this->get_baseurl(), // FIXME for z_path!!!!
                                '$local_user' => local_user(),
                        return $this->cached_profile_image[$avatar_image];
                }
  
+               function get_template_engine() {
+                       return $this->theme['template_engine'];
+               }
+               function set_template_engine($engine = 'internal') {
+                       $this->theme['template_engine'] = 'internal';
+                       switch($engine) {
+                               case 'smarty3':
+                                       if(is_writable('view/smarty3/'))
+                                               $this->theme['template_engine'] = 'smarty3';
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               function get_template_ldelim($engine = 'internal') {
+                       return $this->ldelim[$engine];
+               }
+               function get_template_rdelim($engine = 'internal') {
+                       return $this->rdelim[$engine];
+               }
  
        }
  }
@@@ -776,16 -806,12 +806,12 @@@ function is_ajax() 
  
  // Primarily involved with database upgrade, but also sets the
  // base url for use in cmdline programs which don't have
- // $_SERVER variables, and synchronising the state of installed plugins.
+ // $_SERVER variables
  
  
  if(! function_exists('check_config')) {
        function check_config(&$a) {
  
-               $build = get_config('system','build');
-               if(! x($build))
-                       $build = set_config('system','build',DB_UPDATE_VERSION);
                $url = get_config('system','url');
  
                // if the url isn't set or the stored url is radically different
                        $url = set_config('system','url',$a->get_baseurl());
  
  
+               $build = get_config('system','build');
+               if(! x($build))
+                       $build = set_config('system','build',DB_UPDATE_VERSION);
                if($build != DB_UPDATE_VERSION) {
                        $stored = intval($build);
                        $current = intval(DB_UPDATE_VERSION);
                                                                        '$error' => sprintf( t('Update %s failed. See error logs.'), $x)
                                                                ));
                                                                $subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
-                                                                       
+                                                               require_once('include/email.php');
+                                                               $subject = email_header_encode($subject,'UTF-8');       
                                                                mail($a->config['admin_email'], $subject, $email_msg,
-                                                                       'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
+                                                                       'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n"
                                                                        . 'Content-type: text/plain; charset=UTF-8' . "\n"
                                                                        . 'Content-transfer-encoding: 8bit' );
                                                                //try the logger
                        }
                }
  
+               return;
+       }
+ }
+ if(! function_exists('check_plugins')) {
+       function check_plugins(&$a) {
                /**
                 *
                 * Synchronise plugins:
@@@ -1108,6 -1147,10 +1147,10 @@@ if(! function_exists('get_max_import_si
   * Profile information is placed in the App structure for later retrieval.
   * Honours the owner's chosen theme for display.
   *
+  * IMPORTANT: Should only be run in the _init() functions of a module. That ensures that
+  * the theme is chosen before the _init() function of a theme is run, which will usually
+  * load a lot of theme-specific content
+  *
   */
  
  if(! function_exists('profile_load')) {
  
                if(! $r[0]['is-default']) {
                        $x = q("select `pub_keywords` from `profile` where uid = %d and `is-default` = 1 limit 1",
-                                       intval($profile_uid)
+                                       intval($r[0]['profile_uid'])
                        );
                        if($x && count($x))
                                $r[0]['pub_keywords'] = $x[0]['pub_keywords'];
  
                $a->profile = $r[0];
  
-               $a->profile['mobile-theme'] = get_pconfig($profile_uid, 'system', 'mobile_theme');
+               $a->profile['mobile-theme'] = get_pconfig($a->profile['profile_uid'], 'system', 'mobile_theme');
  
  
                $a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename'];
                 * load/reload current theme info
                 */
  
+               $a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
                $theme_info_file = "view/theme/".current_theme()."/theme.php";
                if (file_exists($theme_info_file)){
                        require_once($theme_info_file);
@@@ -1344,8 -1389,6 +1389,6 @@@ if(! function_exists('profile_sidebar')
                }
  
  
-               $tpl = get_markup_template('profile_vcard.tpl');
                $p = array();
                foreach($profile as $k => $v) {
                        $k = str_replace('-','_',$k);
                if($a->theme['template_engine'] === 'internal')
                        $location = template_escape($location);
  
+               $tpl = get_markup_template('profile_vcard.tpl');
                $o .= replace_macros($tpl, array(
                        '$profile' => $p,
                        '$connect'  => $connect,
@@@ -1612,7 -1656,7 +1656,7 @@@ if(! function_exists('current_theme')) 
  //            $mobile_detect = new Mobile_Detect();
  //            $is_mobile = $mobile_detect->isMobile() || $mobile_detect->isTablet();
                $is_mobile = $a->is_mobile || $a->is_tablet;
-       
                if($is_mobile) {
                        if(isset($_SESSION['show-mobile']) && !$_SESSION['show-mobile']) {
                                $system_theme = '';
@@@ -1947,16 -1991,9 +1991,9 @@@ function clear_cache($basepath = "", $p
  }
  
  function set_template_engine(&$a, $engine = 'internal') {
+ // This function is no longer necessary, but keep it as a wrapper to the class method
+ // to avoid breaking themes again unnecessarily
  
-       $a->theme['template_engine'] = 'internal';
-       if(is_writable('view/smarty3/')) {
-               switch($engine) {
-                       case 'smarty3':
-                               $a->theme['template_engine'] = 'smarty3';
-                               break;
-                       default:
-                               break;
-               }
-       }
+       $a->set_template_engine($engine);
  }
diff --combined database.sql
index 99d60429aeabf6737a0d8e99835ba9756d50089f,28a7c931e77b97f3360313b06f9209411480ca71..cf060ebf499ec43ae5894c8ed867ff83532e27b6
@@@ -241,6 -241,20 +241,20 @@@ CREATE TABLE IF NOT EXISTS `deliverq` 
  
  -- --------------------------------------------------------
  
+ --
+ -- Table structure for table `dsprphotoq`
+ --
+ CREATE TABLE `dsprphotoq` (
+   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+   `uid` int(11) NOT NULL,
+   `msg` mediumtext NOT NULL,
+   `attempt` tinyint(4) NOT NULL,
+   PRIMARY KEY (`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+ -- --------------------------------------------------------
  --
  -- Table structure for table `event`
  --
@@@ -546,7 -560,6 +560,7 @@@ CREATE TABLE IF NOT EXISTS `item` 
    `deleted` tinyint(1) NOT NULL DEFAULT '0',
    `origin` tinyint(1) NOT NULL DEFAULT '0',
    `forum_mode` tinyint(1) NOT NULL DEFAULT '0',
 +  `mention` tinyint(1) NOT NULL DEFAULT '0',
    `last-child` tinyint(1) unsigned NOT NULL DEFAULT '1',
    PRIMARY KEY (`id`),
    KEY `uri` (`uri`),
    KEY `uid_commented` (`uid`, `commented`),
    KEY `uid_created` (`uid`, `created`),
    KEY `uid_unseen` (`uid`, `unseen`),
 +  KEY `mention` (`mention`),
    FULLTEXT KEY `title` (`title`),
    FULLTEXT KEY `body` (`body`),
    FULLTEXT KEY `allow_cid` (`allow_cid`),
@@@ -1017,22 -1029,18 +1031,22 @@@ CREATE TABLE IF NOT EXISTS `spam` 
  --
  
  CREATE TABLE IF NOT EXISTS `term` (
 -  `tid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
 -  `oid` INT UNSIGNED NOT NULL ,
 -  `otype` TINYINT( 3 ) UNSIGNED NOT NULL ,
 -  `type` TINYINT( 3 ) UNSIGNED NOT NULL ,
 -  `term` CHAR( 255 ) NOT NULL ,
 -  `url` CHAR( 255 ) NOT NULL, 
 +  `tid` int(10) unsigned NOT NULL AUTO_INCREMENT,
 +  `aid` int(10) unsigned NOT NULL DEFAULT '0',
 +  `uid` int(10) unsigned NOT NULL DEFAULT '0',
 +  `oid` int(10) unsigned NOT NULL,
 +  `otype` tinyint(3) unsigned NOT NULL,
 +  `type` tinyint(3) unsigned NOT NULL,
 +  `term` char(255) NOT NULL,
 +  `url` char(255) NOT NULL,
    PRIMARY KEY (`tid`),
 -  KEY `oid` ( `oid` ),
 -  KEY `otype` ( `otype` ),
 -  KEY `type`  ( `type` ),
 -  KEY `term`  ( `term` )
 -) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 +  KEY `oid` (`oid`),
 +  KEY `otype` (`otype`),
 +  KEY `type` (`type`),
 +  KEY `term` (`term`),
 +  KEY `uid` (`uid`),
 +  KEY `aid` (`aid`)
 +) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  
  -- --------------------------------------------------------
  
@@@ -1124,17 -1132,3 +1138,17 @@@ CREATE TABLE IF NOT EXISTS `userd` 
    `username` char(255) NOT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Table structure for table `tag`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `tag` (
 +  `iid` int(11) NOT NULL,
 +  `tag` char(255) NOT NULL,
 +  `link` char(255) NOT NULL,
 +  PRIMARY KEY (`iid`, `tag`),
 +  KEY `tag` (`tag`)
 +) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --combined include/bbcode.php
index a7cfa079d1c38d3072a56a3a01fa62c15388d35c,228b75d5abbd711dc26afdfce0492ef300ddcfa9..613c2b7db06eec5787d51d893f7d57a66c144ad4
@@@ -254,12 -254,22 +254,22 @@@ function bb_ShareAttributes($match) 
          if ($matches[1] != "")
                  $profile = $matches[1];
  
+         $posted = "";
+         preg_match("/posted='(.*?)'/ism", $attributes, $matches);
+         if ($matches[1] != "")
+                 $posted = $matches[1];
+         preg_match('/posted="(.*?)"/ism', $attributes, $matches);
+         if ($matches[1] != "")
+                 $posted = $matches[1];
+               $reldate = (($posted) ? " " . relative_date($posted) : ''); 
          $headline = '<div class="shared_header">';
  
        if ($avatar != "")
                $headline .= '<img src="'.$avatar.'" height="32" width="32" >';
  
-       $headline .= sprintf(t('<span><a href="%s" target="external-link">%s</a> wrote the following <a href="%s" target="external-link">post</a>:</span>'), $profile, $author, $link);
+       $headline .= sprintf(t('<span><a href="%s" target="external-link">%s</a> wrote the following <a href="%s" target="external-link">post</a>'.$reldate.':</span>'), $profile, $author, $link);
  
          $headline .= "</div>";
  
@@@ -312,6 -322,9 +322,9 @@@ function bbcode($Text,$preserve_nl = fa
        $Text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","[share$1]$2[/share]",$Text);
        $Text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism","[quote$1]$2[/quote]",$Text);
  
+       $Text = preg_replace("/\n\[code\]/ism", "[code]", $Text);
+       $Text = preg_replace("/\[\/code\]\n/ism", "[/code]", $Text);
        // when the content is meant exporting to other systems then remove the avatar picture since this doesn't really look good on these systems
        if (!$tryoembed)
                $Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","\n[share$1$2]$3[/share]",$Text);
        $Text = str_replace("\r\n","\n", $Text);
  
        // removing multiplicated newlines
-       $search = array("\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]");
-       $replace = array("\n\n", "\n", "\n", "[/quote]\n", "[/quote]");
-       do {
-               $oldtext = $Text;
-               $Text = str_replace($search, $replace, $Text);
-       } while ($oldtext != $Text);
+ //    $search = array("\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]");
+ //    $replace = array("\n\n", "\n", "\n", "[/quote]\n", "[/quote]");
+ //    do {
+ //            $oldtext = $Text;
+ //            $Text = str_replace($search, $replace, $Text);
+ //    } while ($oldtext != $Text);
  
        $Text = str_replace(array("\r","\n"), array('<br />','<br />'), $Text);
  
  
        // Clean up the HTML by loading and saving the HTML with the DOM
        // Only do it when it has to be done - for performance reasons
 -      if (!$tryoembed) {
 +      // Update: Now it is done every time - since bad structured html can break a whole page
 +      //if (!$tryoembed) {
                $doc = new DOMDocument();
                $doc->preserveWhiteSpace = false;
  
                $Text = str_replace('<br></li>','</li>', $Text);
  
                $Text = mb_convert_encoding($Text, "UTF-8", 'HTML-ENTITIES');
 -      }
 +      //}
  
        call_hooks('bbcode',$Text);
  
diff --combined include/conversation.php
index 7c4e606a72e4b50b0f8b9f7b2854a68ae71ba833,e659ca04d93e44b8c006755cccc2142aa538721c..cc66d380b7561463670beca0c3e8203a729b41f6
@@@ -523,26 -523,7 +523,26 @@@ function conversation(&$a, $items, $mod
                                $tags=array();
                                $hashtags = array();
                                $mentions = array();
 -                              foreach(explode(',',$item['tag']) as $tag){
 +
 +                              $taglist = q("SELECT `type`, `term`, `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d) ORDER BY `tid`",
 +                                              intval(TERM_OBJ_POST), intval($item['id']), intval(TERM_HASHTAG), intval(TERM_MENTION));
 +
 +                              foreach($taglist as $tag) {
 +
 +                                      if ($tag["url"] == "")
 +                                              $tag["url"] = $searchpath.strtolower($tag["term"]);
 +
 +                                      if ($tag["type"] == TERM_HASHTAG) {
 +                                              $hashtags[] = "#<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +                                              $prefix = "#";
 +                                      } elseif ($tag["type"] == TERM_MENTION) {
 +                                              $mentions[] = "@<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +                                              $prefix = "@";
 +                                      }
 +                                      $tags[] = $prefix."<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +                              }
 +
 +                              /*foreach(explode(',',$item['tag']) as $tag){
                                        $tag = trim($tag);
                                        if ($tag!="") {
                                                $t = bbcode($tag);
                                                elseif($t[0] == '@')
                                                        $mentions[] = $t;
                                        }
 -                              }
 +                              }*/
  
                                $sp = false;
                                $profile_link = best_link_url($item,$sp);
@@@ -896,26 -877,21 +896,21 @@@ function format_like($cnt,$arr,$type,$i
        if($cnt == 1)
                $o .= (($type === 'like') ? sprintf( t('%s likes this.'), $arr[0]) : sprintf( t('%s doesn\'t like this.'), $arr[0])) . EOL ;
        else {
-               //$spanatts = 'class="fakelink" onclick="openClose(\'' . $type . 'list-' . $id . '\');"';
+               $spanatts = "class=\"fakelink\" onclick=\"openClose('{$type}list-$id');\"";
                switch($type) {
                        case 'like':
- //                            $phrase = sprintf( t('<span  %1$s>%2$d people</span> like this.'), $spanatts, $cnt);
-                               $mood = t('like this');
+                               $phrase = sprintf( t('<span  %1$s>%2$d people</span> like this'), $spanatts, $cnt);
                                break;
                        case 'dislike':
- //                            $phrase = sprintf( t('<span  %1$s>%2$d people</span> don\'t like this.'), $spanatts, $cnt);
-                               $mood = t('don\'t like this');
+                               $phrase = sprintf( t('<span  %1$s>%2$d people</span> don\'t like this'), $spanatts, $cnt);
                                break;
                }
-               $tpl = get_markup_template("voting_fakelink.tpl");
-               $phrase = replace_macros($tpl, array(
-                       '$vote_id' => $type . 'list-' . $id,
-                       '$count' => $cnt,
-                       '$people' => t('people'),
-                       '$vote_mood' => $mood
+               $phrase .= EOL ;
+               $o .= replace_macros(get_markup_template('voting_fakelink.tpl'), array(
+                       '$phrase' => $phrase,
+                       '$type' => $type,
+                       '$id' => $id
                ));
-               $o .= $phrase;
- //            $o .= EOL ;
  
                $total = count($arr);
                if($total >= MAX_LIKERS)
diff --combined include/items.php
index 377912684018a81a44ed50ee87c4add1f1cea981,08127c6eb68a127fc5d72cdfbe386191fad853db..54b392b3860f8c482adeadea6d67aa56df12c956
@@@ -5,8 -5,7 +5,9 @@@ require_once('include/oembed.php')
  require_once('include/salmon.php');
  require_once('include/crypto.php');
  require_once('include/Photo.php');
 +require_once('include/tags.php');
 +require_once('include/text.php');
+ require_once('include/email.php');
  
  function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) {
  
@@@ -27,7 -26,7 +28,7 @@@
                }
        }
  
 -      
 +
  
        // default permissions - anonymous user
  
@@@ -239,7 -238,7 +240,7 @@@ function construct_activity_object($ite
                                        $r->link = str_replace('&','&amp;', $r->link);
                                $r->link = preg_replace('/\<link(.*?)\"\>/','<link$1"/>',$r->link);
                                $o .= $r->link;
 -                      }                                       
 +                      }
                        else
                                $o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n";
                }
@@@ -271,7 -270,7 +272,7 @@@ function construct_activity_target($ite
                                        $r->link = str_replace('&','&amp;', $r->link);
                                $r->link = preg_replace('/\<link(.*?)\"\>/','<link$1"/>',$r->link);
                                $o .= $r->link;
 -                      }                                       
 +                      }
                        else
                                $o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n";
                }
@@@ -671,7 -670,7 +672,7 @@@ function get_atom_elements($feed,$item
        }
  
        // translate OStatus unfollow to activity streams if it happened to get selected
 -              
 +
        if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow'))
                $res['verb'] = ACTIVITY_UNFOLLOW;
  
                if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
                        $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'];
                        $res['object'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
 -              }       
 +              }
                if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
                        $res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
                if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
                $child = $rawobj[0]['child'];
                if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
                        $res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
 -              }       
 +              }
                if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
                        $res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
                if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
@@@ -883,7 -882,7 +884,7 @@@ function item_store($arr,$force_parent 
                $arr['gravity'] = 0;
        elseif(activity_match($arr['verb'],ACTIVITY_POST))
                $arr['gravity'] = 6;
 -      else      
 +      else
                $arr['gravity'] = 6;   // extensible catchall
  
        if(! x($arr,'type'))
                require_once('library/langdet/Text/LanguageDetect.php');
                $naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']);
                $l = new Text_LanguageDetect;
 -              $lng = $l->detectConfidence($naked_body);
 -              $arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
 +              //$lng = $l->detectConfidence($naked_body);
 +              //$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
 +              $lng = $l->detect($naked_body, 3);
 +
 +              if (sizeof($lng) > 0) {
 +                      $postopts = "";
 +
 +                      foreach ($lng as $language => $score) {
 +                              if ($postopts == "")
 +                                      $postopts = "lang=";
 +                              else
 +                                      $postopts .= ":";
 +
 +                              $postopts .= $language.";".$score;
 +                      }
 +                      $arr['postopts'] = $postopts;
 +              }
        }
  
        $arr['wall']          = ((x($arr,'wall'))          ? intval($arr['wall'])                : 0);
                                logger('item_store: item parent was not found - ignoring item');
                                return 0;
                        }
 -                      
 +
                        $parent_deleted = 0;
                }
        }
        if(count($r)) {
                $current_post = $r[0]['id'];
                logger('item_store: created item ' . $current_post);
 -      }
 -      else {
 +              create_tags_from_item($r[0]['id']);
 +      else {
                logger('item_store: could not locate created item');
                return 0;
        }
                );
        }
  
 -      if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))      
 +      if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
                $parent_id = $current_post;
  
        if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
                intval($parent_deleted),
                intval($current_post)
        );
 +      create_tags_from_item($current_post);
  
          $arr['id'] = $current_post;
          $arr['parent'] = $parent_id;
  
        tag_deliver($arr['uid'],$current_post);
  
 +      // Store the fresh generated item into the cache
 +      $cachefile = get_cachefile($arr["guid"]."-".hash("md5", $arr['body']));
 +
 +      if (($cachefile != '') AND !file_exists($cachefile)) {
 +              $s = prepare_text($arr['body']);
 +              file_put_contents($cachefile, $s);
 +              logger('item_store: put item '.$current_post.' into cachefile '.$cachefile);
 +      }
 +
        return $current_post;
  }
  
@@@ -1298,7 -1272,7 +1299,7 @@@ function tag_deliver($uid,$item_id) 
                intval($item_id)
        );
  
 -      proc_run('php','include/notifier.php','tgroup',$item_id);                       
 +      proc_run('php','include/notifier.php','tgroup',$item_id);
  
  }
  
@@@ -1369,7 -1343,7 +1370,7 @@@ function dfrn_deliver($owner,$contact,$
        if($contact['duplex'] && $contact['dfrn-id'])
                $idtosend = '0:' . $orig_id;
        if($contact['duplex'] && $contact['issued-id'])
 -              $idtosend = '1:' . $orig_id;            
 +              $idtosend = '1:' . $orig_id;
  
        $rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0);
  
                        break;
                case SSL_POLICY_SELFSIGN:
                        $ssl_policy = 'self';
 -                      break;                  
 +                      break;
                case SSL_POLICY_NONE:
                default:
                        $ssl_policy = 'none';
                                intval(($perm == 'rw') ? 1 : 0),
                                intval($contact['id'])
                        );
 -                      $contact['writable'] = (string) 1 - intval($contact['writable']);                       
 +                      $contact['writable'] = (string) 1 - intval($contact['writable']);
                }
        }
  
@@@ -1584,7 -1558,7 +1585,7 @@@ function consume_feed($xml,$importer,&$
                logger('consume_feed: empty input');
                return;
        }
 -              
 +
        $feed = new SimplePie();
        $feed->set_raw_data($xml);
        if($datedir)
                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'];
                                        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);
  
  
                        $a = get_app();
  
 -                      q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'  
 +                      q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
                                WHERE `uid` = %d AND `id` = %d LIMIT 1",
                                dbesc(datetime_convert()),
                                dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()),
                         * to contain a sparkle link and perhaps a photo. 
                         *
                         */
 -                       
 +
                        $bdtext = sprintf( t('%s\'s birthday'), $contact['name']);
                        $bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]' ) ;
  
                                dbesc($bdtext2),
                                dbesc('birthday')
                        );
 -                      
 +
  
                        // update bdyear
  
                                                                                dbesc(implode(',',$newtags)),
                                                                                intval($i[0]['id'])
                                                                        );
 +                                                                      create_tags_from_item($i[0]['id']);
                                                                }
                                                        }
                                                }
                                                        dbesc($item['uri']),
                                                        intval($importer['uid'])
                                                );
 +                                              create_tags_from_itemuri($item['uri'], $importer['uid']);
                                        }
                                        else {
                                                $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
                                                        dbesc($uri),
                                                        intval($importer['uid'])
                                                );
 +                                              create_tags_from_itemuri($uri, $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($item_id),
                                                        intval($importer['uid'])
                                                );
 +                                              create_tags_from_itemuri($item_id, $importer['uid']);
                                        }
  
                                        // update last-child if it changes
                                                dbesc($parent_uri)
                                        );
                                        if($r && count($r))
 -                                              continue; 
 +                                              continue;
                                }
  
                                if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
                                                                        dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag),
                                                                        intval($r[0]['id'])
                                                                );
 +                                                              create_tags_from_item($r[0]['id']);
                                                        }
                                                }
                                        }
                                                        dbesc($item_id),
                                                        intval($importer['uid'])
                                                );
 +                                              create_tags_from_itemuri($item_id, $importer['uid']);
                                        }
  
                                        // update last-child if it changes
@@@ -2263,7 -2231,7 +2264,7 @@@ function local_delivery($importer,$data
                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'];
                                        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);
  
  
                        $a = get_app();
  
 -                      q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'  
 +                      q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
                                WHERE `uid` = %d AND `id` = %d LIMIT 1",
                                dbesc(datetime_convert()),
                                dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()),
                /** 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) 
 +              if ($r === false)
                        return 1;
          $old = $r[0];
 -        
 +
          $x = q("UPDATE contact SET
                          name = '%s',
                          photo = '%s',
                        if ($x === false)
                                return 1;
                }
 -              
 +
                // TODO
                // merge with current record, current contents have priority
                // update record, set url-updated
  
  
                $hash = random_string();
 - 
 +
                $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )
                        VALUES( %d, %d, %d, '%s', '%s', '%s', %d )",
                        intval($fsugg['uid']),
                $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)) 
                        'verb' => ACTIVITY_POST,
                        'otype' => 'mail'
                );
 -                      
 +
                notification($notif_params);
                return 0;
  
                // NOTREACHED
 -      }       
 +      }
  
        $community_page = 0;
        $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community');
                );
                $importer['forum'] = (string) $community_page;
        }
 -      
 +
        logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
  
        // process any deleted entries
                                                        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); 
 +                                                              $author_copy = (($item['origin']) ? true : false);
  
                                                                if($owner_remove && $author_copy)
                                                                        continue;
 -                                                              if($author_remove || $owner_remove) {                                                           
 +                                                              if($author_remove || $owner_remove) {
                                                                        $tags = explode(',',$i[0]['tag']);
                                                                        $newtags = array();
                                                                        if(count($tags)) {
                                                                                dbesc(implode(',',$newtags)),
                                                                                intval($i[0]['id'])
                                                                        );
 +                                                                      create_tags_from_item($i[0]['id']);
                                                                }
                                                        }
                                                }
                                                        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',
                                                        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($item['parent-uri']),
                                                                intval($item['uid'])
                                                        );
 -                                                      // who is the last child now? 
 +                                                      // 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
                                                                ORDER BY `created` DESC LIMIT 1",
                                                                        dbesc($item['parent-uri']),
                                                                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(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($item_id),
                                                        intval($importer['importer_uid'])
                                                );
 +                                              create_tags_from_itemuri($item_id, $importer['importer_uid']);
  
                                                proc_run('php',"include/notifier.php","comment-import",$iid);
  
                                                dbesc($datarray['verb']),
                                                dbesc($datarray['parent-uri']),
                                                dbesc($datarray['parent-uri'])
 -              
 +
                                        );
                                        if($r && count($r))
 -                                              continue; 
 +                                              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);
  
                                                        intval($importer['importer_uid'])
                                                );
                                                if(! count($tagp))
 -                                                      continue;       
 +                                                      continue;
  
 -                                              // extract tag, if not duplicate, and this user allows tags, add to parent item                                         
 +                                              // 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]';
                                                                                intval($tagp[0]['id']),
                                                                                dbesc(datetime_convert())
                                                                        );
 +                                                                      create_tags_from_item($tagp[0]['id']);
                                                                }
                                                        }
 -                                              }                                                                                                       
 +                                              }
                                        }
                                }
  
                                                $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()),
                                        if($posted_id && $parent) {
  
                                                proc_run('php',"include/notifier.php","comment-import","$posted_id");
 -                                      
 +
                                                if((! $is_like) && (! $importer['self'])) {
  
                                                        require_once('include/enotify.php');
                                                        dbesc($item_id),
                                                        intval($importer['importer_uid'])
                                                );
 +                                              create_tags_from_itemuri($item_id, $importer['importer_uid']);
                                        }
  
                                        // update last-child if it changes
                                                dbesc($parent_uri)
                                        );
                                        if($r && count($r))
 -                                              continue; 
 +                                              continue;
  
                                }
  
                                                        intval($importer['importer_uid'])
                                                );
                                                if(! count($r))
 -                                                      continue;                               
 +                                                      continue;
  
 -                                              // extract tag, if not duplicate, add to parent item                                            
 +                                              // 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",
                                                // 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;
  
                                                dbesc($item_id),
                                                intval($importer['importer_uid'])
                                        );
 +                                      create_tags_from_itemuri($item_id, $importer['importer_uid']);
                                }
  
                                // update last-child if it changes
@@@ -3354,7 -3314,7 +3355,7 @@@ function new_follower($importer,$contac
                // send email notification to owner?
        }
        else {
 -      
 +
                // create contact record
  
                $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`, 
                if(count($r))
                                $contact_record = $r[0];
  
 -              // create notification  
 +              // create notification
                $hash = random_string();
  
                if(is_array($contact_record)) {
                                        '$sitename' => $a->config['sitename']
                                ));
                                $res = mail($r[0]['email'], 
-                                       (($sharing) ? t('A new person is sharing with you at ') : t("You have a new follower at ")) . $a->config['sitename'],
+                                       email_header_encode((($sharing) ? t('A new person is sharing with you at ') : t("You have a new follower at ")) . $a->config['sitename'],'UTF-8'),
                                        $email,
-                                       'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
+                                       'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n"
                                        . 'Content-type: text/plain; charset=UTF-8' . "\n"
                                        . 'Content-transfer-encoding: 8bit' );
 -                      
 +
                        }
                }
        }
@@@ -3485,7 -3445,7 +3486,7 @@@ function subscribe_to_hub($url,$importe
        post_url($url,$params);
  
        logger('subscribe_to_hub: returns: ' . $a->get_curl_code(), LOGGER_DEBUG);
 -                      
 +
        return;
  
  }
@@@ -3772,11 -3732,11 +3773,11 @@@ function item_getfeedtags($item) 
  
  function item_getfeedattach($item) {
        $ret = '';
-       $arr = explode(',',$item['attach']);
+       $arr = explode('[/attach],',$item['attach']);
        if(count($arr)) {
                foreach($arr as $r) {
                        $matches = false;
-                       $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches);
+                       $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches);
                        if($cnt) {
                                $ret .= '<link rel="enclosure" href="' . xmlify($matches[1]) . '" type="' . xmlify($matches[3]) . '" ';
                                if(intval($matches[2]))
@@@ -3818,16 -3778,16 +3819,16 @@@ function item_expire($uid,$days) 
  
        $expire_items = get_pconfig($uid, 'expire','items');
        $expire_items = (($expire_items===false)?1:intval($expire_items)); // default if not set: 1
 -      
 +
        $expire_notes = get_pconfig($uid, 'expire','notes');
        $expire_notes = (($expire_notes===false)?1:intval($expire_notes)); // default if not set: 1
  
        $expire_starred = get_pconfig($uid, 'expire','starred');
        $expire_starred = (($expire_starred===false)?1:intval($expire_starred)); // default if not set: 1
 -      
 +
        $expire_photos = get_pconfig($uid, 'expire','photos');
        $expire_photos = (($expire_photos===false)?0:intval($expire_photos)); // default if not set: 0
 - 
 +
        logger('expire: # items=' . count($r). "; expire items: $expire_items, expire notes: $expire_notes, expire starred: $expire_starred, expire photos: $expire_photos");
  
        foreach($r as $item) {
@@@ -3922,7 -3882,6 +3923,7 @@@ function drop_item($id,$interactive = t
                        dbesc(datetime_convert()),
                        intval($item['id'])
                );
 +              create_tags_from_item($item['id']);
  
                // clean up categories and tags so they don't end up as orphans
  
                                dbesc($item['parent-uri']),
                                intval($item['uid'])
                        );
 +                      create_tags_from_item($item['parent-uri'], $item['uid']);
                        // ignore the result
                }
                else {
                                dbesc($item['parent-uri']),
                                intval($item['uid'])
                        );
 -                      // who is the last child now? 
 +                      // 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 ORDER BY `edited` DESC LIMIT 1",
                                dbesc($item['parent-uri']),
                                intval($item['uid'])
                goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
                //NOTREACHED
        }
 -      
 +
  }
  
  
diff --combined include/text.php
index 54c9f39fa6a8e50f1be98594c88aa9bbd4b47849,d1fff85ea358f7cc866976063eefd3d09047e860..53dd06d1fd8e71e095c2f02f9a2a5e6a7e44ab86
@@@ -23,7 -23,6 +23,6 @@@ function replace_macros($s,$r) 
                if(gettype($s) === 'string') {
                        $template = $s;
                        $s = new FriendicaSmarty();
-                       $s->error_reporting = E_ALL & ~E_NOTICE;
                }
                foreach($r as $key=>$value) {
                        if($key[0] === '$') {
@@@ -490,12 -489,12 +489,12 @@@ function get_template_file($a, $filenam
        if($root !== '' && $root[strlen($root)-1] !== '/')
                $root = $root . '/';
  
-       if(file_exists($root . "view/theme/$theme/$filename"))
-               $template_file = $root . "view/theme/$theme/$filename";
-       elseif (x($a->theme_info,"extends") && file_exists($root . "view/theme/".$a->theme_info["extends"]."/$filename"))
-               $template_file = $root . "view/theme/".$a->theme_info["extends"]."/$filename";
+       if(file_exists("{$root}view/theme/$theme/$filename"))
+               $template_file = "{$root}view/theme/$theme/$filename";
+       elseif (x($a->theme_info,"extends") && file_exists("{$root}view/theme/{$a->theme_info["extends"]}/$filename"))
+               $template_file = "{$root}view/theme/{$a->theme_info["extends"]}/$filename";
        else
-               $template_file = $root . "view/$filename";
+               $template_file = "{$root}view/$filename";
  
        return $template_file;
  }}
@@@ -562,12 -561,11 +561,12 @@@ function get_tags($s) 
        $ret = array();
  
        // ignore anything in a code block
 -
        $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
  
 -      // ignore anything in a bbtag
 +      // Force line feeds at bbtags
 +      $s = str_replace(array("[", "]"), array("\n[", "]\n"), $s);
  
 +      // ignore anything in a bbtag
        $s = preg_replace('/\[(.*?)\]/sm','',$s);
  
        // Match full names against @tags including the space between first and last
@@@ -1019,8 -1017,7 +1018,8 @@@ function prepare_body($item,$attach = f
        $a = get_app();
        call_hooks('prepare_body_init', $item);
  
 -      $cachefile = get_cachefile($item["guid"]."-".strtotime($item["edited"])."-".hash("crc32", $item['body']));
 +      //$cachefile = get_cachefile($item["guid"]."-".strtotime($item["edited"])."-".hash("crc32", $item['body']));
 +      $cachefile = get_cachefile($item["guid"]."-".hash("md5", $item['body']));
  
        if (($cachefile != '')) {
                if (file_exists($cachefile))
                else {
                        $s = prepare_text($item['body']);
                        file_put_contents($cachefile, $s);
 +                      logger('prepare_body: put item '.$item["id"].' into cachefile '.$cachefile);
                }
        } else
                $s = prepare_text($item['body']);
                return $s;
        }
  
-       $arr = explode(',',$item['attach']);
+       $arr = explode('[/attach],',$item['attach']);
        if(count($arr)) {
                $s .= '<div class="body-attach">';
                foreach($arr as $r) {
                        $matches = false;
                        $icon = '';
-                       $cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches, PREG_SET_ORDER);
+                       $cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches, PREG_SET_ORDER);
                        if($cnt) {
                                foreach($matches as $mtch) {
                                        $icontype = strtolower(substr($mtch[3],0,strpos($mtch[3],'/')));
diff --combined object/Item.php
index de28da464239e37b61bbbab816f80209cd9842af,9c06fc8cf7b341efb7374dde80a8c4ddcc08de52..18281e9bcba1379a2c58e98ae729dbdf68aa56b6
@@@ -66,6 -66,7 +66,7 @@@ class Item extends BaseObject 
                                if(! visible_activity($item)) {
                                        continue;
                                }
+                               $item['pagedrop'] = $data['pagedrop'];
                                $child = new Item($item);
                                $this->add_child($child);
                        }
                call_hooks('render_location',$locate);
                $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_google($locate));
  
 +              $searchpath = $a->get_baseurl()."/search?tag=";
                $tags=array();
                $hashtags = array();
                $mentions = array();
 -              foreach(explode(',',$item['tag']) as $tag){
 +
 +              $taglist = q("SELECT `type`, `term`, `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d) ORDER BY `tid`",
 +                              intval(TERM_OBJ_POST), intval($item['id']), intval(TERM_HASHTAG), intval(TERM_MENTION));
 +
 +              foreach($taglist as $tag) {
 +
 +                      if ($tag["url"] == "")
 +                              $tag["url"] = $searchpath.strtolower($tag["term"]);
 +
 +                      if ($tag["type"] == TERM_HASHTAG) {
 +                              $hashtags[] = "#<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +                              $prefix = "#";
 +                      } elseif ($tag["type"] == TERM_MENTION) {
 +                              $mentions[] = "@<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +                              $prefix = "@";
 +                      }
 +                      $tags[] = $prefix."<a href=\"".$tag["url"]."\" target=\"external-link\">".$tag["term"]."</a>";
 +              }
 +
 +              /*foreach(explode(',',$item['tag']) as $tag){
                        $tag = trim($tag);
                        if ($tag!="") {
                                $t = bbcode($tag);
                                elseif($t[0] == '@')
                                        $mentions[] = $t;
                        }
 -
 -              }        
 +              }*/
  
                $like    = ((x($alike,$item['uri'])) ? format_like($alike[$item['uri']],$alike[$item['uri'] . '-l'],'like',$item['uri']) : '');
                $dislike = ((x($dlike,$item['uri'])) ? format_like($dlike[$item['uri']],$dlike[$item['uri'] . '-l'],'dislike',$item['uri']) : '');
                localize_item($item);
  
                if ($item["postopts"]) {
 -                      $langdata = explode(";", $item["postopts"]);
 -                      $langstr = substr($langdata[0], 5)." (".round($langdata[1]*100, 1)."%)";
 +                      //$langdata = explode(";", $item["postopts"]);
 +                      //$langstr = substr($langdata[0], 5)." (".round($langdata[1]*100, 1)."%)";
 +                      $langstr = "";
 +                      if (substr($item["postopts"], 0, 5) == "lang=") {
 +                              $postopts = substr($item["postopts"], 5);
 +
 +                              $languages = explode(":", $postopts);
 +
 +                              if (sizeof($languages) == 1) {
 +                                      $languages = array();
 +                                      $languages[] = $postopts;
 +                              }
 +
 +                              foreach ($languages as $language) {
 +                                      $langdata = explode(";", $language);
 +                                      if ($langstr != "")
 +                                              $langstr .= ", ";
 +
 +                                      //$langstr .= $langdata[0]." (".round($langdata[1]*100, 1)."%)";
 +                                      $langstr .= round($langdata[1]*100, 1)."% ".$langdata[0];
 +                              }
 +                      }
                }
  
                $body = prepare_body($item,true);
                        'has_cats' => ((count($categories)) ? 'true' : ''),
                        'has_folders' => ((count($folders)) ? 'true' : ''),
              'categories' => $categories,
 -            'folders' => $folders,            
 +            'folders' => $folders,
                        'body' => $body_e,
                        'text' => $text_e,
                        'id' => $this->get_id(),
                        return false;
                }
  
-               if($a->theme['template_engine'] === 'smarty3') {
-                       $template_file = get_template_file($a, 'smarty3/' . $this->available_templates[$name]);
-               }
-               else {
-                       $template_file = $this->available_templates[$name];
-               }
-               $this->template = $template_file;
+               $this->template = $this->available_templates[$name];
        }
  
        /**
diff --combined update.php
index 4bee3a3bc1bb05ef5167b2e986c82d46c7b9156c,1bea71f4d7ded1d63e7692200439115f88d709a0..2ab2f300c04a3be538d50dc5abe3ee175e29fd88
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  
 -define( 'UPDATE_VERSION' , 1158 );
 +define( 'UPDATE_VERSION' , 1159 );
  
  /**
   *
@@@ -1371,17 -1371,18 +1371,44 @@@ ADD INDEX ( `datasize` ) ")
  }
  
  function update_1157() {
++<<<<<<< HEAD
 +      $r = q("ALTER TABLE `term` ADD `aid` int(10) unsigned NOT NULL DEFAULT '0',
 +              ADD `uid` int(10) unsigned NOT NULL DEFAULT '0',
 +              ADD INDEX (`uid`),
 +              ADD INDEX (`aid`)");
 +
 +      if(!$r) return UPDATE_FAILED;
 +      return UPDATE_SUCCESS;
 +}
 +function update_1158() {
+       $r = q("CREATE TABLE  IF NOT EXISTS `dsprphotoq` (
+         `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+         `uid` int(11) NOT NULL,
+         `msg` mediumtext NOT NULL,
+         `attempt` tinyint(4) NOT NULL,
+         PRIMARY KEY (`id`)
+         ) ENGINE=MyISAM DEFAULT CHARSET=utf8"
+       );
+       if($r)
+               return UPDATE_SUCCESS;
+       return UPDATE_FAILED;
+ }
++function update_1159() {
++      $r = q("ALTER TABLE `term` ADD `aid` int(10) unsigned NOT NULL DEFAULT '0',
++              ADD `uid` int(10) unsigned NOT NULL DEFAULT '0',
++              ADD INDEX (`uid`),
++              ADD INDEX (`aid`)");
++
++      if(!$r) return UPDATE_FAILED;
++      return UPDATE_SUCCESS;
++}
++
++function update_1160() {
 +      $r = q("ALTER TABLE `item` ADD `mention` TINYINT(1) NOT NULL DEFAULT '0', ADD INDEX (`mention`)");
 +// KEY `mention` (`mention`)
 +      if(!$r) return UPDATE_FAILED;
 +      return UPDATE_SUCCESS;
 +}