aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzottel <github@zottel.net>2015-09-03 12:51:08 +0200
committerzottel <github@zottel.net>2015-09-03 12:51:08 +0200
commit015c7243b9b688acda9c1defce9055fe2c3c2e61 (patch)
tree92dd58c4e5a1881b01acb414ea1d218d77ef4721
parentd376d2a5908241082f2e91349c9100d41054f5d0 (diff)
parentf3cb17ac3b007afd2dc5bf7cdad8a054b4d7fcd8 (diff)
downloadvolse-hubzilla-015c7243b9b688acda9c1defce9055fe2c3c2e61.tar.gz
volse-hubzilla-015c7243b9b688acda9c1defce9055fe2c3c2e61.tar.bz2
volse-hubzilla-015c7243b9b688acda9c1defce9055fe2c3c2e61.zip
Merge remote-tracking branch 'upstream/master'
Conflicts: include/zot.php
-rwxr-xr-xboot.php2
-rw-r--r--doc/credits.bb7
-rw-r--r--include/AccessList.php17
-rw-r--r--include/apps.php36
-rw-r--r--include/import.php380
-rw-r--r--include/text.php4
-rw-r--r--include/zot.php14
-rw-r--r--install/schema_mysql.sql6
-rw-r--r--install/schema_postgres.sql4
-rw-r--r--install/update.php26
-rw-r--r--mod/import.php234
-rw-r--r--mod/thing.php21
-rw-r--r--version.inc2
-rw-r--r--view/css/mod_apps.css12
-rw-r--r--view/tpl/app.tpl4
-rwxr-xr-xview/tpl/myapps.tpl2
16 files changed, 546 insertions, 225 deletions
diff --git a/boot.php b/boot.php
index 6ec679408..e7ed7dcee 100755
--- a/boot.php
+++ b/boot.php
@@ -50,7 +50,7 @@ define ( 'PLATFORM_NAME', 'hubzilla' );
define ( 'RED_VERSION', trim(file_get_contents('version.inc')) . 'H');
define ( 'ZOT_REVISION', 1 );
-define ( 'DB_UPDATE_VERSION', 1150 );
+define ( 'DB_UPDATE_VERSION', 1151 );
/**
* @brief Constant with a HTML line break.
diff --git a/doc/credits.bb b/doc/credits.bb
index 5459c7d7a..200f1fc85 100644
--- a/doc/credits.bb
+++ b/doc/credits.bb
@@ -1,5 +1,9 @@
[b]Credits[/b]
+Thanks to all who have helped and contributed to the project and its predecessors over the years. It is possible we missed in your name but this is unintentional. We also thank the community and its members for providing valuable input and without whom this entire effort would be meaningless.
+
+It is also worth acknowledging the contributions and solutions to problems which arose from discussions amongst members and developers of other somewhat related and competing projects; even if we have had our occasional disagreements.
+
Mike Macgirvin
Fabio Comuni
Simon L'nu
@@ -62,6 +66,7 @@ tonnerkiller
Antoine G
Christian Drechsler
Ludovic Grossard
+RedmatrixCanada
Stanislav Lechev [0xAF]
aweiher
bufalo1973
@@ -73,3 +78,5 @@ mycocham
ndurchx
pafcu
Simó Albert i Beltran
+Manuel Reva
+Manuel Jiménez Friaza
diff --git a/include/AccessList.php b/include/AccessList.php
index 46e66d33d..43f1de111 100644
--- a/include/AccessList.php
+++ b/include/AccessList.php
@@ -34,6 +34,11 @@ class AccessList {
return $this->explicit;
}
+ /**
+ * Set AccessList from strings such as those in already
+ * existing stored data items
+ */
+
function set($arr,$explicit = true) {
$this->allow_cid = $arr['allow_cid'];
$this->allow_gid = $arr['allow_gid'];
@@ -43,6 +48,12 @@ class AccessList {
$this->explicit = $explicit;
}
+ /**
+ * return an array consisting of the current
+ * access list components where the elements
+ * are directly storable.
+ */
+
function get() {
return array(
'allow_cid' => $this->allow_cid,
@@ -52,6 +63,12 @@ class AccessList {
);
}
+ /**
+ * Set AccessList from arrays, such as those provided by
+ * acl_selector(). For convenience, a string (or non-array) input is
+ * assumed to be a comma-separated list and auto-converted into an array.
+ */
+
function set_from_array($arr,$explicit = true) {
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
? $arr['contact_allow'] : explode(',',$arr['contact_allow']));
diff --git a/include/apps.php b/include/apps.php
index 7943bc927..661fc2163 100644
--- a/include/apps.php
+++ b/include/apps.php
@@ -264,18 +264,37 @@ function app_install($uid,$app) {
else
$x = app_store($app);
- if($x['success'])
- return $x['app_id'];
+ if($x['success']) {
+ $r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($x['app_id']),
+ intval($uid)
+ );
+ if($r)
+ build_sync_packet($uid,array('app' => $r[0]));
+ return $x['app_id'];
+ }
return false;
}
function app_destroy($uid,$app) {
+
+
if($uid && $app['guid']) {
+
+ $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+ $x[0]['app_deleted'] = 1;
+
+
$r = q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
+
+ build_sync_packet($uid,array('app' => $x));
}
}
@@ -342,7 +361,9 @@ function app_store($arr) {
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
- $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
+ $created = datetime_convert();
+
+ $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($darray['app_id']),
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
@@ -355,7 +376,9 @@ function app_store($arr) {
dbesc($darray['app_addr']),
dbesc($darray['app_price']),
dbesc($darray['app_page']),
- dbesc($darray['app_requires'])
+ dbesc($darray['app_requires']),
+ dbesc($created),
+ dbesc($created)
);
if($r) {
$ret['success'] = true;
@@ -393,7 +416,9 @@ function app_update($arr) {
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
- $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s' where app_id = '%s' and app_channel = %d",
+ $edited = datetime_convert();
+
+ $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s' where app_id = '%s' and app_channel = %d",
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
dbesc($darray['app_name']),
@@ -405,6 +430,7 @@ function app_update($arr) {
dbesc($darray['app_price']),
dbesc($darray['app_page']),
dbesc($darray['app_requires']),
+ dbesc($edited),
dbesc($darray['app_id']),
intval($darray['app_channel'])
);
diff --git a/include/import.php b/include/import.php
new file mode 100644
index 000000000..6ce572ea2
--- /dev/null
+++ b/include/import.php
@@ -0,0 +1,380 @@
+<?php
+
+
+function import_channel($channel) {
+
+ if(! array_key_exists('channel_system',$channel)) {
+ $channel['channel_system'] = (($channel['channel_pageflags'] & 0x1000) ? 1 : 0);
+ $channel['channel_removed'] = (($channel['channel_pageflags'] & 0x8000) ? 1 : 0);
+ }
+
+ $r = q("select * from channel where (channel_guid = '%s' or channel_hash = '%s' or channel_address = '%s' ) limit 1",
+ dbesc($channel['channel_guid']),
+ dbesc($channel['channel_hash']),
+ dbesc($channel['channel_address'])
+ );
+
+ // We should probably also verify the hash
+
+ if($r) {
+ if($r[0]['channel_guid'] === $channel['channel_guid'] || $r[0]['channel_hash'] === $channel['channel_hash']) {
+ logger('mod_import: duplicate channel. ', print_r($channel,true));
+ notice( t('Cannot create a duplicate channel identifier on this system. Import failed.') . EOL);
+ return false;
+ }
+ else {
+ // try at most ten times to generate a unique address.
+ $x = 0;
+ $found_unique = false;
+ do {
+ $tmp = $channel['channel_address'] . mt_rand(1000,9999);
+ $r = q("select * from channel where channel_address = '%s' limit 1",
+ dbesc($tmp)
+ );
+ if(! $r) {
+ $channel['channel_address'] = $tmp;
+ $found_unique = true;
+ break;
+ }
+ $x ++;
+ } while ($x < 10);
+ if(! $found_unique) {
+ logger('mod_import: duplicate channel. randomisation failed.', print_r($channel,true));
+ notice( t('Unable to create a unique channel address. Import failed.') . EOL);
+ return false;
+ }
+ }
+ }
+
+ unset($channel['channel_id']);
+ $channel['channel_account_id'] = get_account_id();
+ $channel['channel_primary'] = (($seize) ? 1 : 0);
+
+ dbesc_array($channel);
+
+ $r = dbq("INSERT INTO channel (`"
+ . implode("`, `", array_keys($channel))
+ . "`) VALUES ('"
+ . implode("', '", array_values($channel))
+ . "')"
+ );
+
+ if(! $r) {
+ logger('mod_import: channel clone failed. ', print_r($channel,true));
+ notice( t('Channel clone failed. Import failed.') . EOL);
+ return false;
+ }
+
+ $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
+ intval(get_account_id()),
+ $channel['channel_guid'] // Already dbesc'd
+ );
+ if(! $r) {
+ logger('mod_import: channel not found. ', print_r($channel,true));
+ notice( t('Cloned channel not found. Import failed.') . EOL);
+ return false;
+ }
+ // reset
+ $channel = $r[0];
+
+ set_default_login_identity(get_account_id(),$channel['channel_id'],false);
+ logger('import step 1');
+ $_SESSION['import_step'] = 1;
+ ref_session_write(session_id(), serialize($_SESSION));
+ return $channel;
+
+}
+
+function import_config($channel,$configs) {
+
+ if($channel && $configs) {
+ foreach($configs as $config) {
+ unset($config['id']);
+ $config['uid'] = $channel['channel_id'];
+ dbesc_array($config);
+ $r = dbq("INSERT INTO pconfig (`"
+ . implode("`, `", array_keys($config))
+ . "`) VALUES ('"
+ . implode("', '", array_values($config))
+ . "')" );
+ }
+ load_pconfig($channel['channel_id']);
+ }
+}
+
+
+function import_profiles($channel,$profiles) {
+
+ if($channel && $profiles) {
+ foreach($profiles as $profile) {
+ unset($profile['id']);
+ $profile['aid'] = get_account_id();
+ $profile['uid'] = $channel['channel_id'];
+
+ // we are going to reset all profile photos to the original
+ // somebody will have to fix this later and put all the applicable photos into the export
+
+ $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id'];
+ $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id'];
+
+ dbesc_array($profile);
+ $r = dbq("INSERT INTO profile (`"
+ . implode("`, `", array_keys($profile))
+ . "`) VALUES ('"
+ . implode("', '", array_values($profile))
+ . "')"
+ );
+ }
+ }
+}
+
+
+function import_hublocs($channel,$hublocs,$seize) {
+
+ if($channel && $hublocs) {
+ foreach($hublocs as $hubloc) {
+
+ $hash = make_xchan_hash($hubloc['hubloc_guid'],$hubloc['hubloc_guid_sig']);
+ if($hubloc['hubloc_network'] === 'zot' && $hash !== $hubloc['hubloc_hash']) {
+ logger('forged hubloc: ' . print_r($hubloc,true));
+ continue;
+ }
+
+ if(! array_key_exists('hubloc_primary',$hubloc)) {
+ $hubloc['hubloc_primary'] = (($hubloc['hubloc_flags'] & 0x0001) ? 1 : 0);
+ $hubloc['hubloc_orphancheck'] = (($hubloc['hubloc_flags'] & 0x0004) ? 1 : 0);
+ $hubloc['hubloc_error'] = (($hubloc['hubloc_status'] & 0x0003) ? 1 : 0);
+ $hubloc['hubloc_deleted'] = (($hubloc['hubloc_flags'] & 0x1000) ? 1 : 0);
+ }
+
+ $arr = array(
+ 'guid' => $hubloc['hubloc_guid'],
+ 'guid_sig' => $hubloc['hubloc_guid_sig'],
+ 'url' => $hubloc['hubloc_url'],
+ 'url_sig' => $hubloc['hubloc_url_sig']
+ );
+ if(($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize))
+ $hubloc['hubloc_primary'] = 0;
+
+ if(! zot_gethub($arr)) {
+ unset($hubloc['hubloc_id']);
+ dbesc_array($hubloc);
+
+ $r = dbq("INSERT INTO hubloc (`"
+ . implode("`, `", array_keys($hubloc))
+ . "`) VALUES ('"
+ . implode("', '", array_values($hubloc))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+function import_objs($channel,$objs) {
+
+ if($channel && $objs) {
+ foreach($objs as $obj) {
+
+ // if it's the old term format - too hard to support
+ if(! $obj['obj_created'])
+ continue;
+
+ $baseurl = $obj['obj_baseurl'];
+ unset($obj['obj_id']);
+ unset($obj['obj_baseurl']);
+
+ $obj['obj_channel'] = $channel['channel_id'];
+
+ if($baseurl && (strpos($obj['obj_url'],$baseurl . '/thing/') !== false)) {
+ $obj['obj_url'] = str_replace($baseurl,z_root(),$obj['obj_url']);
+ }
+
+ if($obj['obj_imgurl']) {
+ $x = import_xchan_photo($obj['obj_imgurl'],$channel['channel_hash'],true);
+ $obj['obj_imgurl'] = $x[0];
+ }
+
+ dbesc_array($obj);
+
+ $r = dbq("INSERT INTO obj (`"
+ . implode("`, `", array_keys($obj))
+ . "`) VALUES ('"
+ . implode("', '", array_values($obj))
+ . "')"
+ );
+ }
+ }
+}
+
+function sync_objs($channel,$objs) {
+
+ if($channel && $objs) {
+ foreach($objs as $obj) {
+
+ if(array_key_exists('obj_deleted',$obj) && $obj['obj_deleted'] && $obj['obj_obj']) {
+ q("delete from obj where obj_obj = '%s' and obj_channel = %d limit 1",
+ dbesc($obj['obj_obj']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ // if it's the old term format - too hard to support
+ if(! $obj['obj_created'])
+ continue;
+
+ $baseurl = $obj['obj_baseurl'];
+ unset($obj['obj_id']);
+ unset($obj['obj_baseurl']);
+
+ $obj['obj_channel'] = $channel['channel_id'];
+
+ if($baseurl && (strpos($obj['obj_url'],$baseurl . '/thing/') !== false)) {
+ $obj['obj_url'] = str_replace($baseurl,z_root(),$obj['obj_url']);
+ }
+
+ $exists = false;
+
+ $x = q("select * from obj where obj_obj = '%s' and obj_channel = %d limit 1",
+ dbesc($obj['obj_obj']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['obj_edited'] >= $obj['obj_edited'])
+ continue;
+
+ $exists = true;
+ }
+
+ if($obj['obj_imgurl']) {
+ $x = import_xchan_photo($obj['obj_imgurl'],$channel['channel_hash'],true);
+ $obj['obj_imgurl'] = $x[0];
+ }
+
+ $hash = $obj['obj_obj'];
+
+ if($exists) {
+ unset($obj['obj_obj']);
+ foreach($obj as $k => $v) {
+ $r = q("UPDATE obj SET `%s` = '%s' WHERE obj_obj = '%s' AND obj_channel = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($hash),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+
+ dbesc_array($obj);
+
+ $r = dbq("INSERT INTO obj (`"
+ . implode("`, `", array_keys($obj))
+ . "`) VALUES ('"
+ . implode("', '", array_values($obj))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+
+
+function import_apps($channel,$apps) {
+
+ if($channel && $apps) {
+ foreach($apps as $app) {
+
+ unset($app['id']);
+ unset($app['app_channel']);
+
+ $app['app_channel'] = $channel['channel_id'];
+
+ if($app['app_photo']) {
+ $x = import_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
+ $app['app_photo'] = $x[0];
+ }
+
+ dbesc_array($app);
+ $r = dbq("INSERT INTO app (`"
+ . implode("`, `", array_keys($app))
+ . "`) VALUES ('"
+ . implode("', '", array_values($app))
+ . "')"
+ );
+ }
+ }
+}
+
+
+
+function sync_apps($channel,$apps) {
+
+ if($channel && $apps) {
+ foreach($apps as $app) {
+
+ if(array_key_exists('app_deleted',$app) && $app['app_deleted'] && $app['app_id']) {
+ q("delete from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['app_id']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ unset($app['id']);
+ unset($app['app_channel']);
+
+ if(! $app['app_created'] || $app['app_created'] === NULL_DATE)
+ $app['app_created'] = datetime_convert();
+ if(! $app['app_edited'] || $app['app_edited'] === NULL_DATE)
+ $app['app_edited'] = datetime_convert();
+
+ $app['app_channel'] = $channel['channel_id'];
+
+ if($app['app_photo']) {
+ $x = import_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
+ $app['app_photo'] = $x[0];
+ }
+
+ $exists = false;
+
+ $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['app_id']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['app_edited'] >= $obj['app_edited'])
+ continue;
+ $exists = true;
+ }
+ $hash = $app['app_id'];
+
+ if($exists) {
+ unset($app['app_id']);
+ foreach($app as $k => $v) {
+ $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($hash),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+ dbesc_array($app);
+ $r = dbq("INSERT INTO app (`"
+ . implode("`, `", array_keys($app))
+ . "`) VALUES ('"
+ . implode("', '", array_values($app))
+ . "')"
+ );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/include/text.php b/include/text.php
index e4735ac48..4d9670806 100644
--- a/include/text.php
+++ b/include/text.php
@@ -72,10 +72,6 @@ function notags($string) {
// return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string));
}
-// use this on "body" or "content" input where angle chars shouldn't be removed,
-// and allow them to be safely displayed.
-
-
/**
* use this on "body" or "content" input where angle chars shouldn't be removed,
diff --git a/include/zot.php b/include/zot.php
index fb82c4873..fecaa7ad2 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -1637,11 +1637,9 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
}
}
-
- $ab = q("select * from abook where abook_channel = %d
- and abook_xchan = '%s'",
+ $ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
intval($channel['channel_id']),
- $arr['owner_xchan']
+ dbesc($arr['owner_xchan'])
);
$abook = (($ab) ? $ab[0] : null);
@@ -2843,6 +2841,8 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
*/
function process_channel_sync_delivery($sender, $arr, $deliveries) {
+ require_once('include/import.php');
+
/** @FIXME this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic. */
$result = array();
@@ -2875,6 +2875,12 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
}
}
+ if(array_key_exists('obj',$arr) && $arr['obj'])
+ sync_objs($channel,$arr['obj']);
+
+ if(array_key_exists('app',$arr) && $arr['app'])
+ sync_apps($channel,$arr['app']);
+
if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) {
if(array_key_exists('channel_page_flags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) {
$arr['channel']['channel_removed'] = (($arr['channel']['channel_pageflags'] & 0x8000) ? 1 : 0);
diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql
index d7d44a0a6..1793f89c2 100644
--- a/install/schema_mysql.sql
+++ b/install/schema_mysql.sql
@@ -108,6 +108,8 @@ CREATE TABLE IF NOT EXISTS `app` (
`app_price` char(255) NOT NULL DEFAULT '',
`app_page` char(255) NOT NULL DEFAULT '',
`app_requires` char(255) NOT NULL DEFAULT '',
+ `app_created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `app_edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `app_id` (`app_id`),
KEY `app_name` (`app_name`),
@@ -115,7 +117,9 @@ CREATE TABLE IF NOT EXISTS `app` (
KEY `app_photo` (`app_photo`),
KEY `app_version` (`app_version`),
KEY `app_channel` (`app_channel`),
- KEY `app_price` (`app_price`)
+ KEY `app_price` (`app_price`),
+ KEY `app_created` (`app_created`),
+ KEY `app_edited` (`app_edited`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `attach` (
diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql
index 4c307a7f0..d31c304eb 100644
--- a/install/schema_postgres.sql
+++ b/install/schema_postgres.sql
@@ -107,6 +107,8 @@ CREATE TABLE "app" (
"app_price" text NOT NULL DEFAULT '',
"app_page" text NOT NULL DEFAULT '',
"app_requires" text NOT NULL DEFAULT '',
+ "app_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
+ "app_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY ("id")
);
create index "app_id" on app ("app_id");
@@ -116,6 +118,8 @@ create index "app_photo" on app ("app_photo");
create index "app_version" on app ("app_version");
create index "app_channel" on app ("app_channel");
create index "app_price" on app ("app_price");
+create index "app_created" on app ("app_created");
+create index "app_edited" on app ("app_edited");
CREATE TABLE "attach" (
"id" serial NOT NULL,
"aid" bigint NOT NULL DEFAULT '0',
diff --git a/install/update.php b/install/update.php
index d0ea4d147..8e531b595 100644
--- a/install/update.php
+++ b/install/update.php
@@ -1,6 +1,6 @@
<?php
-define( 'UPDATE_VERSION' , 1150 );
+define( 'UPDATE_VERSION' , 1151 );
/**
*
@@ -1775,4 +1775,26 @@ function update_r1149() {
return UPDATE_SUCCESS;
return UPDATE_FAILED;
-} \ No newline at end of file
+}
+
+function update_r1150() {
+
+ if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
+ $r1 = q("ALTER TABLE app ADD app_created timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
+ ADD app_edited timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' ");
+ }
+ else {
+ $r1 = q("ALTER TABLE app ADD app_created DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ ADD app_edited DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ");
+ }
+
+ $r2 = q("create index app_created on app ( app_created ) ");
+ $r3 = q("create index app_edited on app ( app_edited ) ");
+
+ $r = $r1 && $r2 && $r3;
+ if($r)
+ return UPDATE_SUCCESS;
+ return UPDATE_FAILED;
+
+}
+
diff --git a/mod/import.php b/mod/import.php
index 0472abfcd..c2ed82a0a 100644
--- a/mod/import.php
+++ b/mod/import.php
@@ -6,6 +6,8 @@
require_once('include/Contact.php');
require_once('include/zot.php');
require_once('include/identity.php');
+require_once('include/import.php');
+
function import_post(&$a) {
@@ -118,118 +120,41 @@ function import_post(&$a) {
// import channel
if(array_key_exists('channel',$data)) {
- $channel = $data['channel'];
if($completed < 1) {
+ $channel = import_channel($data['channel']);
- if(! array_key_exists('channel_system',$channel)) {
- $channel['channel_system'] = (($channel['channel_pageflags'] & 0x1000) ? 1 : 0);
- $channel['channel_removed'] = (($channel['channel_pageflags'] & 0x8000) ? 1 : 0);
- }
-
- $r = q("select * from channel where (channel_guid = '%s' or channel_hash = '%s' or channel_address = '%s' ) limit 1",
- dbesc($channel['channel_guid']),
- dbesc($channel['channel_hash']),
- dbesc($channel['channel_address'])
- );
-
- // We should probably also verify the hash
-
- if($r) {
- if($r[0]['channel_guid'] === $channel['channel_guid'] || $r[0]['channel_hash'] === $channel['channel_hash']) {
- logger('mod_import: duplicate channel. ', print_r($channel,true));
- notice( t('Cannot create a duplicate channel identifier on this system. Import failed.') . EOL);
- return;
- }
- else {
- // try at most ten times to generate a unique address.
- $x = 0;
- $found_unique = false;
- do {
- $tmp = $channel['channel_address'] . mt_rand(1000,9999);
- $r = q("select * from channel where channel_address = '%s' limit 1",
- dbesc($tmp)
- );
- if(! $r) {
- $channel['channel_address'] = $tmp;
- $found_unique = true;
- break;
- }
- $x ++;
- } while ($x < 10);
- if(! $found_unique) {
- logger('mod_import: duplicate channel. randomisation failed.', print_r($channel,true));
- notice( t('Unable to create a unique channel address. Import failed.') . EOL);
- return;
- }
- }
- }
-
- unset($channel['channel_id']);
- $channel['channel_account_id'] = get_account_id();
- $channel['channel_primary'] = (($seize) ? 1 : 0);
-
- dbesc_array($channel);
-
- $r = dbq("INSERT INTO channel (`"
- . implode("`, `", array_keys($channel))
- . "`) VALUES ('"
- . implode("', '", array_values($channel))
- . "')" );
-
- if(! $r) {
- logger('mod_import: channel clone failed. ', print_r($channel,true));
- notice( t('Channel clone failed. Import failed.') . EOL);
- return;
- }
-
+ }
+ else {
$r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
intval(get_account_id()),
- $channel['channel_guid'] // Already dbesc'd
+ dbesc($channel['channel_guid'])
);
- if(! $r) {
- logger('mod_import: channel not found. ', print_r($channel,true));
- notice( t('Cloned channel not found. Import failed.') . EOL);
- return;
- }
- // reset
- $channel = $r[0];
-
- set_default_login_identity(get_account_id(),$channel['channel_id'],false);
- logger('import step 1');
- $_SESSION['import_step'] = 1;
- ref_session_write(session_id(), serialize($_SESSION));
+ if($r)
+ $channel = $r[0];
}
- }
- else {
- $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
- intval(get_account_id()),
- dbesc($channel['channel_guid'])
- );
- if($r)
- $channel = $r[0];
- else {
+ if(! $channel) {
logger('mod_import: channel not found. ', print_r($channel,true));
notice( t('Cloned channel not found. Import failed.') . EOL);
return;
}
}
- if($completed < 2) {
+ if(! $channel)
+ $channel = $a->get_channel();
+
+ if(! $channel) {
+ logger('mod_import: channel not found. ', print_r($channel,true));
+ notice( t('No channel. Import failed.') . EOL);
+ return;
+ }
- $configs = $data['config'];
- if($configs) {
- foreach($configs as $config) {
- unset($config['id']);
- $config['uid'] = $channel['channel_id'];
- dbesc_array($config);
- $r = dbq("INSERT INTO pconfig (`"
- . implode("`, `", array_keys($config))
- . "`) VALUES ('"
- . implode("', '", array_values($config))
- . "')" );
- }
+
+ if($completed < 2) {
+ if(is_array($data['config'])) {
+ import_config($channel,$data['config']);
}
+
logger('import step 2');
$_SESSION['import_step'] = 2;
ref_session_write(session_id(), serialize($_SESSION));
@@ -244,27 +169,9 @@ function import_post(&$a) {
import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],get_account_id(),$channel['channel_id']);
}
- $profiles = $data['profile'];
- if($profiles) {
- foreach($profiles as $profile) {
- unset($profile['id']);
- $profile['aid'] = get_account_id();
- $profile['uid'] = $channel['channel_id'];
-
- // we are going to reset all profile photos to the original
- // somebody will have to fix this later and put all the applicable photos into the export
-
- $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id'];
- $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id'];
+ if(is_array($data['profiles']))
+ import_profiles($channel,$data['profiles']);
- dbesc_array($profile);
- $r = dbq("INSERT INTO profile (`"
- . implode("`, `", array_keys($profile))
- . "`) VALUES ('"
- . implode("', '", array_values($profile))
- . "')" );
- }
- }
logger('import step 3');
$_SESSION['import_step'] = 3;
ref_session_write(session_id(), serialize($_SESSION));
@@ -272,43 +179,10 @@ function import_post(&$a) {
if($completed < 4) {
- $hublocs = $data['hubloc'];
- if($hublocs) {
- foreach($hublocs as $hubloc) {
- $hash = make_xchan_hash($hubloc['hubloc_guid'],$hubloc['hubloc_guid_sig']);
- if($hubloc['hubloc_network'] === 'zot' && $hash !== $hubloc['hubloc_hash']) {
- logger('forged hubloc: ' . print_r($hubloc,true));
- continue;
- }
+ if(is_array($data['hubloc'])) {
+ import_hublocs($channel,$data['hubloc'],$seize);
- if(! array_key_exists('hubloc_primary',$hubloc)) {
- $hubloc['hubloc_primary'] = (($hubloc['hubloc_flags'] & 0x0001) ? 1 : 0);
- $hubloc['hubloc_orphancheck'] = (($hubloc['hubloc_flags'] & 0x0004) ? 1 : 0);
- $hubloc['hubloc_error'] = (($hubloc['hubloc_status'] & 0x0003) ? 1 : 0);
- $hubloc['hubloc_deleted'] = (($hubloc['hubloc_flags'] & 0x1000) ? 1 : 0);
- }
-
- $arr = array(
- 'guid' => $hubloc['hubloc_guid'],
- 'guid_sig' => $hubloc['hubloc_guid_sig'],
- 'url' => $hubloc['hubloc_url'],
- 'url_sig' => $hubloc['hubloc_url_sig']
- );
- if(($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize))
- $hubloc['hubloc_primary'] = 0;
-
- if(! zot_gethub($arr)) {
- unset($hubloc['hubloc_id']);
- dbesc_array($hubloc);
-
- $r = dbq("INSERT INTO hubloc (`"
- . implode("`, `", array_keys($hubloc))
- . "`) VALUES ('"
- . implode("', '", array_values($hubloc))
- . "')" );
- }
- }
}
logger('import step 4');
$_SESSION['import_step'] = 4;
@@ -556,59 +430,11 @@ function import_post(&$a) {
ref_session_write(session_id(), serialize($_SESSION));
}
- $objs = $data['obj'];
- if($objs) {
- foreach($objs as $obj) {
- // if it's the old term format - too hard to support
- if(! $obj['obj_created'])
- continue;
- $baseurl = $obj['obj_baseurl'];
- unset($obj['obj_id']);
- unset($obj['obj_baseurl']);
-
- $obj['obj_channel'] = $channel['channel_id'];
-
- if($baseurl && (strpos($obj['obj_url'],$baseurl . '/thing/') !== false)) {
- $obj['obj_url'] = str_replace($baseurl,z_root(),$obj['obj_url']);
- }
-
- if($obj['obj_imgurl']) {
- $x = import_xchan_photo($obj['obj_imgurl'],get_observer_hash(),true);
- $obj['obj_imgurl'] = $x[0];
- }
-
- dbesc_array($obj);
- $r = dbq("INSERT INTO obj (`"
- . implode("`, `", array_keys($obj))
- . "`) VALUES ('"
- . implode("', '", array_values($obj))
- . "')" );
- }
- }
-
- $apps = $data['app'];
- if($app) {
- foreach($apps as $app) {
-
- unset($app['id']);
- unset($app['app_channel']);
-
- $app['app_channel'] = $channel['channel_id'];
-
- if($app['app_photo']) {
- $x = import_xchan_photo($app['app_photo'],get_observer_hash(),true);
- $app['app_photo'] = $x[0];
- }
-
- dbesc_array($app);
- $r = dbq("INSERT INTO app (`"
- . implode("`, `", array_keys($obj))
- . "`) VALUES ('"
- . implode("', '", array_values($obj))
- . "')" );
- }
- }
+ if(is_array($data['obj']))
+ import_objs($channel,$data['obj']);
+ if(is_array($data['app']))
+ import_apps($channel,$data['app']);
$saved_notification_flags = notifications_off($channel['channel_id']);
diff --git a/mod/thing.php b/mod/thing.php
index 86712d9eb..03dc7db5b 100644
--- a/mod/thing.php
+++ b/mod/thing.php
@@ -109,6 +109,15 @@ function thing_init(&$a) {
);
info( t('Thing updated') . EOL);
+
+ $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1",
+ intval(local_channel()),
+ dbesc($term_hash)
+ );
+ if($r) {
+ build_sync_packet(0, array('obj' => $r));
+ }
+
return;
}
@@ -157,6 +166,14 @@ function thing_init(&$a) {
info( t('Thing added'));
+ $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1",
+ intval(local_channel()),
+ dbesc($hash)
+ );
+ if($r) {
+ build_sync_packet(0, array('obj' => $r));
+ }
+
if($activity) {
$arr = array();
$links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $url));
@@ -310,6 +327,10 @@ function thing_content(&$a) {
intval(local_channel())
);
+ $r[0]['obj_deleted'] = 1;
+
+ build_sync_packet(0,array('obj' => $r));
+
return $o;
}
diff --git a/version.inc b/version.inc
index bfff44914..da2499cde 100644
--- a/version.inc
+++ b/version.inc
@@ -1 +1 @@
-2015-09-01.1142
+2015-09-02.1143
diff --git a/view/css/mod_apps.css b/view/css/mod_apps.css
index 5e98a6a18..cfaf5ef87 100644
--- a/view/css/mod_apps.css
+++ b/view/css/mod_apps.css
@@ -1,6 +1,16 @@
.app-container {
float: left;
width: 125px;
- height: 160px;
+ height: 180px;
padding: 20px;
}
+
+.app-detail {
+ height: 130px;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
+
+.app-tools {
+ margin-bottom: 0;
+}
diff --git a/view/tpl/app.tpl b/view/tpl/app.tpl
index cebc17d45..727be5eba 100644
--- a/view/tpl/app.tpl
+++ b/view/tpl/app.tpl
@@ -1,4 +1,5 @@
<div class="app-container">
+<div class="app-detail">
<a href="{{$app.url}}" {{if $ap.target}}target="{{$ap.target}}" {{/if}}{{if $app.desc}}title="{{$app.desc}}{{if $app.price}} ({{$app.price}}){{/if}}"{{else}}title="{{$app.name}}"{{/if}}><img src="{{$app.photo}}" width="80" height="80" />
<div class="app-name" style="text-align:center;">{{$app.name}}</div>
</a>
@@ -6,7 +7,9 @@
{{if $purchase}}
<a href="{{$app.page}}" class="btn btn-default" title="{{$purchase}}" ><i class="icon-external"></i></a>
{{/if}}
+</div>
{{if $install || $update || $delete }}
+<div class="app-tools">
<form action="{{$hosturl}}appman" method="post">
<input type="hidden" name="papp" value="{{$app.papp}}" />
{{if $install}}<button type="submit" name="install" value="{{$install}}" class="btn btn-default" title="{{$install}}" ><i class="icon-download-alt" ></i></button>{{/if}}
@@ -16,4 +19,5 @@
{{/if}}
{{/if}}
</div>
+</div>
diff --git a/view/tpl/myapps.tpl b/view/tpl/myapps.tpl
index 1a591f9f8..ccb995849 100755
--- a/view/tpl/myapps.tpl
+++ b/view/tpl/myapps.tpl
@@ -1,9 +1,7 @@
<h3>{{$title}}</h3>
{{foreach $apps as $ap}}
-<div class="app-container">
{{$ap}}
-</div>
{{/foreach}}
<div class="clear"></div>