]> git.mxchange.org Git - friendica-addons.git/commitdiff
Merge pull request #94 from pokerazor/master
authorfriendica <info@friendica.com>
Wed, 9 Jan 2013 07:29:33 +0000 (23:29 -0800)
committerfriendica <info@friendica.com>
Wed, 9 Jan 2013 07:29:33 +0000 (23:29 -0800)
Updated OpenStreetMap

27 files changed:
communityhome.tgz
communityhome/README.md
communityhome/communityhome.css
communityhome/communityhome.php
communityhome/twillingham/README [deleted file]
communityhome/twillingham/communityhome.php [deleted file]
communityhome/view/directory_item.tpl
extcron.tgz
extcron/extcron.php
facebook.tgz
facebook/facebook.php
fbpost.tgz
fbpost/fbpost.php
forumdirectory.tgz
forumdirectory/forumdirectory.php
forumdirectory/view/forumdirectory_item.tpl
forumdirectory/view/smarty3/forumdirectory_item.tpl
forumlist.tgz
forumlist/forumlist.php
privacy_image_cache.tgz
privacy_image_cache/privacy_image_cache.php
procrunner.tgz [new file with mode: 0644]
procrunner/procrunner.php [new file with mode: 0755]
statusnet.tgz
statusnet/statusnet.php
twitter.tgz
twitter/twitter.php

index 71f1f8e30f3e38731dbf8efd496e65f82623ba94..ab251425b711a5e6749dedbf1c4a8f56b036d49a 100755 (executable)
Binary files a/communityhome.tgz and b/communityhome.tgz differ
index 3cf610ec17689aad9f90f2de3bf267d3a9be6bd9..21f2a9465f97389ea0d36325c93721e3e72ccdfe 100755 (executable)
@@ -9,3 +9,26 @@ choosed to be in site directory), last ten public photos and last ten
 In main content is shown the community stream. This plugin doesn't 
 honour your community page visibility site setting: the community 
 stream is shown also if you have choose to not show the community page.
+
+If 'home.html' is found in your friendica root, its content is inserted 
+before community stream
+
+Each elements can be show or not. At the moment, there is no admin page
+for settings, so this settings must be added to yout .htconfig.php
+
+
+    $a->config['communityhome']['showcommunitystream'] = true;
+    $a->config['communityhome']['showlastlike'] = true;
+    $a->config['communityhome']['showlastphotos'] = true;
+    $a->config['communityhome']['showactiveusers'] = true;
+    $a->config['communityhome']['showlastusers'] = true;
+
+If you don't want to show something, set it to false.
+
+Note:
+-----
+
+- Default is "false". With no settings in .htconfig.php, nothing is 
+shown, except login form and content of 'home.html'
+
+- Active users query can be heavy for db, and on some system don't work
index 2efb6ebd50621dc99db5367a54cfb5cdc662c1e5..45a65537487994063ffab79fdcfe09ccb1c04cf0 100755 (executable)
@@ -39,4 +39,5 @@ aside .directory-photo-img { max-width: 48px; max-height: 48px; }
 aside #likes { margin: 0px; padding: 0px; list-style: none; }
 
 
-aside #login-extra-links { overflow: auto;     width: 100%; padding-top:120px;}
+aside #div_id_remember { overflow: auto;       width: 100%; padding-top:120px;}
+#login_openid input { width: 160px; }
index 8b831888a330852c7f64c84318082704e42c51cc..ba2af6de62bf36340a92ec9b8dd49bae2fdfd2cb 100755 (executable)
@@ -2,7 +2,7 @@
 /**
  * Name: Community home
  * Description: Show last community activity in homepage
- * Version: 1.0
+ * Version: 2.0
  * Author: Fabio Comuni <http://kirgroup.com/profile/fabrixxm>
  */
 
@@ -35,145 +35,151 @@ function communityhome_home(&$a, &$o){
        $aside['$login_form'] = login(($a->config['register_policy'] == REGISTER_CLOSED) ? false : true);
        
        // last 12 users
-       $aside['$lastusers_title'] = t('Latest users');
-       $aside['$lastusers_items'] = array();
-       $sql_extra = "";
-       $publish = (get_config('system','publish_all') ? '' : " AND `publish` = 1 " );
-       $order = " ORDER BY `register_date` DESC ";
+       if (get_config('communityhome','showlastusers')===true){
+               $aside['$lastusers_title'] = t('Latest users');
+               $aside['$lastusers_items'] = array();
+               $sql_extra = "";
+               $publish = (get_config('system','publish_all') ? '' : " AND `publish` = 1 " );
+               $order = " ORDER BY `register_date` DESC ";
 
-       $r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`
-                       FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` 
-                       WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d , %d ",
-               0,
-               12
-       );
-#      $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
-       $tpl = get_markup_template( 'directory_item.tpl', 'addon/communityhome/' );
-       if(count($r)) {
-               $photo = 'thumb';
-               foreach($r as $rr) {
-                       $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
-                       $entry = replace_macros($tpl,array(
-                               '$id' => $rr['id'],
-                               '$profile-link' => $profile_link,
-                               '$photo' => $a->get_cached_avatar_image($rr[$photo]),
-                               '$alt-text' => $rr['name'],
-                       ));
-                       $aside['$lastusers_items'][] = $entry;
+               $r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`
+                               FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` 
+                               WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d , %d ",
+                       0,
+                       12
+               );
+       #       $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
+               $tpl = get_markup_template( 'directory_item.tpl', 'addon/communityhome/' );
+               if(count($r)) {
+                       $photo = 'thumb';
+                       foreach($r as $rr) {
+                               $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
+                               $entry = replace_macros($tpl,array(
+                                       '$id' => $rr['id'],
+                                       '$profile_link' => $profile_link,
+                                       '$photo' => $a->get_cached_avatar_image($rr[$photo]),
+                                       '$alt_text' => $rr['name'],
+                               ));
+                               $aside['$lastusers_items'][] = $entry;
+                       }
                }
        }
-       
        // 12 most active users (by posts and contacts)
        // this query don't work on some mysql versions
-       $r = q("SELECT `uni`.`contacts`,`uni`.`items`, `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`  FROM
-                       (SELECT COUNT(`id`) as `contacts`, `uid` FROM `contact` WHERE `self`=0 GROUP BY `uid`) AS `con`,
-                       (SELECT COUNT(`id`) as `items`, `uid` FROM `item` WHERE `item`.`changed` > DATE(NOW() - INTERVAL 1 MONTH) AND `item`.`wall` = 1 GROUP BY `uid`) AS `ite`,
-                       (
-                       SELECT `contacts`,`items`,`ite`.`uid` FROM `con` RIGHT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid` 
-                       UNION ALL 
-                       SELECT `contacts`,`items`,`con`.`uid` FROM `con` LEFT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid`
-                       ) AS `uni`, `user`, `profile`
-                       WHERE `uni`.`uid`=`user`.`uid`
-                       AND `uni`.`uid`=`profile`.`uid` AND `profile`.`publish`=1
-                       GROUP BY `uid`
-                       ORDER BY `items` DESC,`contacts` DESC
-                       LIMIT 0,10");
-       if($r && count($r)) {
-               $aside['$activeusers_title']  = t('Most active users');
-               $aside['$activeusers_items']  = array();
-               
-               $photo = 'thumb';
-               foreach($r as $rr) {
-                       $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
-                       $entry = replace_macros($tpl,array(
-                               '$id' => $rr['id'],
-                               '$profile-link' => $profile_link,
-                               '$photo' => $rr[$photo],
-                               '$alt-text' => sprintf("%s (%s posts, %s contacts)",$rr['name'], ($rr['items']?$rr['items']:'0'), ($rr['contacts']?$rr['contacts']:'0'))
-                       ));
-                       $aside['$activeusers_items'][] = $entry;
+       if (get_config('communityhome','showactiveusers')===true){
+               $r = q("SELECT `uni`.`contacts`,`uni`.`items`, `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`  FROM
+                               (SELECT COUNT(`id`) as `contacts`, `uid` FROM `contact` WHERE `self`=0 GROUP BY `uid`) AS `con`,
+                               (SELECT COUNT(`id`) as `items`, `uid` FROM `item` WHERE `item`.`changed` > DATE(NOW() - INTERVAL 1 MONTH) AND `item`.`wall` = 1 GROUP BY `uid`) AS `ite`,
+                               (
+                               SELECT `contacts`,`items`,`ite`.`uid` FROM `con` RIGHT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid` 
+                               UNION ALL 
+                               SELECT `contacts`,`items`,`con`.`uid` FROM `con` LEFT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid`
+                               ) AS `uni`, `user`, `profile`
+                               WHERE `uni`.`uid`=`user`.`uid`
+                               AND `uni`.`uid`=`profile`.`uid` AND `profile`.`publish`=1
+                               GROUP BY `uid`
+                               ORDER BY `items` DESC,`contacts` DESC
+                               LIMIT 0,10");
+               if($r && count($r)) {
+                       $aside['$activeusers_title']  = t('Most active users');
+                       $aside['$activeusers_items']  = array();
+                       
+                       $photo = 'thumb';
+                       foreach($r as $rr) {
+                               $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
+                               $entry = replace_macros($tpl,array(
+                                       '$id' => $rr['id'],
+                                       '$profile_link' => $profile_link,
+                                       '$photo' => $rr[$photo],
+                                       '$alt_text' => sprintf("%s (%s posts, %s contacts)",$rr['name'], ($rr['items']?$rr['items']:'0'), ($rr['contacts']?$rr['contacts']:'0'))
+                               ));
+                               $aside['$activeusers_items'][] = $entry;
+                       }
                }
        }
-       
        // last 12 photos
-       $aside['$photos_title'] = t('Latest photos');
-       $aside['$photos_items'] = array();
-       $r = q("SELECT `photo`.`id`, `photo`.`resource-id`, `photo`.`scale`, `photo`.`desc`, `user`.`nickname`, `user`.`username` FROM 
-                               (SELECT `resource-id`, MAX(`scale`) as maxscale FROM `photo` 
-                                       WHERE `profile`=0 AND `contact-id`=0 AND `album` NOT IN ('Contact Photos', '%s', 'Profile Photos', '%s')
-                                               AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`='' GROUP BY `resource-id`) AS `t1`
-                               INNER JOIN `photo` ON `photo`.`resource-id`=`t1`.`resource-id` AND `photo`.`scale` = `t1`.`maxscale`,
-                               `user` 
-                               WHERE `user`.`uid` = `photo`.`uid`
-                               AND `user`.`blockwall`=0
-                               AND `user`.`hidewall` = 0
-                               ORDER BY `photo`.`edited` DESC
-                               LIMIT 0, 12",
-                               dbesc(t('Contact Photos')),
-                               dbesc(t('Profile Photos'))
-                               );
+       if (get_config('communityhome','showlastphotos')===true){
+               $aside['$photos_title'] = t('Latest photos');
+               $aside['$photos_items'] = array();
+               $r = q("SELECT `photo`.`id`, `photo`.`resource-id`, `photo`.`scale`, `photo`.`desc`, `user`.`nickname`, `user`.`username` FROM 
+                                       (SELECT `resource-id`, MAX(`scale`) as maxscale FROM `photo` 
+                                               WHERE `profile`=0 AND `contact-id`=0 AND `album` NOT IN ('Contact Photos', '%s', 'Profile Photos', '%s')
+                                                       AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`='' GROUP BY `resource-id`) AS `t1`
+                                       INNER JOIN `photo` ON `photo`.`resource-id`=`t1`.`resource-id` AND `photo`.`scale` = `t1`.`maxscale`,
+                                       `user` 
+                                       WHERE `user`.`uid` = `photo`.`uid`
+                                       AND `user`.`blockwall`=0
+                                       AND `user`.`hidewall` = 0
+                                       ORDER BY `photo`.`edited` DESC
+                                       LIMIT 0, 12",
+                                       dbesc(t('Contact Photos')),
+                                       dbesc(t('Profile Photos'))
+                                       );
 
-               
-       if(count($r)) {
-#              $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
-               $tpl = get_markup_template( 'directory_item.tpl', 'addon/communityhome/' );
-               foreach($r as $rr) {
-                       $photo_page = $a->get_baseurl() . '/photos/' . $rr['nickname'] . '/image/' . $rr['resource-id'];
-                       $photo_url = $a->get_baseurl() . '/photo/' .  $rr['resource-id'] . '-' . $rr['scale'] .'.jpg';
-               
-                       $entry = replace_macros($tpl,array(
-                               '$id' => $rr['id'],
-                               '$profile-link' => $photo_page,
-                               '$photo' => $photo_url,
-                               '$alt-text' => $rr['username']." : ".$rr['desc'],
-                       ));
+                       
+               if(count($r)) {
+       #               $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
+                       $tpl = get_markup_template( 'directory_item.tpl', 'addon/communityhome/' );
+                       foreach($r as $rr) {
+                               $photo_page = $a->get_baseurl() . '/photos/' . $rr['nickname'] . '/image/' . $rr['resource-id'];
+                               $photo_url = $a->get_baseurl() . '/photo/' .  $rr['resource-id'] . '-' . $rr['scale'] .'.jpg';
+                       
+                               $entry = replace_macros($tpl,array(
+                                       '$id' => $rr['id'],
+                                       '$profile_link' => $photo_page,
+                                       '$photo' => $photo_url,
+                                       '$alt_text' => $rr['username']." : ".$rr['desc'],
+                               ));
 
-                       $aside['$photos_items'][] = $entry;
+                               $aside['$photos_items'][] = $entry;
+                       }
                }
        }
        
        // last 10 liked items
-       $aside['$like_title'] = t('Latest likes');
-       $aside['$like_items'] = array();
-       $r = q("SELECT `T1`.`created`, `T1`.`liker`, `T1`.`liker-link`, `item`.* FROM 
-                       (SELECT `parent-uri`, `created`, `author-name` AS `liker`,`author-link` AS `liker-link` 
-                               FROM `item` WHERE `verb`='http://activitystrea.ms/schema/1.0/like' GROUP BY `parent-uri` ORDER BY `created` DESC) AS T1
-                       INNER JOIN `item` ON `item`.`uri`=`T1`.`parent-uri` 
-                       WHERE `T1`.`liker-link` LIKE '%s%%' OR `item`.`author-link` LIKE '%s%%'
-                       GROUP BY `uri`
-                       ORDER BY `T1`.`created` DESC
-                       LIMIT 0,10",
-                       $a->get_baseurl(),$a->get_baseurl()
-                       );
+       if (get_config('communityhome','showlastlike')===true){
+               $aside['$like_title'] = t('Latest likes');
+               $aside['$like_items'] = array();
+               $r = q("SELECT `T1`.`created`, `T1`.`liker`, `T1`.`liker-link`, `item`.* FROM 
+                               (SELECT `parent-uri`, `created`, `author-name` AS `liker`,`author-link` AS `liker-link` 
+                                       FROM `item` WHERE `verb`='http://activitystrea.ms/schema/1.0/like' GROUP BY `parent-uri` ORDER BY `created` DESC) AS T1
+                               INNER JOIN `item` ON `item`.`uri`=`T1`.`parent-uri` 
+                               WHERE `T1`.`liker-link` LIKE '%s%%' OR `item`.`author-link` LIKE '%s%%'
+                               GROUP BY `uri`
+                               ORDER BY `T1`.`created` DESC
+                               LIMIT 0,10",
+                               $a->get_baseurl(),$a->get_baseurl()
+                               );
 
-       foreach ($r as $rr) {
-               $author  = '<a href="' . $rr['liker-link'] . '">' . $rr['liker'] . '</a>';
-               $objauthor =  '<a href="' . $rr['author-link'] . '">' . $rr['author-name'] . '</a>';
-               
-               //var_dump($rr['verb'],$rr['object-type']); killme();
-               switch($rr['verb']){
-                       case 'http://activitystrea.ms/schema/1.0/post':
-                               switch ($rr['object-type']){
-                                       case 'http://activitystrea.ms/schema/1.0/event':
-                                               $post_type = t('event');
-                                               break;
-                                       default:
+               foreach ($r as $rr) {
+                       $author  = '<a href="' . $rr['liker-link'] . '">' . $rr['liker'] . '</a>';
+                       $objauthor =  '<a href="' . $rr['author-link'] . '">' . $rr['author-name'] . '</a>';
+                       
+                       //var_dump($rr['verb'],$rr['object-type']); killme();
+                       switch($rr['verb']){
+                               case 'http://activitystrea.ms/schema/1.0/post':
+                                       switch ($rr['object-type']){
+                                               case 'http://activitystrea.ms/schema/1.0/event':
+                                                       $post_type = t('event');
+                                                       break;
+                                               default:
+                                                       $post_type = t('status');
+                                       }
+                                       break;
+                               default:
+                                       if ($rr['resource-id']){
+                                               $post_type = t('photo');
+                                               $m=array();     preg_match("/\[url=([^]]*)\]/", $rr['body'], $m);
+                                               $rr['plink'] = $m[1];
+                                       } else {
                                                $post_type = t('status');
-                               }
-                               break;
-                       default:
-                               if ($rr['resource-id']){
-                                       $post_type = t('photo');
-                                       $m=array();     preg_match("/\[url=([^]]*)\]/", $rr['body'], $m);
-                                       $rr['plink'] = $m[1];
-                               } else {
-                                       $post_type = t('status');
-                               }
-               }
-               $plink = '<a href="' . $rr['plink'] . '">' . $post_type . '</a>';
+                                       }
+                       }
+                       $plink = '<a href="' . $rr['plink'] . '">' . $post_type . '</a>';
 
-               $aside['$like_items'][] = sprintf( t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
-               
+                       $aside['$like_items'][] = sprintf( t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
+                       
+               }
        }
        
 #      $tpl = file_get_contents(dirname(__file__).'/communityhome.tpl');
@@ -182,8 +188,13 @@ function communityhome_home(&$a, &$o){
        
        $o = '<h1>' . ((x($a->config,'sitename')) ? sprintf( t("Welcome to %s") ,$a->config['sitename']) : "" ) . '</h1>';
        
-       $oldset = get_config('system','no_community_page');
-       set_config('system','no_community_page', false);
-       $o .= community_content($a,1);
-       set_config('system','no_community_page', $oldset);
+       if(file_exists('home.html'))
+               $o = file_get_contents('home.html');
+       
+       if (get_config('communityhome','showcommunitystream')===true){
+               $oldset = get_config('system','no_community_page');
+               set_config('system','no_community_page', false);
+               $o .= community_content($a,1);
+               set_config('system','no_community_page', $oldset);
+       }
 }
diff --git a/communityhome/twillingham/README b/communityhome/twillingham/README
deleted file mode 100644 (file)
index dbbe141..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-This is a variant of the community home.  Instead of displaying the community tab in the front page, we still use home.html, but we also add the latest users to the sidebar.
-
-Simply replace addon/communityhome/communityhome.php with this version then enable community home in your admin panel as usual.
\ No newline at end of file
diff --git a/communityhome/twillingham/communityhome.php b/communityhome/twillingham/communityhome.php
deleted file mode 100644 (file)
index 102732a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/**
- * Name: Community home
- * Description: Show last community activity in homepage
- * Version: 1.0
- * Author: Fabio Comuni <http://kirgroup.com/profile/fabrixxm>
- */
-
-
-require_once('mod/community.php');
-
-
-function communityhome_install() {
-       register_hook('home_content', 'addon/communityhome/communityhome.php', 'communityhome_home');
-       logger("installed communityhome");
-}
-
-function communityhome_uninstall() {
-       unregister_hook('home_content', 'addon/communityhome/communityhome.php', 'communityhome_home');
-       logger("removed communityhome");
-}
-
-function communityhome_home(&$a, &$o){
-       // custom css
-       $a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="'.$a->get_baseurl().'/addon/communityhome/communityhome.css" media="all" />';
-       
-       $aside = array(
-               '$tab_1' => t('Login'),
-               '$tab_2' => t('OpenID'),
-               '$noOid' => get_config('system','no_openid'),
-       );
-       
-       // login form
-       $aside['$login_title'] =  t('Login');
-       $aside['$login_form'] = login(($a->config['register_policy'] == REGISTER_CLOSED) ? false : true);
-       
-       // last 12 users
-       $aside['$lastusers_title'] = t('Latest users');
-       $aside['$lastusers_items'] = array();
-       $sql_extra = "";
-       $publish = (get_config('system','publish_all') ? '' : " AND `publish` = 1 " );
-       $order = " ORDER BY `register_date` DESC ";
-
-       $r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`
-                       FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` 
-                       WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d , %d ",
-               0,
-               12
-       );
-       $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
-       if(count($r)) {
-               $photo = 'thumb';
-               foreach($r as $rr) {
-                       $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
-                       $entry = replace_macros($tpl,array(
-                               '$id' => $rr['id'],
-                               '$profile-link' => $profile_link,
-                               '$photo' => $rr[$photo],
-                               '$alt-text' => $rr['name'],
-                       ));
-                       $aside['$lastusers_items'][] = $entry;
-               }
-       }
-       
-       // 12 most active users (by posts and contacts)
-       // this query don't work on some mysql versions
-       $r = q("SELECT `uni`.`contacts`,`uni`.`items`, `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`  FROM
-                       (SELECT COUNT(`id`) as `contacts`, `uid` FROM `contact` WHERE `self`=0 GROUP BY `uid`) AS `con`,
-                       (SELECT COUNT(`id`) as `items`, `uid` FROM `item` WHERE `item`.`changed` > DATE(NOW() - INTERVAL 1 MONTH) AND `item`.`wall` = 1 GROUP BY `uid`) AS `ite`,
-                       (
-                       SELECT `contacts`,`items`,`ite`.`uid` FROM `con` RIGHT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid` 
-                       UNION ALL 
-                       SELECT `contacts`,`items`,`con`.`uid` FROM `con` LEFT OUTER JOIN `ite` ON `con`.`uid`=`ite`.`uid`
-                       ) AS `uni`, `user`, `profile`
-                       WHERE `uni`.`uid`=`user`.`uid`
-                       AND `uni`.`uid`=`profile`.`uid` AND `profile`.`publish`=1
-                       GROUP BY `uid`
-                       ORDER BY `items` DESC,`contacts` DESC
-                       LIMIT 0,10");
-       if($r && count($r)) {
-               $aside['$activeusers_title']  = t('Most active users');
-               $aside['$activeusers_items']  = array();
-               
-               $photo = 'thumb';
-               foreach($r as $rr) {
-                       $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
-                       $entry = replace_macros($tpl,array(
-                               '$id' => $rr['id'],
-                               '$profile-link' => $profile_link,
-                               '$photo' => $rr[$photo],
-                               '$alt-text' => sprintf("%s (%s posts, %s contacts)",$rr['name'], ($rr['items']?$rr['items']:'0'), ($rr['contacts']?$rr['contacts']:'0'))
-                       ));
-                       $aside['$activeusers_items'][] = $entry;
-               }
-       }
-       
-       
-       
-       
-       $tpl = file_get_contents(dirname(__file__).'/communityhome.tpl');
-       $a->page['aside'] = replace_macros($tpl, $aside);
-       $o = '';
-       if(file_exists('home.html'))
-       
-               $o .= file_get_contents('home.html');
-       
-}
index db1936e4b725d6cd532b3d347531295e71356c9e..f32f5a4f78068a609de8de623cfe2cd370cc38f9 100755 (executable)
@@ -2,8 +2,8 @@
 <div class="directory-item" id="directory-item-$id" >
        <div class="directory-photo-wrapper" id="directory-photo-wrapper-$id" > 
                <div class="directory-photo" id="directory-photo-$id" >
-                       <a href="$profile-link" class="directory-profile-link" id="directory-profile-link-$id" >
-                               <img class="directory-photo-img" src="$photo" alt="$alt-text" title="$alt-text" />
+                       <a href="$profile_link" class="directory-profile-link" id="directory-profile-link-$id" >
+                               <img class="directory-photo-img" src="$photo" alt="$alt_text" title="$alt_text" />
                        </a>
                </div>
        </div>
index 0e5b28929a2942f5105b87922f563f5184f6fdeb..dabe1d09db19ebba110adfad1ae1ed77caf438bc 100755 (executable)
Binary files a/extcron.tgz and b/extcron.tgz differ
index e3c21209b3c33e28d8e34caef0181d98efd183f5..3eb34cdcb2dcd2e072d5c75dd5794a8d467c6dbc 100755 (executable)
@@ -5,7 +5,7 @@
  * Name: external cron
  * Description: Use external server or service to run poller regularly
  * Version: 1.0
- * Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
+ * Author: Mike Macgirvin <https://macgirvin.com/profile/mike>
  * 
  * Notes: External service needs to make a web request to http(s)://yoursite/extcron
  */
index 6bf8f7a990c5c31be19c91051e7924d8234cf90b..2dbd4efd0f28329b0616821454299916880db917 100644 (file)
Binary files a/facebook.tgz and b/facebook.tgz differ
index f977bef90192f469097bc26d3cb729aab93447f9..4c1c0a14142dcc34e5768ceb103454fc0d5f2f2c 100644 (file)
@@ -383,10 +383,12 @@ function fb_get_friends_sync_full($uid, $access_token, $persons) {
         if($s) {
             $results = json_decode($s);
             logger('fb_get_friends: info: ' . print_r($results,true), LOGGER_DATA);
-            foreach ($results as $contact) {
-                if ($contact->code != 200) logger('fb_get_friends: not found: ' . print_r($contact,true), LOGGER_DEBUG);
-                else fb_get_friends_sync_parsecontact($uid, json_decode($contact->body));
-            }
+                       if(count($results)) {
+                   foreach ($results as $contact) {
+                   if ($contact->code != 200) logger('fb_get_friends: not found: ' . print_r($contact,true), LOGGER_DEBUG);
+                       else fb_get_friends_sync_parsecontact($uid, json_decode($contact->body));
+               }
+                       }
         }
     }
 }
index ecf933d8e023c0c5ddabf96e975d3e7364682796..790a573214bb411a4a4ba3f1a00ca8364d199fb9 100644 (file)
Binary files a/fbpost.tgz and b/fbpost.tgz differ
index ab49c30336c3d5992c376fff76bd1ca4e162a902..1486afdb2ba6efb802cf87075ccfd16c2c813d29 100644 (file)
@@ -21,7 +21,8 @@
  * authenticate to your site to establish identity. We will address this 
  * in a future release.
  */
+
+define('FACEBOOK_DEFAULT_POLL_INTERVAL', 5); // given in minutes
 
 require_once('include/security.php');
 
@@ -32,6 +33,7 @@ function fbpost_install() {
        register_hook('connector_settings',  'addon/fbpost/fbpost.php', 'fbpost_plugin_settings');
        register_hook('enotify',          'addon/fbpost/fbpost.php', 'fbpost_enotify');
        register_hook('queue_predeliver', 'addon/fbpost/fbpost.php', 'fbpost_queue_hook');
+       register_hook('cron',             'addon/fbpost/fbpost.php', 'fbpost_cron');
 }
 
 
@@ -42,8 +44,7 @@ function fbpost_uninstall() {
        unregister_hook('connector_settings',  'addon/fbpost/fbpost.php', 'fbpost_plugin_settings');
        unregister_hook('enotify',          'addon/fbpost/fbpost.php', 'fbpost_enotify');
        unregister_hook('queue_predeliver', 'addon/fbpost/fbpost.php', 'fbpost_queue_hook');
-
-
+       unregister_hook('cron',             'addon/fbpost/fbpost.php', 'fbpost_cron');
 }
 
 
@@ -140,6 +141,9 @@ function fbpost_post(&$a) {
                $value = ((x($_POST,'post_by_default')) ? intval($_POST['post_by_default']) : 0);
                set_pconfig($uid,'facebook','post_by_default', $value);
 
+               $value = ((x($_POST,'mirror_posts')) ? intval($_POST['mirror_posts']) : 0);
+               set_pconfig($uid,'facebook','mirror_posts', $value);
+
                $value = ((x($_POST,'suppress_view_on_friendica')) ? intval($_POST['suppress_view_on_friendica']) : 0);
                set_pconfig($uid,'facebook','suppress_view_on_friendica', $value);
 
@@ -209,7 +213,7 @@ function fbpost_content(&$a) {
                $o .= '<div id="fbpost-enable-wrapper">';
 
                $o .= '<a href="https://www.facebook.com/dialog/oauth?client_id=' . $appid . '&redirect_uri=' 
-                       . $a->get_baseurl() . '/fbpost/' . $a->user['nickname'] . '&scope=publish_stream,manage_pages,photo_upload,user_groups,offline_access">' . t('Install Facebook Post connector for this account.') . '</a>';
+                       . $a->get_baseurl() . '/fbpost/' . $a->user['nickname'] . '&scope=read_stream,publish_stream,manage_pages,photo_upload,user_groups,offline_access">' . t('Install Facebook Post connector for this account.') . '</a>';
                $o .= '</div>';
        }
 
@@ -221,7 +225,7 @@ function fbpost_content(&$a) {
                $o .= '<div id="fbpost-enable-wrapper">';
 
                $o .= '<a href="https://www.facebook.com/dialog/oauth?client_id=' . $appid . '&redirect_uri=' 
-                       . $a->get_baseurl() . '/fbpost/' . $a->user['nickname'] . '&scope=publish_stream,manage_pages,photo_upload,user_groups,offline_access">' . t('Re-authenticate [This is necessary whenever your Facebook password is changed.]') . '</a>';
+                       . $a->get_baseurl() . '/fbpost/' . $a->user['nickname'] . '&scope=read_stream,publish_stream,manage_pages,photo_upload,user_groups,offline_access">' . t('Re-authenticate [This is necessary whenever your Facebook password is changed.]') . '</a>';
                $o .= '</div>';
 
                $o .= '<div id="fbpost-post-default-form">';
@@ -234,6 +238,10 @@ function fbpost_content(&$a) {
                $checked = (($suppress_view_on_friendica) ? ' checked="checked" ' : '');
                $o .= '<input type="checkbox" name="suppress_view_on_friendica" value="1"' . $checked . '/>' . ' ' . t('Suppress "View on friendica"') . EOL;
 
+               $mirror_posts = get_pconfig(local_user(),'facebook','mirror_posts');
+               $checked = (($mirror_posts) ? ' checked="checked" ' : '');
+               $o .= '<input type="checkbox" name="mirror_posts" value="1"' . $checked . '/>' . ' ' . t('Mirror wall posts from facebook to friendica.') . EOL;
+
                // List all pages
                $post_to_page = get_pconfig(local_user(),'facebook','post_to_page');
                $page_access_token = get_pconfig(local_user(),'facebook','page_access_token');
@@ -386,6 +394,14 @@ function fbpost_post_hook(&$a,&$b) {
        if($b['deleted'] || ($b['created'] !== $b['edited']))
                return;
 
+       // Don't transmit answers (have to be cleaned up in the following code)
+       if($b['parent'] != $b['id'])
+               return;
+
+       // if post comes from facebook don't send it back
+       if($b['app'] == "Facebook")
+               return;
+
        /**
         * Post to Facebook stream
         */
@@ -931,28 +947,28 @@ function fbpost_queue_hook(&$a,&$b) {
  * @return bool|string
  */
 function fbpost_get_app_access_token() {
-       
+
        $acc_token = get_config('facebook','app_access_token');
-       
+
        if ($acc_token !== false) return $acc_token;
-       
+
        $appid = get_config('facebook','appid');
        $appsecret = get_config('facebook', 'appsecret');
-       
+
        if ($appid === false || $appsecret === false) {
                logger('fb_get_app_access_token: appid and/or appsecret not set', LOGGER_DEBUG);
                return false;
        }
        logger('https://graph.facebook.com/oauth/access_token?client_id=' . $appid . '&client_secret=' . $appsecret . '&grant_type=client_credentials', LOGGER_DATA);
        $x = fetch_url('https://graph.facebook.com/oauth/access_token?client_id=' . $appid . '&client_secret=' . $appsecret . '&grant_type=client_credentials');
-       
+
        if(strpos($x,'access_token=') !== false) {
                logger('fb_get_app_access_token: returned access token: ' . $x, LOGGER_DATA);
-       
+
                $token = str_replace('access_token=', '', $x);
                if(strpos($token,'&') !== false)
                        $token = substr($token,0,strpos($token,'&'));
-               
+
                if ($token == "") {
                        logger('fb_get_app_access_token: empty token: ' . $x, LOGGER_DEBUG);
                        return false;
@@ -965,3 +981,214 @@ function fbpost_get_app_access_token() {
        }
 }
 
+function fbpost_cron($a,$b) {
+       $last = get_config('facebook','last_poll');
+
+       $poll_interval = intval(get_config('facebook','poll_interval'));
+       if(! $poll_interval)
+               $poll_interval = FACEBOOK_DEFAULT_POLL_INTERVAL;
+
+       if($last) {
+               $next = $last + ($poll_interval * 60);
+               if($next > time()) {
+                       logger('facebook: poll intervall not reached');
+                       return;
+               }
+       }
+       logger('facebook: cron_start');
+
+       $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'mirror_posts' AND `v` = '1' ORDER BY RAND() ");
+       if(count($r)) {
+               foreach($r as $rr) {
+                       logger('facebook: fetching for user '.$rr['uid']);
+                       fbpost_fetchwall($a, $rr['uid']);
+               }
+       }
+
+       logger('facebook: cron_end');
+
+       set_config('facebook','last_poll', time());
+}
+
+function fbpost_fetchwall($a, $uid) {
+       $access_token = get_pconfig($uid,'facebook','access_token');
+       $post_to_page = get_pconfig($uid,'facebook','post_to_page');
+       $lastcreated = get_pconfig($uid,'facebook','last_created');
+
+       if ((int)$post_to_page == 0)
+               $post_to_page = "me";
+
+       $url = "https://graph.facebook.com/".$post_to_page."/feed?access_token=".$access_token;
+
+       $first_time = ($lastcreated == "");
+
+       if ($lastcreated != "")
+               $url .= "&since=".urlencode($lastcreated);
+
+       $feed = fetch_url($url);
+       $data = json_decode($feed);
+       $items = array_reverse($data->data);
+
+       foreach ($items as $item) {
+               if ($item->created_time > $lastcreated)
+                       $lastcreated = $item->created_time;
+
+               if ($first_time)
+                       continue;
+
+               if ($item->application->id == get_config('facebook','appid'))
+                       continue;
+
+               if(isset($item->privacy) && ($item->privacy->value !== 'EVERYONE') && ($item->privacy->value !== ''))
+                       continue;
+
+               $_SESSION["authenticated"] = true;
+               $_SESSION["uid"] = $uid;
+
+               $_REQUEST["type"] = "wall";
+               $_REQUEST["api_source"] = true;
+               $_REQUEST["profile_uid"] = $uid;
+               $_REQUEST["source"] = "Facebook";
+
+               $_REQUEST["body"] = (isset($item->message) ? escape_tags($item->message) : '');
+
+               if(isset($item->name) and isset($item->link))
+                       $_REQUEST["body"] .= "\n\n[bookmark=".$item->link."]".$item->name."[/bookmark]";
+               elseif (isset($item->name))
+                       $_REQUEST["body"] .= "\n\n[b]" . $item->name."[/b]";
+
+               /*if(isset($item->caption)) {
+                       if(!isset($item->name) and isset($item->link))
+                               $_REQUEST["body"] .= "\n\n[bookmark=".$item->link."]".$item->caption."[/bookmark]";
+                       //else
+                       //      $_REQUEST["body"] .= "[i]" . $item->caption."[/i]\n";
+                       }
+
+                       if(!isset($item->caption) and !isset($item->name)) {
+                               if (isset($item->link))
+                                       $_REQUEST["body"] .= "\n[url]".$item->link."[/url]\n";
+                               else
+                                       $_REQUEST["body"] .= "\n";
+               }*/
+
+               $quote = "";
+               if(isset($item->description) and ($item->type != "photo"))
+                       $quote = $item->description;
+
+               if(isset($item->caption) and ($item->type == "photo"))
+                       $quote = $item->caption;
+
+               //if (isset($item->properties))
+               //      foreach ($item->properties as $property)
+               //              $quote .= "\n".$property->name.": [url=".$property->href."]".$property->text."[/url]";
+
+               if ($quote)
+                       $_REQUEST["body"] .= "\n[quote]".$quote."[/quote]";
+
+               // Only import the picture when the message is no video
+               // oembed display a picture of the video as well
+               if ($item->type != "video") {
+               //if (($item->type != "video") and ($item->type != "photo")) {
+                       if(isset($item->picture) && isset($item->link))
+                               $_REQUEST["body"] .= "\n".'[url='.$item->link.'][img]'.fpost_cleanpicture($item->picture).'[/img][/url]';
+                       else {
+                               if (isset($item->picture))
+                                       $_REQUEST["body"] .= "\n".'[img]'.fpost_cleanpicture($item->picture).'[/img]';
+                               // if just a link, it may be a wall photo - check
+                               if(isset($item->link))
+                                       $_REQUEST["body"] .= fbpost_get_photo($uid,$item->link);
+                       }
+               }
+
+               /*if (($datarray['app'] == "Events") and isset($item->actions))
+                       foreach ($item->actions as $action)
+                               if ($action->name == "View")
+                                       $_REQUEST["body"] .= " [url=".$action->link."]".$item->story."[/url]";
+               */
+
+               if(trim($_REQUEST["body"]) == '') {
+                       logger('facebook: empty body '.$item->id.' '.print_r($item, true));
+                       continue;
+               }
+
+               $_REQUEST["body"] = trim($_REQUEST["body"]);
+
+               if (isset($item->place)) {
+                       if ($item->place->name or $item->place->location->street or
+                               $item->place->location->city or $item->place->location->country) {
+                               $_REQUEST["location"] = '';
+                               if ($item->place->name)
+                                       $_REQUEST["location"] .= $item->place->name;
+                               if ($item->place->location->street)
+                                       $_REQUEST["location"] .= " ".$item->place->location->street;
+                               if ($item->place->location->city)
+                                       $_REQUEST["location"] .= " ".$item->place->location->city;
+                               if ($item->place->location->country)
+                                       $_REQUEST["location"] .= " ".$item->place->location->country;
+
+                               $_REQUEST["location"] = trim($_REQUEST["location"]);
+                       }
+                       if ($item->place->location->latitude and $item->place->location->longitude)
+                               $_REQUEST["coord"] = substr($item->place->location->latitude, 0, 8)
+                                               .' '.substr($item->place->location->longitude, 0, 8);
+               }
+
+               //print_r($_REQUEST);
+               logger('facebook: posting for user '.$uid);
+
+               require_once('mod/item.php');
+               item_post($a);
+       }
+
+       set_pconfig($uid,'facebook','last_created', $lastcreated);
+}
+
+function fbpost_get_photo($uid,$link) {
+       $access_token = get_pconfig($uid,'facebook','access_token');
+       if(! $access_token || (! stristr($link,'facebook.com/photo.php')))
+               return "";
+
+       $ret = preg_match('/fbid=([0-9]*)/',$link,$match);
+       if($ret)
+               $photo_id = $match[1];
+       else
+               return "";
+
+       $x = fetch_url('https://graph.facebook.com/'.$photo_id.'?access_token='.$access_token);
+       $j = json_decode($x);
+       if($j->picture)
+               return "\n\n".'[url='.$link.'][img]'.fpost_cleanpicture($j->picture).'[/img][/url]';
+
+       return "";
+}
+
+function fpost_cleanpicture($image) {
+
+       if (strpos($image, ".fbcdn.net/") and (substr($image, -6) == "_s.jpg"))
+               $image = substr($image, 0, -6)."_n.jpg";
+
+       $queryvar = fbpost_parse_query($image);
+       if ($queryvar['url'] != "")
+               $image = urldecode($queryvar['url']);
+
+       return $image;
+}
+
+function fbpost_parse_query($var) {
+       /**
+        *  Use this function to parse out the query array element from
+        *  the output of parse_url().
+       */
+       $var  = parse_url($var, PHP_URL_QUERY);
+       $var  = html_entity_decode($var);
+       $var  = explode('&', $var);
+       $arr  = array();
+
+       foreach($var as $val) {
+               $x          = explode('=', $val);
+               $arr[$x[0]] = $x[1];
+       }
+
+       unset($val, $x, $var);
+       return $arr;
+}
index 249cd22645f56aa842c15b68551b885e89cfbc55..0a84585dd41af97f49d12658c1f3576c295b5c4b 100644 (file)
Binary files a/forumdirectory.tgz and b/forumdirectory.tgz differ
index 0d7fbee804891533deffd4b888cbc0f09c081546..9837b9c18aa878f84c4a7bdf0a5f654b76a57acc 100644 (file)
@@ -168,12 +168,12 @@ function forumdirectory_content(&$a) {
 
                        $entry = replace_macros($tpl,array(
                                '$id' => $rr['id'],
-                               '$profile-link' => $profile_link,
+                               '$profile_link' => $profile_link,
                                '$photo' => $a->get_cached_avatar_image($rr[$photo]),
-                               '$alt-text' => $rr['name'],
+                               '$alt_text' => $rr['name'],
                                '$name' => $rr['name'],
                                '$details' => $pdesc . $details,
-                               '$page-type' => $page_type,
+                               '$page_type' => $page_type,
                                '$profile' => $profile,
                                '$location' => template_escape($location),
                                '$gender'   => $gender,
index 3b24d25f2b9acca86a6b043d1e0cd53810e10192..e1bbffec8223051dce3ac956928329c6eeca5065 100755 (executable)
@@ -2,14 +2,14 @@
 <div class="forumdirectory-item" id="forumdirectory-item-$id" >
        <div class="forumdirectory-photo-wrapper" id="forumdirectory-photo-wrapper-$id" > 
                <div class="forumdirectory-photo" id="forumdirectory-photo-$id" >
-                       <a href="$profile-link" class="forumdirectory-profile-link" id="forumdirectory-profile-link-$id" >
-                               <img class="forumdirectory-photo-img photo" src="$photo" alt="$alt-text" title="$alt-text" />
+                       <a href="$profile_link" class="forumdirectory-profile-link" id="forumdirectory-profile-link-$id" >
+                               <img class="forumdirectory-photo-img photo" src="$photo" alt="$alt_text" title="$alt_text" />
                        </a>
                </div>
        </div>
        <div class="forumdirectory-profile-wrapper" id="forumdirectory-profile-wrapper-$id" >
                <div class="contact-name" id="forumdirectory-name-$id">$name</div>
-               <div class="page-type">$page-type</div>
+               <div class="page-type">$page_type</div>
                {{ if $pdesc }}<div class="forumdirectory-profile-title">$profile.pdesc</div>{{ endif }}
        <div class="forumdirectory-detailcolumns-wrapper" id="forumdirectory-detailcolumns-wrapper-$id">
                <div class="forumdirectory-detailscolumn-wrapper" id="forumdirectory-detailscolumn1-wrapper-$id">       
index 540a5aeae7d61d5575b38a0c8d539829be23e676..66410efed8645a5bdc6b9695b8b75e0b1e99ce06 100644 (file)
@@ -2,14 +2,14 @@
 <div class="forumdirectory-item" id="forumdirectory-item-{{$id}}" >
        <div class="forumdirectory-photo-wrapper" id="forumdirectory-photo-wrapper-{{$id}}" > 
                <div class="forumdirectory-photo" id="forumdirectory-photo-{{$id}}" >
-                       <a href="{{$profile}}-link" class="forumdirectory-profile-link" id="forumdirectory-profile-link-{{$id}}" >
-                               <img class="forumdirectory-photo-img photo" src="{{$photo}}" alt="{{$alt}}-text" title="{{$alt}}-text" />
+                       <a href="{{$profile_link}}" class="forumdirectory-profile-link" id="forumdirectory-profile-link-{{$id}}" >
+                               <img class="forumdirectory-photo-img photo" src="{{$photo}}" alt="{{$alt_text}}" title="{{$alt_text}}" />
                        </a>
                </div>
        </div>
        <div class="forumdirectory-profile-wrapper" id="forumdirectory-profile-wrapper-{{$id}}" >
                <div class="contact-name" id="forumdirectory-name-{{$id}}">{{$name}}</div>
-               <div class="page-type">{{$page}}-type</div>
+               <div class="page-type">{{$page_type}}</div>
                {{if $pdesc}}<div class="forumdirectory-profile-title">{{$profile.pdesc}}</div>{{/if}}
        <div class="forumdirectory-detailcolumns-wrapper" id="forumdirectory-detailcolumns-wrapper-{{$id}}">
                <div class="forumdirectory-detailscolumn-wrapper" id="forumdirectory-detailscolumn1-wrapper-{{$id}}">   
index 1f303145a19366d9c5b261966f6bbf5473136c16..8356d443d0cb1ade39c865f13e6efcca67e36f79 100644 (file)
Binary files a/forumlist.tgz and b/forumlist.tgz differ
index 37752462912efccd9a70bc8fdb882b9bad5b5f94..95ae98909bf81e4e81905ae21cf6c0beb7c054a0 100644 (file)
@@ -74,7 +74,7 @@ function forumlist_network_mod_init($a,$b) {
 
        if(count($contacts)) {
                foreach($contacts as $contact) {
-                       $forumlist .= '<a href="' . $a->get_baseurl() . '/redir/' . $contact["id"] . '" title="' . $contact['url'] . '" class="label sparkle" target="external-link"><img class="forumlist-img" height="20" width="20" src="' . $contact['micro'] .'" alt="' . $contact['url'] . '" /></a> <a href="' . $a->get_baseurl() . '/network?f=&cid=' . $contact['id'] . '" >' . $contact["name"]."</a><br />";
+                       $forumlist .= '<div><a href="' . $a->get_baseurl() . '/redir/' . $contact["id"] . '" title="' . $contact['url'] . '" class="label sparkle" target="external-link"><img class="forumlist-img" height="20" width="20" src="' . $contact['micro'] .'" alt="' . $contact['url'] . '" /></a> <a href="' . $a->get_baseurl() . '/network?f=&cid=' . $contact['id'] . '" >' . $contact["name"]."</a></div>";
                }
        }
        else {
index b0690fc2bcb02d3f208ae0a54901db629b7a4d0c..45444a683932dcf4da5a6c8ee63fee86b5f868f2 100644 (file)
Binary files a/privacy_image_cache.tgz and b/privacy_image_cache.tgz differ
index 3be4262088310dbf8751c9ff791d071b115deefa..0e241e7e36825b8aea73635b30aa5fdb396c05cf 100644 (file)
@@ -119,7 +119,17 @@ function privacy_image_cache_init() {
                // It shouldn't happen but it does - spaces in URL
                $_REQUEST['url'] = str_replace(" ", "+", $_REQUEST['url']);
 
-               $img_str = fetch_url($_REQUEST['url'],true);
+               // if the picture seems to be from another picture cache then take the original source
+               $queryvar = privacy_image_cache_parse_query($_REQUEST['url']);
+               if ($queryvar['url'] != "")
+                       $_REQUEST['url'] = urldecode($queryvar['url']);
+
+               // if fetching facebook pictures don't fetch the thumbnail but the big one
+               if (strpos($_REQUEST['url'], ".fbcdn.net/") and (substr($_REQUEST['url'], -6) == "_s.jpg"))
+                       $_REQUEST['url'] = substr($_REQUEST['url'], 0, -6)."_n.jpg";
+
+               $redirects = 0;
+               $img_str = fetch_url($_REQUEST['url'],true, $redirects, 10);
 
                $tempfile = tempnam(get_config("system","temppath"), "cache");
                file_put_contents($tempfile, $img_str);
@@ -132,9 +142,9 @@ function privacy_image_cache_init() {
                        $mime = "image/png";
                        $cachefile = ""; // Clear the cachefile so that the dummy isn't stored
                        $valid = false;
-                       $img = new Photo($img_str);
+                       $img = new Photo($img_str, "image/png");
                        if($img->is_valid()) {
-                               $img->scaleImage(1);
+                               $img->scaleImage(10);
                                $img_str = $img->imageString();
                        }
                //} else if (substr($img_str, 0, 6) == "GIF89a") {
@@ -319,13 +329,11 @@ function privacy_image_cache_cron(&$a = null, &$b = null) {
 
     logger("Purging old Cache of the Privacy Image Cache", LOGGER_DEBUG);
     q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
-    set_config('pi_cache', 'last_delete', $time);
 
     clear_cache($a->get_basepath(), $a->get_basepath()."/privacy_image_cache");
-}
-
-
 
+    set_config('pi_cache', 'last_delete', $time);
+}
 
 /**
  * @param App $a
@@ -372,3 +380,22 @@ function privacy_image_cache_plugin_admin_post(&$a = null, &$o = null){
         q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%"');
     }
 }
+
+function privacy_image_cache_parse_query($var) {
+       /**
+        *  Use this function to parse out the query array element from
+        *  the output of parse_url().
+       */
+       $var  = parse_url($var, PHP_URL_QUERY);
+       $var  = html_entity_decode($var);
+       $var  = explode('&', $var);
+       $arr  = array();
+
+       foreach($var as $val) {
+               $x          = explode('=', $val);
+               $arr[$x[0]] = $x[1];
+       }
+
+       unset($val, $x, $var);
+       return $arr;
+}
diff --git a/procrunner.tgz b/procrunner.tgz
new file mode 100644 (file)
index 0000000..fec9dfa
Binary files /dev/null and b/procrunner.tgz differ
diff --git a/procrunner/procrunner.php b/procrunner/procrunner.php
new file mode 100755 (executable)
index 0000000..4c6f64b
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Name: Proc Runner
+ * Description: Derivative of poormancron when proc_open() and exec() are disabled
+ * Version: 1.0
+ * Author: Fabio Comuni <http://kirgroup.com/profile/fabrix>
+ * Author: Mike Macgirvin
+ */
+
+function procrunner_install() {
+
+       $addons = get_config('system','addon');
+       if(strstr('poormancron',$addons)) {
+               logger('procrunner incompatible with poormancron. Not installing procrunner.');
+               return;
+       }
+
+       // check for command line php
+       $a = get_app();
+       $ex = Array();
+       $ex[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
+       $ex[1] = dirname(dirname(dirname(__file__)))."/testargs.php";
+       $ex[2] = "test";
+       $out = exec(implode(" ", $ex));
+       if ($out==="test") {
+               logger('procrunner not required on this system. Not installing.');
+               return;
+       } else {
+               register_hook('proc_run', 'addon/procrunner/procrunner.php','procrunner_procrun');
+               logger("installed procrunner");
+       }
+       
+}
+
+function procrunner_uninstall() {
+       unregister_hook('proc_run', 'addon/procrunner/procrunner.php','procrunner_procrun');
+       logger("removed procrunner");
+}
+
+
+
+function procrunner_procrun(&$a, &$arr) {
+
+       $argv = $arr['args'];
+       $arr['run_cmd'] = false;
+       logger("procrunner procrun ".implode(", ",$argv));
+       array_shift($argv);
+       $argc = count($argv);
+       logger("procrunner procrun require_once ".basename($argv[0]));
+       require_once(basename($argv[0]));
+       $funcname=str_replace(".php", "", basename($argv[0]))."_run";  
+       $funcname($argv, $argc);
+}
index 9801af556eb6fd101242b0ae00ae0ffd1ec39967..ea19ef18e6b4d640896c428ea01bf121671f403d 100755 (executable)
Binary files a/statusnet.tgz and b/statusnet.tgz differ
index 4781fcc2558c235f0306990c0e4c9a90bf91ab29..f3678c805b6b157f83a531db2a8779f81b7b93ac 100755 (executable)
@@ -30,6 +30,8 @@
  * Thank you guys for the Twitter compatible API!
  */
 
+define('STATUSNET_DEFAULT_POLL_INTERVAL', 5); // given in minutes
+
 require_once('library/twitteroauth.php');
 
 class StatusNetOAuth extends TwitterOAuth {
@@ -104,6 +106,7 @@ function statusnet_install() {
        register_hook('notifier_normal', 'addon/statusnet/statusnet.php', 'statusnet_post_hook');
        register_hook('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local');
        register_hook('jot_networks',    'addon/statusnet/statusnet.php', 'statusnet_jot_nets');
+       register_hook('cron', 'addon/statusnet/statusnet.php', 'statusnet_cron');
        logger("installed statusnet");
 }
 
@@ -114,6 +117,7 @@ function statusnet_uninstall() {
        unregister_hook('notifier_normal', 'addon/statusnet/statusnet.php', 'statusnet_post_hook');
        unregister_hook('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local');
        unregister_hook('jot_networks',    'addon/statusnet/statusnet.php', 'statusnet_jot_nets');
+       unregister_hook('cron', 'addon/statusnet/statusnet.php', 'statusnet_cron');
 
        // old setting - remove only
        unregister_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook');
@@ -131,13 +135,10 @@ function statusnet_jot_nets(&$a,&$b) {
                $statusnet_defpost = get_pconfig(local_user(),'statusnet','post_by_default');
                $selected = ((intval($statusnet_defpost) == 1) ? ' checked="checked" ' : '');
                $b .= '<div class="profile-jot-net"><input type="checkbox" name="statusnet_enable"' . $selected . ' value="1" /> ' 
-                       . t('Post to StatusNet') . '</div>';    
+                       . t('Post to StatusNet') . '</div>';
        }
 }
 
-
-
-
 function statusnet_settings_post ($a,$post) {
        if(! local_user())
            return;
@@ -148,14 +149,17 @@ function statusnet_settings_post ($a,$post) {
             /***
              * if the statusnet-disconnect checkbox is set, clear the statusnet configuration
              */
-            del_pconfig( local_user(), 'statusnet', 'consumerkey'  );
-            del_pconfig( local_user(), 'statusnet', 'consumersecret' );
-            del_pconfig( local_user(), 'statusnet', 'post' );
-            del_pconfig( local_user(), 'statusnet', 'post_by_default' );
-            del_pconfig( local_user(), 'statusnet', 'oauthtoken' );
-            del_pconfig( local_user(), 'statusnet', 'oauthsecret' );
-            del_pconfig( local_user(), 'statusnet', 'baseapi' );
-            del_pconfig( local_user(), 'statusnet', 'post_taglinks');
+            del_pconfig(local_user(), 'statusnet', 'consumerkey');
+            del_pconfig(local_user(), 'statusnet', 'consumersecret');
+            del_pconfig(local_user(), 'statusnet', 'post');
+            del_pconfig(local_user(), 'statusnet', 'post_by_default');
+            del_pconfig(local_user(), 'statusnet', 'oauthtoken');
+            del_pconfig(local_user(), 'statusnet', 'oauthsecret');
+            del_pconfig(local_user(), 'statusnet', 'baseapi');
+            del_pconfig(local_user(), 'statusnet', 'post_taglinks');
+            del_pconfig(local_user(), 'statusnet', 'lastid');
+            del_pconfig(local_user(), 'statusnet', 'mirror_posts');
+            del_pconfig(local_user(), 'statusnet', 'intelligent_shortening');
        } else {
             if (isset($_POST['statusnet-preconf-apiurl'])) {
                 /***
@@ -229,6 +233,8 @@ function statusnet_settings_post ($a,$post) {
                                        set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable']));
                                         set_pconfig(local_user(),'statusnet','post_by_default',intval($_POST['statusnet-default']));
                                         set_pconfig(local_user(),'statusnet','post_taglinks',intval($_POST['statusnet-sendtaglinks']));
+                                       set_pconfig(local_user(), 'statusnet', 'mirror_posts', intval($_POST['statusnet-mirror']));
+                                       set_pconfig(local_user(), 'statusnet', 'intelligent_shortening', intval($_POST['statusnet-shortening']));
                                        info( t('StatusNet settings updated.') . EOL);
                }}}}
 }
@@ -253,6 +259,12 @@ function statusnet_settings(&$a,&$s) {
         $defchecked = (($defenabled) ? ' checked="checked" ' : '');
         $linksenabled = get_pconfig(local_user(),'statusnet','post_taglinks');
         $linkschecked = (($linksenabled) ? ' checked="checked" ' : '');
+
+       $mirrorenabled = get_pconfig(local_user(),'statusnet','mirror_posts');
+       $mirrorchecked = (($mirrorenabled) ? ' checked="checked" ' : '');
+       $shorteningenabled = get_pconfig(local_user(),'statusnet','intelligent_shortening');
+       $shorteningchecked = (($shorteningenabled) ? ' checked="checked" ' : '');
+
        $s .= '<div class="settings-block">';
        $s .= '<h3>'. t('StatusNet Posting Settings').'</h3>';
 
@@ -342,6 +354,15 @@ function statusnet_settings(&$a,&$s) {
                        $s .= '<label id="statusnet-default-label" for="statusnet-default">'. t('Send public postings to StatusNet by default') .'</label>';
                        $s .= '<input id="statusnet-default" type="checkbox" name="statusnet-default" value="1" ' . $defchecked . '/>';
                        $s .= '<div class="clear"></div>';
+
+                       $s .= '<label id="statusnet-mirror-label" for="statusnet-mirror">'.t('Mirror all posts from statusnet that are no replies or repeated messages').'</label>';
+                       $s .= '<input id="statusnet-mirror" type="checkbox" name="statusnet-mirror" value="1" '. $mirrorchecked . '/>';
+                       $s .= '<div class="clear"></div>';
+
+                       $s .= '<label id="statusnet-shortening-label" for="statusnet-shortening">'.t('Shortening method that optimizes the post').'</label>';
+                       $s .= '<input id="statusnet-shortening" type="checkbox" name="statusnet-shortening" value="1" '. $shorteningchecked . '/>';
+                       $s .= '<div class="clear"></div>';
+
                         $s .= '<label id="statusnet-sendtaglinks-label" for="statusnet-sendtaglinks">'.t('Send linked #-tags and @-names to StatusNet').'</label>';
                         $s .= '<input id="statusnet-sendtaglinks" type="checkbox" name="statusnet-sendtaglinks" value="1" '. $linkschecked . '/>';
                        $s .= '</div><div class="clear"></div>';
@@ -427,6 +448,24 @@ function statusnet_shortenmsg($b, $max_char) {
        if ($b["title"] != "")
                $body = $b["title"]."\n\n".$body;
 
+       if (strpos($body, "[bookmark") !== false) {
+               // splitting the text in two parts:
+               // before and after the bookmark
+               $pos = strpos($body, "[bookmark");
+               $body1 = substr($body, 0, $pos);
+               $body2 = substr($body, $pos);
+
+               // Removing all quotes after the bookmark
+               // they are mostly only the content after the bookmark.
+               $body2 = preg_replace("/\[quote\=([^\]]*)\](.*?)\[\/quote\]/ism",'',$body2);
+               $body2 = preg_replace("/\[quote\](.*?)\[\/quote\]/ism",'',$body2);
+               $body = $body1.$body2;
+       }
+
+       // Add some newlines so that the message could be cut better
+       $body = str_replace(array("[quote", "[bookmark", "[/bookmark]", "[/quote]"),
+                               array("\n[quote", "\n[bookmark", "[/bookmark]\n", "[/quote]\n"), $body);
+
        // remove the recycle signs and the names since they aren't helpful on twitter
        // recycle 1
        $recycle = html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
@@ -523,20 +562,31 @@ function statusnet_post_hook(&$a,&$b) {
        if(! strstr($b['postopts'],'statusnet'))
                return;
 
+       // if posts comes from statusnet don't send it back
+       if($b['app'] == "StatusNet")
+               return;
+
+        logger('statusnet post invoked');
+
        load_pconfig($b['uid'], 'statusnet');
-            
+
        $api     = get_pconfig($b['uid'], 'statusnet', 'baseapi');
-       $ckey    = get_pconfig($b['uid'], 'statusnet', 'consumerkey'  );
-       $csecret = get_pconfig($b['uid'], 'statusnet', 'consumersecret' );
-       $otoken  = get_pconfig($b['uid'], 'statusnet', 'oauthtoken'  );
-       $osecret = get_pconfig($b['uid'], 'statusnet', 'oauthsecret' );
+       $ckey    = get_pconfig($b['uid'], 'statusnet', 'consumerkey');
+       $csecret = get_pconfig($b['uid'], 'statusnet', 'consumersecret');
+       $otoken  = get_pconfig($b['uid'], 'statusnet', 'oauthtoken');
+       $osecret = get_pconfig($b['uid'], 'statusnet', 'oauthsecret');
+       $intelligent_shortening = get_pconfig($b['uid'], 'statusnet', 'intelligent_shortening');
+
+       // Global setting overrides this
+       if (get_config('statusnet','intelligent_shortening'))
+               $intelligent_shortening = get_config('statusnet','intelligent_shortening');
 
        if($ckey && $csecret && $otoken && $osecret) {
 
                require_once('include/bbcode.php');
                $dent = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret);
                 $max_char = $dent->get_maxlength(); // max. length for a dent
-                // we will only work with up to two times the length of the dent 
+                // we will only work with up to two times the length of the dent
                 // we can later send to StatusNet. This way we can "gain" some
                 // information during shortening of potential links but do not
                 // shorten all the links in a 200000 character long essay.
@@ -697,14 +747,113 @@ function statusnet_plugin_admin(&$a, &$o){
                'key' => Array("key[$id]", t("Consumer Key"), "", ""),
        );
 
-       
        $t = get_markup_template( "admin.tpl", "addon/statusnet/" );
        $o = replace_macros($t, array(
                '$submit' => t('Submit'),
-                                                       
                '$sites' => $sitesform,
-               
        ));
-       
-       
 }
+
+function statusnet_cron($a,$b) {
+       $last = get_config('statusnet','last_poll');
+
+       $poll_interval = intval(get_config('statusnet','poll_interval'));
+       if(! $poll_interval)
+               $poll_interval = STATUSNET_DEFAULT_POLL_INTERVAL;
+
+       if($last) {
+               $next = $last + ($poll_interval * 60);
+               if($next > time()) {
+                       logger('statusnet: poll intervall not reached');
+                       return;
+               }
+       }
+       logger('statusnet: cron_start');
+
+       $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'statusnet' AND `k` = 'mirror_posts' AND `v` = '1' ORDER BY RAND() ");
+       if(count($r)) {
+               foreach($r as $rr) {
+                       logger('statusnet: fetching for user '.$rr['uid']);
+                       statusnet_fetchtimeline($a, $rr['uid']);
+               }
+       }
+
+       logger('statusnet: cron_end');
+
+       set_config('statusnet','last_poll', time());
+}
+
+function statusnet_fetchtimeline($a, $uid) {
+       $ckey    = get_pconfig($uid, 'statusnet', 'consumerkey');
+       $csecret = get_pconfig($uid, 'statusnet', 'consumersecret');
+       $api     = get_pconfig($uid, 'statusnet', 'baseapi');
+       $otoken  = get_pconfig($uid, 'statusnet', 'oauthtoken');
+       $osecret = get_pconfig($uid, 'statusnet', 'oauthsecret');
+       $lastid  = get_pconfig($uid, 'statusnet', 'lastid');
+
+       $application_name  = get_config('statusnet', 'application_name');
+
+       if ($application_name == "")
+               $application_name = $a->get_hostname();
+
+       $connection = new StatusNetOAuth($api, $ckey,$csecret,$otoken,$osecret);
+
+       $parameters = array("exclude_replies" => true, "trim_user" => true, "contributor_details" => false, "include_rts" => false);
+
+       $first_time = ($lastid == "");
+
+       if ($lastid <> "")
+               $parameters["since_id"] = $lastid;
+
+       $items = $connection->get('statuses/user_timeline', $parameters);
+       $posts = array_reverse($items);
+
+       foreach ($posts as $post) {
+               if ($post->id > $lastid)
+                       $lastid = $post->id;
+
+               if ($first_time)
+                       continue;
+
+               if (is_object($post->retweeted_status))
+                       continue;
+
+               if ($post->in_reply_to_status_id != "")
+                       continue;
+
+               if (!strpos($post->source, $application_name)) {
+                       $_SESSION["authenticated"] = true;
+                       $_SESSION["uid"] = $uid;
+
+                       $_REQUEST["type"] = "wall";
+                       $_REQUEST["api_source"] = true;
+                       $_REQUEST["profile_uid"] = $uid;
+                       $_REQUEST["source"] = "StatusNet";
+
+                       //$_REQUEST["date"] = $post->created_at;
+
+                       $_REQUEST["body"] = $post->text;
+                       if (is_string($post->place->name))
+                               $_REQUEST["location"] = $post->place->name;
+
+                       if (is_string($post->place->full_name))
+                               $_REQUEST["location"] = $post->place->full_name;
+
+                       if (is_array($post->geo->coordinates))
+                               $_REQUEST["coord"] = $post->geo->coordinates[0]." ".$post->geo->coordinates[1];
+
+                       if (is_array($post->coordinates->coordinates))
+                               $_REQUEST["coord"] = $post->coordinates->coordinates[1]." ".$post->coordinates->coordinates[0];
+
+                       //print_r($_REQUEST);
+                       if ($_REQUEST["body"] != "") {
+                               logger('statusnet: posting for user '.$uid);
+
+                               require_once('mod/item.php');
+                               item_post($a);
+                       }
+               }
+       }
+       set_pconfig($uid, 'statusnet', 'lastid', $lastid);
+}
+
index 0505830c085659c6d51cff518f10849dc12e74f6..d86175b0dad7b7c5065285ecc235a4778f35acae 100755 (executable)
Binary files a/twitter.tgz and b/twitter.tgz differ
index 6cb2d9cd8a9ca934369d4f4f78162e61cce4edc6..88cf38588e3532a707180639e83b31095cadd870 100755 (executable)
@@ -36,6 +36,8 @@
  *     Documentation: http://diekershoff.homeunix.net/redmine/wiki/friendikaplugin/Twitter_Plugin
  */
 
+define('TWITTER_DEFAULT_POLL_INTERVAL', 5); // given in minutes
+
 function twitter_install() {
        //  we need some hooks, for the configuration and for sending tweets
        register_hook('connector_settings', 'addon/twitter/twitter.php', 'twitter_settings'); 
@@ -43,6 +45,7 @@ function twitter_install() {
        register_hook('post_local', 'addon/twitter/twitter.php', 'twitter_post_local');
        register_hook('notifier_normal', 'addon/twitter/twitter.php', 'twitter_post_hook');
        register_hook('jot_networks', 'addon/twitter/twitter.php', 'twitter_jot_nets');
+       register_hook('cron', 'addon/twitter/twitter.php', 'twitter_cron');
        logger("installed twitter");
 }
 
@@ -53,6 +56,7 @@ function twitter_uninstall() {
        unregister_hook('post_local', 'addon/twitter/twitter.php', 'twitter_post_local');
        unregister_hook('notifier_normal', 'addon/twitter/twitter.php', 'twitter_post_hook');
        unregister_hook('jot_networks', 'addon/twitter/twitter.php', 'twitter_jot_nets');
+       unregister_hook('cron', 'addon/twitter/twitter.php', 'twitter_cron');
 
        // old setting - remove only
        unregister_hook('post_local_end', 'addon/twitter/twitter.php', 'twitter_post_hook');
@@ -70,10 +74,8 @@ function twitter_jot_nets(&$a,&$b) {
                $tw_defpost = get_pconfig(local_user(),'twitter','post_by_default');
                $selected = ((intval($tw_defpost) == 1) ? ' checked="checked" ' : '');
                $b .= '<div class="profile-jot-net"><input type="checkbox" name="twitter_enable"' . $selected . ' value="1" /> ' 
-                       . t('Post to Twitter') . '</div>';      
+                       . t('Post to Twitter') . '</div>';
        }
-
-
 }
 
 function twitter_settings_post ($a,$post) {
@@ -87,20 +89,23 @@ function twitter_settings_post ($a,$post) {
                 * if the twitter-disconnect checkbox is set, clear the OAuth key/secret pair
                 * from the user configuration
                 */
-               del_pconfig( local_user(), 'twitter', 'consumerkey'  );
-               del_pconfig( local_user(), 'twitter', 'consumersecret' );
-                del_pconfig( local_user(), 'twitter', 'oauthtoken'  );  
-                del_pconfig( local_user(), 'twitter', 'oauthsecret'  );  
-                del_pconfig( local_user(), 'twitter', 'post' );
-                del_pconfig( local_user(), 'twitter', 'post_by_default' );
-                del_pconfig( local_user(), 'twitter', 'post_taglinks');
+               del_pconfig(local_user(), 'twitter', 'consumerkey');
+               del_pconfig(local_user(), 'twitter', 'consumersecret');
+                del_pconfig(local_user(), 'twitter', 'oauthtoken');
+                del_pconfig(local_user(), 'twitter', 'oauthsecret');
+                del_pconfig(local_user(), 'twitter', 'post');
+                del_pconfig(local_user(), 'twitter', 'post_by_default');
+                del_pconfig(local_user(), 'twitter', 'post_taglinks');
+               del_pconfig(local_user(), 'twitter', 'lastid');
+               del_pconfig(local_user(), 'twitter', 'mirror_posts');
+               del_pconfig(local_user(), 'twitter', 'intelligent_shortening');
        } else {
        if (isset($_POST['twitter-pin'])) {
                //  if the user supplied us with a PIN from Twitter, let the magic of OAuth happen
                logger('got a Twitter PIN');
                require_once('library/twitteroauth.php');
-               $ckey    = get_config('twitter', 'consumerkey'  );
-               $csecret = get_config('twitter', 'consumersecret' );
+               $ckey    = get_config('twitter', 'consumerkey');
+               $csecret = get_config('twitter', 'consumersecret');
                //  the token and secret for which the PIN was generated were hidden in the settings
                //  form as token and token2, we need a new connection to Twitter using these token
                //  and secret to request a Access Token with the PIN
@@ -119,6 +124,8 @@ function twitter_settings_post ($a,$post) {
                set_pconfig(local_user(),'twitter','post',intval($_POST['twitter-enable']));
                 set_pconfig(local_user(),'twitter','post_by_default',intval($_POST['twitter-default']));
                 set_pconfig(local_user(),'twitter','post_taglinks',intval($_POST['twitter-sendtaglinks']));
+               set_pconfig(local_user(), 'twitter', 'mirror_posts', intval($_POST['twitter-mirror']));
+               set_pconfig(local_user(), 'twitter', 'intelligent_shortening', intval($_POST['twitter-shortening']));
                 info( t('Twitter settings updated.') . EOL);
        }}
 }
@@ -141,6 +148,10 @@ function twitter_settings(&$a,&$s) {
        $defchecked = (($defenabled) ? ' checked="checked" ' : '');
         $linksenabled = get_pconfig(local_user(),'twitter','post_taglinks');
         $linkschecked = (($linksenabled) ? ' checked="checked" ' : '');
+        $mirrorenabled = get_pconfig(local_user(),'twitter','mirror_posts');
+        $mirrorchecked = (($mirrorenabled) ? ' checked="checked" ' : '');
+        $shorteningenabled = get_pconfig(local_user(),'twitter','intelligent_shortening');
+        $shorteningchecked = (($shorteningenabled) ? ' checked="checked" ' : '');
 
        $s .= '<div class="settings-block">';
        $s .= '<h3>'. t('Twitter Posting Settings') .'</h3>';
@@ -198,6 +209,15 @@ function twitter_settings(&$a,&$s) {
                         $s .= '<label id="twitter-default-label" for="twitter-default">'. t('Send public postings to Twitter by default') .'</label>';
                         $s .= '<input id="twitter-default" type="checkbox" name="twitter-default" value="1" ' . $defchecked . '/>';
                        $s .= '<div class="clear"></div>';
+
+                        $s .= '<label id="twitter-mirror-label" for="twitter-mirror">'.t('Mirror all posts from twitter that are no replies or retweets').'</label>';
+                        $s .= '<input id="twitter-mirror" type="checkbox" name="twitter-mirror" value="1" '. $mirrorchecked . '/>';
+                       $s .= '<div class="clear"></div>';
+
+                        $s .= '<label id="twitter-shortening-label" for="twitter-shortening">'.t('Shortening method that optimizes the tweet').'</label>';
+                        $s .= '<input id="twitter-shortening" type="checkbox" name="twitter-shortening" value="1" '. $shorteningchecked . '/>';
+                       $s .= '<div class="clear"></div>';
+
                         $s .= '<label id="twitter-sendtaglinks-label" for="twitter-sendtaglinks">'.t('Send linked #-tags and @-names to Twitter').'</label>';
                         $s .= '<input id="twitter-sendtaglinks" type="checkbox" name="twitter-sendtaglinks" value="1" '. $linkschecked . '/>';
                        $s .= '</div><div class="clear"></div>';
@@ -286,6 +306,24 @@ function twitter_shortenmsg($b) {
        if ($b["title"] != "")
                $body = $b["title"]."\n\n".$body;
 
+       if (strpos($body, "[bookmark") !== false) {
+               // splitting the text in two parts:
+               // before and after the bookmark
+               $pos = strpos($body, "[bookmark");
+               $body1 = substr($body, 0, $pos);
+               $body2 = substr($body, $pos);
+
+               // Removing all quotes after the bookmark
+               // they are mostly only the content after the bookmark.
+               $body2 = preg_replace("/\[quote\=([^\]]*)\](.*?)\[\/quote\]/ism",'',$body2);
+               $body2 = preg_replace("/\[quote\](.*?)\[\/quote\]/ism",'',$body2);
+               $body = $body1.$body2;
+       }
+
+       // Add some newlines so that the message could be cut better
+       $body = str_replace(array("[quote", "[bookmark", "[/bookmark]", "[/quote]"),
+                       array("\n[quote", "\n[bookmark", "[/bookmark]\n", "[/quote]\n"), $body);
+
        // remove the recycle signs and the names since they aren't helpful on twitter
        // recycle 1
        $recycle = html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
@@ -385,15 +423,24 @@ function twitter_post_hook(&$a,&$b) {
        if($b['parent'] != $b['id'])
                return;
 
+       // if post comes from twitter don't send it back
+       if($b['app'] == "Twitter")
+               return;
+
        logger('twitter post invoked');
 
 
        load_pconfig($b['uid'], 'twitter');
 
-       $ckey    = get_config('twitter', 'consumerkey'  );
-       $csecret = get_config('twitter', 'consumersecret' );
-       $otoken  = get_pconfig($b['uid'], 'twitter', 'oauthtoken'  );
-       $osecret = get_pconfig($b['uid'], 'twitter', 'oauthsecret' );
+       $ckey    = get_config('twitter', 'consumerkey');
+       $csecret = get_config('twitter', 'consumersecret');
+       $otoken  = get_pconfig($b['uid'], 'twitter', 'oauthtoken');
+       $osecret = get_pconfig($b['uid'], 'twitter', 'oauthsecret');
+       $intelligent_shortening = get_pconfig($b['uid'], 'twitter', 'intelligent_shortening');
+
+       // Global setting overrides this
+       if (get_config('twitter','intelligent_shortening'))
+                $intelligent_shortening = get_config('twitter','intelligent_shortening');
 
        if($ckey && $csecret && $otoken && $osecret) {
                logger('twitter: we have customer key and oauth stuff, going to send.', LOGGER_DEBUG);
@@ -403,9 +450,6 @@ function twitter_post_hook(&$a,&$b) {
                $tweet = new TwitterOAuth($ckey,$csecret,$otoken,$osecret);
                 // in theory max char is 140 but T. uses t.co to make links 
                 // longer so we give them 10 characters extra
-
-                $intelligent_shortening = get_config('twitter','intelligent_shortening');
-
                if (!$intelligent_shortening) {
                        $max_char = 130; // max. length for a tweet
                        // we will only work with up to two times the length of the dent 
@@ -506,15 +550,106 @@ function twitter_plugin_admin_post(&$a){
 function twitter_plugin_admin(&$a, &$o){
        $t = get_markup_template( "admin.tpl", "addon/twitter/" );
 
-       $includes = array(
-               '$field_input' => 'field_input.tpl',
-       );
-       $includes = set_template_includes($a->theme['template_engine'], $includes);
-
-       $o = replace_macros($t, $includes + array(
+       $o = replace_macros($t, array(
                '$submit' => t('Submit'),
                                                                // name, label, value, help, [extra values]
                '$consumerkey' => array('consumerkey', t('Consumer key'),  get_config('twitter', 'consumerkey' ), ''),
                '$consumersecret' => array('consumersecret', t('Consumer secret'),  get_config('twitter', 'consumersecret' ), '')
        ));
 }
+
+function twitter_cron($a,$b) {
+       $last = get_config('twitter','last_poll');
+
+       $poll_interval = intval(get_config('twitter','poll_interval'));
+       if(! $poll_interval)
+               $poll_interval = TWITTER_DEFAULT_POLL_INTERVAL;
+
+       if($last) {
+               $next = $last + ($poll_interval * 60);
+               if($next > time()) {
+                       logger('twitter: poll intervall not reached');
+                       return;
+               }
+       }
+       logger('twitter: cron_start');
+
+       $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'twitter' AND `k` = 'mirror_posts' AND `v` = '1' ORDER BY RAND() ");
+       if(count($r)) {
+               foreach($r as $rr) {
+                       logger('twitter: fetching for user '.$rr['uid']);
+                       twitter_fetchtimeline($a, $rr['uid']);
+               }
+       }
+
+       logger('twitter: cron_end');
+
+       set_config('twitter','last_poll', time());
+}
+
+function twitter_fetchtimeline($a, $uid) {
+       $ckey    = get_config('twitter', 'consumerkey');
+       $csecret = get_config('twitter', 'consumersecret');
+       $otoken  = get_pconfig($uid, 'twitter', 'oauthtoken');
+       $osecret = get_pconfig($uid, 'twitter', 'oauthsecret');
+       $lastid  = get_pconfig($uid, 'twitter', 'lastid');
+
+       $application_name  = get_config('twitter', 'application_name');
+
+       if ($application_name == "")
+               $application_name = $a->get_hostname();
+
+       require_once('library/twitteroauth.php');
+       $connection = new TwitterOAuth($ckey,$csecret,$otoken,$osecret);
+
+       $parameters = array("exclude_replies" => true, "trim_user" => true, "contributor_details" => false, "include_rts" => false);
+
+       $first_time = ($lastid == "");
+
+       if ($lastid <> "")
+               $parameters["since_id"] = $lastid;
+
+       $items = $connection->get('statuses/user_timeline', $parameters);
+       $posts = array_reverse($items);
+
+       foreach ($posts as $post) {
+               if ($post->id_str > $lastid)
+                       $lastid = $post->id_str;
+
+               if ($first_time)
+                       continue;
+
+               if (!strpos($post->source, $application_name)) {
+                       $_SESSION["authenticated"] = true;
+                       $_SESSION["uid"] = $uid;
+
+                       $_REQUEST["type"] = "wall";
+                       $_REQUEST["api_source"] = true;
+                       $_REQUEST["profile_uid"] = $uid;
+                       $_REQUEST["source"] = "Twitter";
+
+                       //$_REQUEST["date"] = $post->created_at;
+
+                       $_REQUEST["body"] = $post->text;
+                       if (is_string($post->place->name))
+                               $_REQUEST["location"] = $post->place->name;
+
+                       if (is_string($post->place->full_name))
+                               $_REQUEST["location"] = $post->place->full_name;
+
+                       if (is_array($post->geo->coordinates))
+                               $_REQUEST["coord"] = $post->geo->coordinates[0]." ".$post->geo->coordinates[1];
+
+                       if (is_array($post->coordinates->coordinates))
+                               $_REQUEST["coord"] = $post->coordinates->coordinates[1]." ".$post->coordinates->coordinates[0];
+
+                       //print_r($_REQUEST);
+                       logger('twitter: posting for user '.$uid);
+
+                       require_once('mod/item.php');
+                       item_post($a);
+
+               }
+       }
+       set_pconfig($uid, 'twitter', 'lastid', $lastid);
+}