diff --git a/README.md b/README.md index ac62f721a..9de6393b1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -Hubzilla -======== +Hubzilla - Community Server +=========================== -###Websites. Redefined. +Websites. Redefined. +-------------------- - -![Hubzilla](images/ghash-32.png) +![Hubzilla](images/hubzilla_house_arrows.png) **What are Hubs?** diff --git a/boot.php b/boot.php index e7ed7dcee..bc8baf818 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', 1151 ); +define ( 'DB_UPDATE_VERSION', 1152 ); /** * @brief Constant with a HTML line break. @@ -82,7 +82,7 @@ $DIRECTORY_FALLBACK_SERVERS = array( 'https://zotid.net', 'https://red.zottel.red', 'https://gravizot.de', - 'https://my.federated.social', + 'https://my.federated.social' ); diff --git a/doc/bugs.bb b/doc/bugs.bb new file mode 100644 index 000000000..1a27e66ba --- /dev/null +++ b/doc/bugs.bb @@ -0,0 +1,45 @@ +[h2]Bugs, Issues, and things that go bump in the night...[/h2] +[h3]Something went wrong! Who is charge of fixing it?[/h3] + +[b]Hubzilla Community Server[/b] + +Hubzilla Community Server is open source software which is maintained by "the community" - essentially unpaid volunteers. + +[b]Hubzilla Enterprise Server[/b] + +Hubzilla Enterprise Server is commercial software with a variety of support plans depending on the specific license terms. + + +The first thing you need to do is talk to your hub administrator - the person who runs and manages your site. They are in the unique position of having access to the internal software and database and [b]logfiles[/b] and will need to be involved in fixing your problem. Other people "on the net" can't really help with this. The first thing the hub administrator needs to do is look at their logs and/or try to reproduce the problem. So try to be as helpful and courteous as possible in helping them look into the problem. + +To find your hub administrator (if you don't know who they are) please look at [url=[baseurl]/siteinfo]this page[/url]. If they have not provided any contact info on that page or provided an "Impressum" there, see [url=[baseurl]/siteinfo/json]this site info summary[/url] under the heading "admin:". + +[h3]I'm a hub administrator; what do I do?[/h3] + +The software instructions which provide this server are open source and are available for your inspection. If an error message was reported, often one can do a search on the source files for that error message and find out what triggered it. With this information and the site logfiles it may be possible to figure out the sequence of events leading to the error. There could also be other sites involved, and the problem may not even be on your site but elsewhere in the network. Try to pin down the communication endpoints (hubs or sites) involved in the problem and contact the administrator of that site or those sites. Please try and provide an event time of when things went wrong so it can be found in the logs. Work with the other administrator(s) to try and find the cause of the problem. Logfiles are your friend. When something happens in the software that we didn't expect, it is nearly always logged. + +[h3]The white screen of death[/h3] + +If you get a blank white screen when doing something, this is almost always a code or syntax error. There are instructions in your .htconfig.php file for enabling syntax logging. We recommend all sites use this. With syntax logging enabled repeat the sequence which led to the error and it should log the offending line of code. Hopefully you will be able to fix the problem with this information. When you do, please submit the fix "upstream" so that we can share the fix with the rest of the project members and other communities. This is a key benefit of using open source software - we share with each other and everybody benefits. + +[h3]I'm stumped. I can't figure out what is wrong.[/h3] + +[b]Hubzilla Enterprise Server[/b] + +Please make contact with the vendor - who will have provided you with support contact details. Preferably this contact will be made by the hub administrator so that he/she can assist us in collecting the necessary issue details. We will assign a ticket and notify you of progress. + + +[b]Hubzilla Community Server[/b] + +At this point it might be worthwhile discussing the issue on one of the online forums. There may be several of these and some may be more suited to your spoken language. As a last resort, try "Channel One", which is in English. + +If the community developers can't help you right away, understand that they are volunteers and may have a lot of other work and demands on their time. At this point you need to file a bug report. You will need an account on github.com to do this. So register, and then visit https://github.com/redmatrix/hubzilla/issues +. Create an issue here and provide all the same information that you provided online. Don't leave out anything. + +Then you wait. If it's a high profile issue, it may get fixed quickly. But nobody is in charge of fixing bugs. If it lingers without resolution, please spend some more time investigating the problem. Ask about anything you don't understand related to the behaviour. You will learn more about how the software works and quite possibly figure out why it isn't working now. Ultimately it is somebody in the community who is going to fix this and you are a member of the community; and this is how the open source process works. + + +[b]In either case[/b] + +Other developers working to fix the problem may need to find out more, so do your homework and document what is happening and everything you've tried. Don't say "I did xyz and it didn't work." That doesn't tell us anything. Tell us precisely what steps you took and what you expected the result to be, and precisely what happened as a result. If there were any error messages, don't say "there was an error message". Tell us exactly what the message said. + \ No newline at end of file diff --git a/doc/dav_dolphin.bb b/doc/dav_dolphin.bb index a1ebba394..ae60a6d52 100644 --- a/doc/dav_dolphin.bb +++ b/doc/dav_dolphin.bb @@ -1,8 +1,8 @@ [b]Using The Cloud - Dolphin[/b] -Visit webdavs://example.com/cloud where "example.com" is the URL of your hub. +Visit webdavs://example.com/dav where "example.com" is the URL of your hub. -When prompted for a username and password, enter your username (the first part of your webbie - no @ or domain name) and password for your normal account. +When prompted for a username and password, enter your channel name (the first part of your webbie - no @ or domain name) and password for your normal account. Note, if you are already logged in to the web interface via Konqueror, you will not be prompted for further authentication. diff --git a/doc/dav_mount.bb b/doc/dav_mount.bb index d8cb2e08e..0fd3d4691 100644 --- a/doc/dav_mount.bb +++ b/doc/dav_mount.bb @@ -25,14 +25,14 @@ Edit /etc/fstab to include your cloud directory by adding [code] -[baseurl]/cloud/ /mount/point davfs user,noauto,uid=<DesktopUser>,file_mode=600,dir_mode=700 0 1 +[baseurl]/dav/ /mount/point davfs user,noauto,uid=<DesktopUser>,file_mode=600,dir_mode=700 0 1 [/code] Where [baseurl] is the URL of your hub, /mount/point is the location you want to mount the cloud, and <DesktopUser> is the user you log in to one your computer. Note that if you are mounting as a normal user (not root) the mount point must be in your home directory. For example, if I wanted to mount my cloud to a directory called 'cloud' in my home directory, and my username was bob, my fstab would be -[code][baseurl]/cloud/ /home/bob/cloud davfs user,noauto,uid=bob,file_mode=600,dir_mode=700 0 1[/code] +[code][baseurl]/dav/ /home/bob/cloud davfs user,noauto,uid=bob,file_mode=600,dir_mode=700 0 1[/code] Now, create the mount point. @@ -49,7 +49,7 @@ Create a file called 'secrets' and add your cloud login credentials [code] -[baseurl]/cloud <username> <password> +[baseurl]/dav <username> <password> [/code] Where <username> and <password> are the username and password [i]for your hub[/i]. @@ -60,7 +60,7 @@ Don't let this file be writeable by anyone who doesn't need it with Finally, mount the drive. -[code]mount [baseurl]/cloud[/code] +[code]mount [baseurl]/dav[/code] You can now find your cloud at /home/bob/cloud and use it as though it were part of your local filesystem - even if the applications you are using have no dav support themselves. diff --git a/doc/dav_nautilus.bb b/doc/dav_nautilus.bb index 51663b6de..c8911cda8 100644 --- a/doc/dav_nautilus.bb +++ b/doc/dav_nautilus.bb @@ -2,8 +2,8 @@ 1. Open a File browsing window (that's Nautilus) 2. Select File > Connect to server from the menu -3. Type davs://<domain_name>/cloud/<your_username> and click Connect -4. You will be prompted for your username (same as above) and password +3. Type davs://<domain_name>/dav/<your_channelname> and click Connect +4. You will be prompted for your channel name (same as above) and password 5. Your personal DAV directory will be shown in the window #include doc/macros/cloud_footer.bb; diff --git a/doc/dav_nemo.bb b/doc/dav_nemo.bb index 2c88b0782..f2d994fbb 100644 --- a/doc/dav_nemo.bb +++ b/doc/dav_nemo.bb @@ -3,16 +3,16 @@ For (file browser) Nemo 1.8.2 under Linux Mint 15, Cinnamon 1.8.8. Nemo ist the standard file browser there. 1st way -type "davs://yourusername@friendicared.net/cloud" in the address bar +type "davs://<domain_name>/dav/<your_channelname>" in the address bar. 2nd way Menu > file > connect to server Fill the dialog -- Server: friendicared.net +- Server: hubzilla_domain_name - Type: Secure WebDAV (https) -- Folder: /cloud -- Username: yourusername -- Passwort: yourpasswort +- Folder: /dav +- Username: yourchannelname +- Password: yourpassword Once open you can set a bookmark. diff --git a/doc/dav_windows.bb b/doc/dav_windows.bb index 0eaffd4d0..96862e2b5 100644 --- a/doc/dav_windows.bb +++ b/doc/dav_windows.bb @@ -4,8 +4,8 @@ RedDav using Windows 7 graphical user interface wizard: 1. Left-click the Start-button to open the start menu. 2. Right-click the My computer icon to access its menu. 3. Left-click Map network drive... to open the connection dialog wizard. -4. Type #^[url=https://example.net/cloud/your_user_name]https://example.net/cloud/your_user_name[/url] in the textbox and click the Complete button where "example.net" is the URL of your hub. -5. Type your Red account's user name. IMPORTANT - NO at-sign or domain name. -6. Type your Red password +4. Type #^[url=https://example.net/dav/your_channel_name]https://example.net/dav/your_channel_name[/url] in the textbox and click the Complete button where "example.net" is the URL of your hub. +5. Type your Hubzilla account's user name. IMPORTANT - NO at-sign or domain name. +6. Type your Hubzilla password #include doc/macros/cloud_footer.bb; diff --git a/doc/members.bb b/doc/members.bb index 705154b56..13339ef2d 100644 --- a/doc/members.bb +++ b/doc/members.bb @@ -22,3 +22,4 @@ [zrl=[baseurl]/help/addons]Help With Addons[/zrl] [zrl=[baseurl]/help/diaspora_compat]Diaspora Communications Compatibility (Diaspora and Friendica)[/zrl] [zrl=[baseurl]/help/faq_members]FAQ For Members[/zrl] +[zrl=[baseurl]/help/bugs]Bugs, Issues, and things that go bump in the night...[/zrl] diff --git a/doc/to_do_code.bb b/doc/to_do_code.bb index 94421bab0..b5c7b9903 100644 --- a/doc/to_do_code.bb +++ b/doc/to_do_code.bb @@ -4,7 +4,7 @@ We need much more than this, but here are areas where developers can help. Pleas [li]Documentation - see Red Documentation Project To-Do List[/li] [li]Include TOS link in registration/verification email[/li] -[li](done) forum widget with unread counts (requires the DB schema changes from v3/hubzilla to be viable)[/li] +[li]Auto preview posts/comments (configurable timer kicks in the preview if not 0)[/li] [li]Create bug tracker module[/li] [li]translation plugins - moses or apertium[/li] [li]plugins - provide 'disable' which is softer than 'uninstall' for those plugins which create additional DB tables[/li] @@ -45,7 +45,7 @@ We need much more than this, but here are areas where developers can help. Pleas [li]Create mobile clients for the top platforms - which involves extending the API so that we can do stuff far beyond the current crop of Twitter/Statusnet clients. Ditto for mobile themes. We can probably use something like the Friendica Android app as a base to start from.[/li] [li](in progress Habeas Codice) Implement owned and exchangeable "things".[/li] [li]Family Account creation - using service classes (an account holder can create a certain number of sub-accounts which are all tied to their subscription - if the subscription lapses they all go away).[/li] -[li]Put mod_admin under Comanche[/li] + In many cases some of the work has already been started and code exists so that you needn't start from scratch. Please contact one of the developer channels like Channel One (one@zothub.com) before embarking and we can tell you what we already have and provide some insights on how we envision these features fitting together. diff --git a/images/hubzilla_house_arrows.png b/images/hubzilla_house_arrows.png new file mode 100644 index 000000000..56402a96b Binary files /dev/null and b/images/hubzilla_house_arrows.png differ diff --git a/include/Import/import_diaspora.php b/include/Import/import_diaspora.php index fca9fa4f2..a0f473b50 100644 --- a/include/Import/import_diaspora.php +++ b/include/Import/import_diaspora.php @@ -57,6 +57,10 @@ function import_diaspora($data) { $channel_id = $c['channel']['channel_id']; + // Hubzilla only: Turn on the Diaspora protocol so that follow requests will be sent. + + set_pconfig($channel_id,'system','diaspora_allowed','1'); + // todo - add auto follow settings, (and strip exif in hubzilla) $location = escape_tags($data['user']['profile']['location']); @@ -70,7 +74,6 @@ function import_diaspora($data) { ); if($data['user']['profile']['nsfw']) { - // fixme for hubzilla which doesn't use pageflags any more q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d", intval(PAGE_ADULT), intval($channel_id) diff --git a/include/api.php b/include/api.php index 6d71cfc33..a77bf15f7 100644 --- a/include/api.php +++ b/include/api.php @@ -896,6 +896,55 @@ require_once('include/items.php'); api_register_func('api/red/item/new','red_item_new', true); + function red_item(&$a, $type) { + + if (api_user() === false) { + logger('api_red_item_new: no user'); + return false; + } + + if($_REQUEST['mid']) { + $arr = array('mid' => $_REQUEST['mid']); + } + elseif($_REQUEST['item_id']) { + $arr = array('item_id' => $_REQUEST['item_id']); + } + else + json_return_and_die(array()); + + $arr['start'] = 0; + $arr['records'] = 999999; + $arr['item_type'] = '*'; + + $i = items_fetch($arr,$a->get_channel(),get_observer_hash()); + + if(! $i) + json_return_and_die(array()); + + $ret = array(); + $tmp = array(); + $str = ''; + foreach($i as $ii) { + $tmp[] = encode_item($ii,true); + if($str) + $str .= ','; + $str .= $ii['id']; + } + $ret['item'] = $tmp; + if($str) { + $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item.id in ( $str ) "); + + if($r) + $ret['item_id'] = $r; + } + + json_return_and_die($ret); + } + + api_register_func('api/red/item/full','red_item', true); + + + function api_get_status($xchan_hash) { require_once('include/security.php'); diff --git a/include/attach.php b/include/attach.php index 620c7620c..513486bfc 100644 --- a/include/attach.php +++ b/include/attach.php @@ -405,6 +405,9 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { require_once('include/photos.php'); + + call_hooks('photo_upload_begin',$arr); + $ret = array('success' => false); $channel_id = $channel['channel_id']; $sql_options = ''; @@ -451,15 +454,28 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $hash = $arr['resource_id']; } elseif($options !== 'update') { - if(! x($_FILES,'userfile')) { - $ret['message'] = t('No source file.'); - return $ret; + $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); + + call_hooks('photo_upload_file',$f); + call_hooks('attach_upload_file',$f); + + if (x($f,'src') && x($f,'filesize')) { + $src = $f['src']; + $filename = $f['filename']; + $filesize = $f['filesize']; + $type = $f['type']; + + } else { + + if(! x($_FILES,'userfile')) { + $ret['message'] = t('No source file.'); + return $ret; + } + + $src = $_FILES['userfile']['tmp_name']; + $filename = basename($_FILES['userfile']['name']); + $filesize = intval($_FILES['userfile']['size']); } - - $src = $_FILES['userfile']['tmp_name']; - $filename = basename($_FILES['userfile']['name']); - $filesize = intval($_FILES['userfile']['size']); - } $existing_size = 0; @@ -615,6 +631,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(($maxfilesize) && ($filesize > $maxfilesize)) { $ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize); @unlink($src); + call_hooks('photo_upload_end',$ret); return $ret; } @@ -627,10 +644,11 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) { $ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000); @unlink($src); + call_hooks('photo_upload_end',$ret); return $ret; } } - $mimetype = z_mime_content_type($filename); + $mimetype = ((isset($type) && $type) ? $type : z_mime_content_type($filename)); } $os_basepath = 'store/' . $channel['channel_address'] . '/' ; @@ -658,7 +676,6 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { else $edited = $created; - if($options === 'replace') { $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, data = '%s', edited = '%s' where id = %d and uid = %d", dbesc($filename), @@ -714,6 +731,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { ); } else { + $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), @@ -738,6 +756,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { } if($is_photo) { + $args = array( 'source' => $source, 'visible' => 0, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct); if($arr['contact_allow']) $args['contact_allow'] = $arr['contact_allow']; @@ -772,6 +791,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(! $r) { $ret['message'] = t('File upload failed. Possible system limit or action terminated.'); + call_hooks('photo_upload_end',$ret); return $ret; } @@ -784,13 +804,17 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(! $r) { $ret['message'] = t('Stored file could not be verified. Upload failed.'); + call_hooks('photo_upload_end',$ret); return $ret; } $ret['success'] = true; $ret['data'] = $r[0]; - + if(! $is_photo) { + // This would've been called already with a success result in photos_upload() if it was a photo. + call_hooks('photo_upload_end',$ret); + } return $ret; } diff --git a/include/chat.php b/include/chat.php index 05bb02bb9..a0646265a 100644 --- a/include/chat.php +++ b/include/chat.php @@ -91,6 +91,8 @@ function chatroom_destroy($channel,$arr) { return $ret; } + create_sync_packet($channel['channel_id'],array('chatroom' => $r)); + q("delete from chatroom where cr_id = %d", intval($r[0]['cr_id']) ); diff --git a/include/conversation.php b/include/conversation.php index a3fdf39df..fb8ef8585 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1137,6 +1137,7 @@ function status_editor($a, $x, $popup = false) { '$newpost' => 'true', '$baseurl' => $a->get_baseurl(true), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => ((x($x,'pretext')) ? $x['pretext'] : ''), '$geotag' => $geotag, '$nickname' => $x['nickname'], '$ispublic' => t('Visible to everybody'), diff --git a/include/event.php b/include/event.php index 6670bc53b..44c172e98 100644 --- a/include/event.php +++ b/include/event.php @@ -446,6 +446,20 @@ function event_addtocal($item_id, $uid) { intval($channel['channel_id']) ); + $item['resource_id'] = $event['event_hash']; + $item['resource_type'] = 'event'; + + $i = array($item); + xchan_query($i); + $sync_item = fetch_post_tags($i); + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + if($z) { + build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); + } + return true; } } @@ -959,4 +973,4 @@ function tasks_fetch($arr) { return $ret; -} \ No newline at end of file +} diff --git a/include/identity.php b/include/identity.php index 115baddc1..b5235e7ff 100644 --- a/include/identity.php +++ b/include/identity.php @@ -5,7 +5,7 @@ require_once('include/zot.php'); require_once('include/crypto.php'); - +require_once('include/menu.php'); /** * @brief Called when creating a new channel. @@ -566,13 +566,57 @@ function identity_basic_export($channel_id, $items = false) { if($r) $ret['obj'] = $r; - $r = q("select * from app where app_channel = %d", intval($channel_id) ); if($r) $ret['app'] = $r; + $r = q("select * from chatroom where cr_uid = %d", + intval($channel_id) + ); + if($r) + $ret['chatroom'] = $r; + + + $r = q("select * from event where uid = %d", + intval($channel_id) + ); + if($r) + $ret['event'] = $r; + + $r = q("select * from item where resource_type = 'event' and uid = %d", + intval($channel_id) + ); + if($r) { + $ret['event_item'] = array(); + xchan_query($r); + $r = fetch_post_tags($r,true); + foreach($r as $rr) + $ret['event_item'][] = encode_item($rr,true); + } + + $x = menu_list($channel_id); + if($x) { + $ret['menu'] = array(); + for($y = 0; $y < count($x); $y ++) { + $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); + if($m) + $ret['menu'][] = menu_element($m); + } + } + + $x = menu_list($channel_id); + if($x) { + $ret['menu'] = array(); + for($y = 0; $y < count($x); $y ++) { + $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); + if($m) + $ret['menu'][] = menu_element($m); + } + } + + if(! $items) return $ret; @@ -594,14 +638,17 @@ function identity_basic_export($channel_id, $items = false) { /** @warning this may run into memory limits on smaller systems */ - /** export one year of posts. If you want to export and import all posts you have to start with + + /** export three months of posts. If you want to export and import all posts you have to start with * the first year and export/import them in ascending order. + * + * Don't export linked resource items. we'll have to pull those out separately. */ - $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s", + $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", intval($channel_id), db_utcnow(), - db_quoteinterval('1 YEAR') + db_quoteinterval('3 MONTH') ); if($r) { $ret['item'] = array(); @@ -635,7 +682,7 @@ function identity_export_year($channel_id,$year,$month = 0) { else $maxdate = datetime_convert('UTC','UTC',$year+1 . '-01-01 00:00:00'); - $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' order by created", + $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created", intval($channel_id), dbesc($mindate), dbesc($maxdate) @@ -649,7 +696,6 @@ function identity_export_year($channel_id,$year,$month = 0) { $ret['item'][] = encode_item($rr,true); } - $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d and item.created >= '%s' and item.created < '%s' order by created ", intval($channel_id), diff --git a/include/import.php b/include/import.php index 6ce572ea2..ad8bcd84e 100644 --- a/include/import.php +++ b/include/import.php @@ -1,5 +1,6 @@ = $obj['app_edited']) + if($x[0]['app_edited'] >= $app['app_edited']) continue; $exists = true; } @@ -377,4 +383,424 @@ function sync_apps($channel,$apps) { } } } -} \ No newline at end of file +} + + + +function import_chatrooms($channel,$chatrooms) { + + if($channel && $chatrooms) { + foreach($chatrooms as $chatroom) { + + if(! $chatroom['cr_name']) + continue; + + unset($chatroom['cr_id']); + unset($chatroom['cr_aid']); + unset($chatroom['cr_uid']); + + $chatroom['cr_aid'] = $channel['channel_account_id']; + $chatroom['cr_uid'] = $channel['channel_id']; + + dbesc_array($chatroom); + $r = dbq("INSERT INTO chatroom (`" + . implode("`, `", array_keys($chatroom)) + . "`) VALUES ('" + . implode("', '", array_values($chatroom)) + . "')" + ); + } + } +} + + + +function sync_chatrooms($channel,$chatrooms) { + + if($channel && $chatrooms) { + foreach($chatrooms as $chatroom) { + + if(! $chatroom['cr_name']) + continue; + + if(array_key_exists('cr_deleted',$chatroom) && $chatroom['cr_deleted']) { + q("delete from chatroom where cr_name = '%s' and cr_uid = %d limit 1", + dbesc($chatroom['cr_name']), + intval($channel['channel_id']) + ); + continue; + } + + + unset($chatroom['cr_id']); + unset($chatroom['cr_aid']); + unset($chatroom['cr_uid']); + + if(! $chatroom['cr_created'] || $chatroom['cr_created'] === NULL_DATE) + $chatroom['cr_created'] = datetime_convert(); + if(! $chatroom['cr_edited'] || $chatroom['cr_edited'] === NULL_DATE) + $chatroom['cr_edited'] = datetime_convert(); + + $chatroom['cr_aid'] = $channel['channel_account_id']; + $chatroom['cr_uid'] = $channel['channel_id']; + + $exists = false; + + $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1", + dbesc($chatroom['cr_name']), + intval($channel['channel_id']) + ); + if($x) { + if($x[0]['cr_edited'] >= $chatroom['cr_edited']) + continue; + $exists = true; + } + $name = $chatroom['cr_name']; + + if($exists) { + foreach($chatroom as $k => $v) { + $r = q("UPDATE chatroom SET `%s` = '%s' WHERE cr_name = '%s' AND cr_uid = %d", + dbesc($k), + dbesc($v), + dbesc($name), + intval($channel['channel_id']) + ); + } + } + else { + dbesc_array($chatroom); + $r = dbq("INSERT INTO chatroom (`" + . implode("`, `", array_keys($chatroom)) + . "`) VALUES ('" + . implode("', '", array_values($chatroom)) + . "')" + ); + } + } + } +} + + + +function import_items($channel,$items) { + + if($channel && $items) { + $allow_code = false; + $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id + where channel_id = %d limit 1", + intval($channel['channel_id']) + ); + if($r) { + if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) { + $allow_code = true; + } + } + + foreach($items as $i) { + $item = get_item_elements($i,$allow_code); + if(! $item) + continue; + + $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1", + dbesc($item['mid']), + intval($channel['channel_id']) + ); + if($r) { + if($item['edited'] > $r[0]['edited']) { + $item['id'] = $r[0]['id']; + $item['uid'] = $channel['channel_id']; + item_store_update($item); + continue; + } + } + else { + $item['aid'] = $channel['channel_account_id']; + $item['uid'] = $channel['channel_id']; + $item_result = item_store($item); + } + + } + } +} + + +function sync_items($channel,$items) { + import_items($channel,$items); +} + + + +function import_item_ids($channel,$itemids) { + if($channel && $itemids) { + foreach($itemids as $i) { + $r = q("select id from item where mid = '%s' and uid = %d limit 1", + dbesc($i['mid']), + intval($channel['channel_id']) + ); + if(! $r) + continue; + $z = q("select * from item_id where service = '%s' and sid = '%s' and iid = %d and uid = %d limit 1", + dbesc($i['service']), + dbesc($i['sid']), + intval($r[0]['id']), + intval($channel['channel_id']) + ); + if(! $z) { + q("insert into item_id (iid,uid,sid,service) values(%d,%d,'%s','%s')", + intval($r[0]['id']), + intval($channel['channel_id']), + dbesc($i['sid']), + dbesc($i['service']) + ); + } + } + } +} + +function import_events($channel,$events) { + + if($channel && $events) { + foreach($events as $event) { + unset($event['id']); + $event['aid'] = $channel['channel_account_id']; + $event['uid'] = $channel['channel_id']; + + dbesc_array($event); + $r = dbq("INSERT INTO event (`" + . implode("`, `", array_keys($event)) + . "`) VALUES ('" + . implode("', '", array_values($event)) + . "')" + ); + } + } +} + + +function sync_events($channel,$events) { + + if($channel && $events) { + foreach($events as $event) { + + if((! $event['event_hash']) || (! $event['start'])) + continue; + + if($event['event_deleted']) { + $r = q("delete from event where event_hash = '%s' and uid = %d limit 1", + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + continue; + } + + unset($event['id']); + $event['aid'] = $channel['channel_account_id']; + $event['uid'] = $channel['channel_id']; + + $exists = false; + + $x = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + if($x) { + if($x[0]['edited'] >= $event['edited']) + continue; + $exists = true; + } + + if($exists) { + foreach($event as $k => $v) { + $r = q("UPDATE event SET `%s` = '%s' WHERE event_hash = '%s' AND uid = %d", + dbesc($k), + dbesc($v), + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + } + } + else { + dbesc_array($event); + $r = dbq("INSERT INTO event (`" + . implode("`, `", array_keys($event)) + . "`) VALUES ('" + . implode("', '", array_values($event)) + . "')" + ); + } + } + } +} + + +function import_menus($channel,$menus) { + + if($channel && $menus) { + foreach($menus as $menu) { + $m = array(); + $m['menu_channel_id'] = $channel['channel_id']; + $m['menu_name'] = $menu['pagetitle']; + $m['menu_desc'] = $menu['desc']; + if($menu['created']) + $m['menu_created'] = datetime_convert($menu['created']); + if($menu['edited']) + $m['menu_edited'] = datetime_convert($menu['edited']); + + $m['menu_flags'] = 0; + if($menu['flags']) { + if(in_array('bookmark',$menu['flags'])) + $m['menu_flags'] |= MENU_BOOKMARK; + if(in_array('system',$menu['flags'])) + $m['menu_flags'] |= MENU_SYSTEM; + + } + + $menu_id = menu_create($m); + + if($menu_id) { + if(is_array($menu['items'])) { + foreach($menu['items'] as $it) { + $mitem = array(); + + $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']); + $mitem['mitem_desc'] = escape_tags($it['desc']); + $mitem['mitem_order'] = intval($it['order']); + if(is_array($it['flags'])) { + $mitem['mitem_flags'] = 0; + if(in_array('zid',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_ZID; + if(in_array('new-window',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN; + if(in_array('chatroom',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM; + } + menu_add_item($menu_id,$channel['channel_id'],$mitem); + } + } + } + } + } +} + + +function sync_menus($channel,$menus) { + + if($channel && $menus) { + foreach($menus as $menu) { + $m = array(); + $m['menu_channel_id'] = $channel['channel_id']; + $m['menu_name'] = $menu['pagetitle']; + $m['menu_desc'] = $menu['desc']; + if($menu['created']) + $m['menu_created'] = datetime_convert($menu['created']); + if($menu['edited']) + $m['menu_edited'] = datetime_convert($menu['edited']); + + $m['menu_flags'] = 0; + if($menu['flags']) { + if(in_array('bookmark',$menu['flags'])) + $m['menu_flags'] |= MENU_BOOKMARK; + if(in_array('system',$menu['flags'])) + $m['menu_flags'] |= MENU_SYSTEM; + + } + + $editing = false; + + $r = q("select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1", + dbesc($m['menu_name']), + intval($channel['channel_id']) + ); + if($r) { + if($r[0]['menu_edited'] >= $m['menu_edited']) + continue; + if($menu['menu_deleted']) { + menu_delete_id($r[0]['menu_id'],$channel['channel_id']); + continue; + } + $menu_id = $r[0]['menu_id']; + $m['menu_id'] = $r[0]['menu_id']; + $x = menu_edit($m); + if(! $x) + continue; + $editing = true; + } + if(! $editing) { + $menu_id = menu_create($m); + } + if($menu_id) { + if($editing) { + // don't try syncing - just delete all the entries and start over + q("delete from menu_item where mitem_menu_id = %d", + intval($menu_id) + ); + } + + if(is_array($menu['items'])) { + foreach($menu['items'] as $it) { + $mitem = array(); + + $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']); + $mitem['mitem_desc'] = escape_tags($it['desc']); + $mitem['mitem_order'] = intval($it['order']); + if(is_array($it['flags'])) { + $mitem['mitem_flags'] = 0; + if(in_array('zid',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_ZID; + if(in_array('new-window',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN; + if(in_array('chatroom',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM; + } + menu_add_item($menu_id,$channel['channel_id'],$mitem); + } + } + } + } + } +} + + + +function import_likes($channel,$likes) { + if($channel && $likes) { + foreach($likes as $like) { + if($like['deleted']) { + q("delete from likes where liker = '%s' and likee = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s'", + dbesc($like['liker']), + dbesc($like['likee']), + dbesc($like['verb']), + dbesc($like['target_type']), + dbesc($like['target_id']) + ); + continue; + } + + unset($like['id']); + unset($like['iid']); + $like['channel_id'] = $channel['channel_id']; + $r = q("select * from likes where liker = '%s' and likee = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' and i_mid = '%s'", + dbesc($like['liker']), + dbesc($like['likee']), + dbesc($like['verb']), + dbesc($like['target_type']), + dbesc($like['target_id']), + dbesc($like['i_mid']) + ); + if($r) + continue; + + dbesc_array($config); + $r = dbq("INSERT INTO likes (`" + . implode("`, `", array_keys($like)) + . "`) VALUES ('" + . implode("', '", array_values($like)) + . "')" ); + } + } +} + + + + + diff --git a/include/items.php b/include/items.php index 9807831e3..28fd8502b 100755 --- a/include/items.php +++ b/include/items.php @@ -833,10 +833,13 @@ function title_is_body($title, $body) { } -function get_item_elements($x) { +function get_item_elements($x,$allow_code = false) { $arr = array(); - $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : ''); + if($allow_code) + $arr['body'] = $x['body']; + else + $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : ''); $key = get_config('system','pubkey'); @@ -1309,7 +1312,7 @@ function encode_item($item,$mirror = false) { $x['comment_scope'] = $c_scope; if($item['term']) - $x['tags'] = encode_item_terms($item['term']); + $x['tags'] = encode_item_terms($item['term'],$mirror); if($item['diaspora_meta']) { $z = json_decode($item['diaspora_meta'],true); @@ -1401,11 +1404,16 @@ function encode_item_xchan($xchan) { return $ret; } -function encode_item_terms($terms) { +function encode_item_terms($terms,$mirror = false) { $ret = array(); $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK ); + if($mirror) { + $allowed_export_terms[] = TERM_PCATEGORY; + $allowed_export_terms[] = TERM_FILE; + } + if($terms) { foreach($terms as $term) { if(in_array($term['type'],$allowed_export_terms)) @@ -3322,7 +3330,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { dbesc($title), dbesc($body), intval($item_wall), - $intval($item_origin), + intval($item_origin), intval($item_id) ); @@ -4632,10 +4640,12 @@ function zot_feed($uid,$observer_hash,$arr) { $items = array(); - /** @FIXME fix this part for PostgreSQL */ + /** @FIXME re-unite these SQL statements. There is no need for them to be separate. The mySQL is convoluted with misuse of group by. As it stands, there is a slight difference where the postgres version doesn't remove the duplicate parents up to 100. In practice this doesn't matter. It could be made to match behavior by adding "distinct on (parent) " to the front of the selection list, at a not-worth-it performance penalty (page temp results to disk). duplicates are still ignored in the in() clause, you just get less than 100 parents if there are many children. */ if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { - return array(); + $groupby = ''; + } else { + $groupby = 'GROUP BY parent'; } $item_normal = item_normal(); @@ -4645,7 +4655,7 @@ function zot_feed($uid,$observer_hash,$arr) { WHERE uid != %d $item_normal AND item_wall = 1 - and item_private = 0 $sql_extra GROUP BY parent ORDER BY created ASC $limit", + and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit", intval($uid) ); } @@ -4653,7 +4663,7 @@ function zot_feed($uid,$observer_hash,$arr) { $r = q("SELECT parent, created, postopts from item WHERE uid = %d $item_normal AND item_wall = 1 - $sql_extra GROUP BY parent ORDER BY created ASC $limit", + $sql_extra $groupby ORDER BY created ASC $limit", intval($uid) ); } @@ -4724,6 +4734,12 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C if($arr['wall']) $sql_options .= " and item_wall = 1 "; + + if($arr['item_id']) + $sql_options .= " and parent = " . intval($arr['item_id']) . " "; + + if($arr['mid']) + $sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' "; $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options ) "; @@ -4850,11 +4866,15 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C require_once('include/security.php'); $sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash); + if($arr['pages']) $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " "; else $item_restrict = " AND item_type = 0 "; + if($arr['item_type'] === '*') + $item_restrict = ''; + if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) { // "New Item View" - show all items unthreaded in reverse created date order diff --git a/include/menu.php b/include/menu.php index 7ed931a59..075372515 100644 --- a/include/menu.php +++ b/include/menu.php @@ -6,7 +6,7 @@ require_once('include/bbcode.php'); function menu_fetch($name,$uid,$observer_xchan) { - $sql_options = permissions_sql($uid); + $sql_options = permissions_sql($uid,$observer_xchan); $r = q("select * from menu where menu_channel_id = %d and menu_name = '%s' limit 1", intval($uid), @@ -238,7 +238,6 @@ function menu_edit($arr) { return false; } - $r = q("select * from menu where menu_id = %d and menu_channel_id = %d limit 1", intval($menu_id), intval($menu_channel_id) @@ -388,3 +387,14 @@ function menu_del_item($menu_id,$uid,$item_id) { return $r; } +function menu_sync_packet($uid,$observer_hash,$menu_id,$delete = false) { + $r = menu_fetch_id($menu_id,$uid); + if($r) { + $m = menu_fetch($r['menu_name'],$uid,$observer_hash); + if($m) { + if($delete) + $m['menu_delete'] = 1; + build_sync_packet($uid,array('menu' => array(menu_element($m)))); + } + } +} diff --git a/include/message.php b/include/message.php index 396e3162c..efe1a7710 100644 --- a/include/message.php +++ b/include/message.php @@ -49,6 +49,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' // look for any existing conversation structure + if(strlen($replyto)) { $r = q("select convid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1", intval(local_channel()), diff --git a/include/network.php b/include/network.php index 75729d6e4..d3320f3ee 100644 --- a/include/network.php +++ b/include/network.php @@ -1137,6 +1137,8 @@ function discover_by_webbie($webbie) { if($hcard) { $vcard = scrape_vcard($hcard); $vcard['nick'] = substr($webbie,0,strpos($webbie,'@')); + if(! $vcard['fn']) + $vcard['fn'] = $webbie; } $r = q("select * from xchan where xchan_hash = '%s' limit 1", diff --git a/include/photos.php b/include/photos.php index b4129fbf1..49aab6865 100644 --- a/include/photos.php +++ b/include/photos.php @@ -27,7 +27,7 @@ function photo_upload($channel, $observer, $args) { return $ret; } - call_hooks('photo_upload_begin', $args); +// call_hooks('photo_upload_begin', $args); /* * Determine the album to use @@ -84,7 +84,7 @@ function photo_upload($channel, $observer, $args) { } else { $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); - call_hooks('photo_upload_file',$f); +// call_hooks('photo_upload_file',$f); if (x($f,'src') && x($f,'filesize')) { $src = $f['src']; @@ -226,11 +226,8 @@ function photo_upload($channel, $observer, $args) { $width_x_height = $ph->getWidth() . 'x' . $ph->getHeight(); - $mid = item_message_id(); - // Create item container - $item_hidden = (($visible) ? 0 : 1 ); $lat = $lon = null; diff --git a/include/security.php b/include/security.php index 7cc93fc06..380505a79 100644 --- a/include/security.php +++ b/include/security.php @@ -256,7 +256,7 @@ function item_permissions_sql($owner_id, $remote_observer = null) { $regexop = db_getfunc('REGEXP'); $sql = sprintf( " AND ( NOT (deny_cid like '%s' OR deny_gid $regexop '%s') - AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '') ) + AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ) ) ) ", dbesc(protect_sprintf( '%<' . $observer . '>%')), @@ -291,7 +291,7 @@ function public_permissions_sql($observer_hash) { $regexop = db_getfunc('REGEXP'); $sql = sprintf( " OR (( NOT (deny_cid like '%s' OR deny_gid $regexop '%s') - AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '') ) + AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ) ) )) ", dbesc(protect_sprintf( '%<' . $observer_hash . '>%')), diff --git a/include/widgets.php b/include/widgets.php index 42d9db19a..5e40bf54a 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -1007,7 +1007,9 @@ function widget_forums($arr) { $perms_sql = item_permissions_sql(local_channel()) . item_normal(); - $r1 = q("select * from abook left join xchan on abook_xchan = xchan_hash where xchan_pubforum = 1 and abook_channel = %d order by xchan_name $limit ", + $r1 = q("select * from abook left join xchan on abook_xchan = xchan_hash where ( xchan_pubforum = 1 or ((abook_their_perms & %d ) != 0 and (abook_their_perms & %d ) = 0) ) and abook_channel = %d order by xchan_name $limit ", + intval(PERMS_W_TAGWALL), + intval(PERMS_W_STREAM), intval(local_channel()) ); if(! $r1) @@ -1034,7 +1036,7 @@ function widget_forums($arr) { foreach($r1 as $rr) { if($unseen && (! intval($rr['unseen']))) continue; - $o .= '
  • ' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . ' ' . $rr['xchan_name'] . '
  • '; + $o .= '
  • ' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . ' ' . $rr['xchan_name'] . '
  • '; } $o .= ''; } @@ -1074,4 +1076,63 @@ function widget_helpindex($arr) { $o .= ''; return $o; +} + + + +function widget_admin($arr) { + + /* + * Side bar links + */ + + if(! is_site_admin()) { + return login(false); + } + + + $a = get_app(); + $o = ''; + + // array( url, name, extra css classes ) + + $aside = array( + 'site' => array(z_root() . '/admin/site/', t('Site'), 'site'), + 'users' => array(z_root() . '/admin/users/', t('Accounts'), 'users'), + 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'), + 'plugins' => array(z_root() . '/admin/plugins/', t('Plugins'), 'plugins'), + 'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'), + 'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'), + 'profs' => array(z_root() . '/admin/profs', t('Profile Config'), 'profs'), + 'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync') + + ); + + /* get plugins admin page */ + + $r = q("SELECT * FROM addon WHERE plugin_admin = 1"); + + $aside['plugins_admin'] = array(); + if($r) { + foreach ($r as $h){ + $plugin = $h['name']; + $aside['plugins_admin'][] = array(z_root() . '/admin/plugins/' . $plugin, $plugin, 'plugin'); + // temp plugins with admin + $a->plugins_admin[] = $plugin; + } + } + + $aside['logs'] = array(z_root() . '/admin/logs/', t('Logs'), 'logs'); + + $o .= replace_macros(get_markup_template('admin_aside.tpl'), array( + '$admin' => $aside, + '$admtxt' => t('Admin'), + '$plugadmtxt' => t('Plugin Features'), + '$logtxt' => t('Logs'), + '$h_pending' => t('User registrations waiting for confirmation'), + '$admurl'=> z_root() . '/admin/' + )); + + return $o; + } \ No newline at end of file diff --git a/include/zot.php b/include/zot.php index fecaa7ad2..0e00f39b4 100644 --- a/include/zot.php +++ b/include/zot.php @@ -294,9 +294,19 @@ function zot_refresh($them, $channel = null, $force = false) { if ($them['hubloc_url']) { $url = $them['hubloc_url']; } else { - $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_hash = '%s'", - dbesc($them['xchan_hash']) - ); + $r = null; + + if(array_key_exists('xchan_addr',$them) && $them['xchan_addr']) { + $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_addr = '%s'", + dbesc($them['xchan_addr']) + ); + } + if(! $r) { + $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_hash = '%s'", + dbesc($them['xchan_hash']) + ); + } + if ($r) { foreach ($r as $rr) { if (intval($rr['hubloc_primary'])) { @@ -962,7 +972,7 @@ function zot_process_response($hub, $arr, $outq) { ); } - logger('zot_process_response: ' . print_r($x,true), LOGGER_DATA); + logger('zot_process_response: ' . print_r($x,true), LOGGER_DEBUG); } /** @@ -2226,7 +2236,7 @@ function sync_locations($sender, $arr, $absolute = false) { // Absolute sync - make sure the current primary is correctly reflected in the xchan $pr = hubloc_change_primary($r[0]); if($pr) { - $what .= 'xchan_primary'; + $what .= 'xchan_primary '; $changed = true; } } @@ -2878,9 +2888,30 @@ 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('likes',$arr) && $arr['likes']) + import_likes($channel,$arr['likes']); + if(array_key_exists('app',$arr) && $arr['app']) sync_apps($channel,$arr['app']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) + sync_chatrooms($channel,$arr['chatroom']); + + if(array_key_exists('event',$arr) && $arr['event']) + sync_events($channel,$arr['event']); + + if(array_key_exists('event_item',$arr) && $arr['event_item']) + sync_items($channel,$arr['event_item']); + + if(array_key_exists('item',$arr) && $arr['item']) + sync_items($channel,$arr['item']); + + if(array_key_exists('item_id',$arr) && $arr['item_id']) + sync_items($channel,$arr['item_id']); + + if(array_key_exists('menu',$arr) && $arr['menu']) + sync_menus($channel,$arr['menu']); + 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/update.php b/install/update.php index 8e531b595..339d0cb25 100644 --- a/install/update.php +++ b/install/update.php @@ -1,6 +1,6 @@ array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"), - 'users' => array($a->get_baseurl(true)."/admin/users/", t("Accounts") , "users"), - 'channels' => array($a->get_baseurl(true)."/admin/channels/", t("Channels") , "channels"), - 'plugins' => array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"), - 'themes' => array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"), - 'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'), -// 'hubloc' => array($a->get_baseurl(true)."/admin/hubloc/", t("Server") , "server"), - 'profs' => array(z_root() . '/admin/profs', t('Profile Config'), 'profs'), - 'dbsync' => array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync") - - ); - - /* get plugins admin page */ - - $r = q("SELECT * FROM addon WHERE plugin_admin = 1"); - $aside['plugins_admin'] = array(); - foreach ($r as $h){ - $plugin = $h['name']; - $aside['plugins_admin'][] = array($a->get_baseurl(true) . '/admin/plugins/' . $plugin, $plugin, 'plugin'); - // temp plugins with admin - $a->plugins_admin[] = $plugin; - } - - $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs"); - - $t = get_markup_template("admin_aside.tpl"); - $a->page['aside'] .= replace_macros( $t, array( - '$admin' => $aside, - '$admtxt' => t('Admin'), - '$plugadmtxt' => t('Plugin Features'), - '$logtxt' => t('Logs'), - '$h_pending' => t('User registrations waiting for confirmation'), - '$admurl'=> $a->get_baseurl(true)."/admin/" - )); - /* * Page content diff --git a/mod/chat.php b/mod/chat.php index c2c11d0ab..9ad58bc32 100644 --- a/mod/chat.php +++ b/mod/chat.php @@ -62,11 +62,13 @@ function chat_post(&$a) { chatroom_create($channel,$arr); - $x = q("select cr_id from chatroom where cr_name = '%s' and cr_uid = %d limit 1", + $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1", dbesc($room), intval(local_channel()) ); + create_sync_packet(0, array('chatroom' => $x)); + if($x) goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']); diff --git a/mod/editblock.php b/mod/editblock.php index b4d954ef5..9269676b1 100644 --- a/mod/editblock.php +++ b/mod/editblock.php @@ -111,6 +111,7 @@ function editblock_content(&$a) { $a->page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => $a->get_baseurl(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', '$ispublic' => ' ', // t('Visible to everybody'), '$geotag' => '', '$nickname' => $channel['channel_address'], diff --git a/mod/editlayout.php b/mod/editlayout.php index 6ea7f4100..fc68cfe3c 100644 --- a/mod/editlayout.php +++ b/mod/editlayout.php @@ -105,6 +105,7 @@ function editlayout_content(&$a) { $a->page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => $a->get_baseurl(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', '$ispublic' => ' ', // t('Visible to everybody'), '$geotag' => $geotag, '$nickname' => $channel['channel_address'], diff --git a/mod/editpost.php b/mod/editpost.php index daca7c154..d4dc35ef8 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -47,6 +47,7 @@ function editpost_content(&$a) { $a->page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => $a->get_baseurl(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', '$ispublic' => ' ', // t('Visible to everybody'), '$geotag' => $geotag, '$nickname' => $channel['channel_address'], diff --git a/mod/editwebpage.php b/mod/editwebpage.php index 974e8cc38..0192fd9c0 100644 --- a/mod/editwebpage.php +++ b/mod/editwebpage.php @@ -146,6 +146,7 @@ function editwebpage_content(&$a) { $a->page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => $a->get_baseurl(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', '$ispublic' => ' ', // t('Visible to everybody'), '$geotag' => $geotag, '$nickname' => $channel['channel_address'], diff --git a/mod/events.php b/mod/events.php index 9120f8713..d76602a33 100755 --- a/mod/events.php +++ b/mod/events.php @@ -205,6 +205,23 @@ function events_post(&$a) { $item_id = event_store_item($datarray,$event); + if($item_id) { + $r = q("select * from item where id = %d", + intval($item_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($r[0]['resource_id']), + intval($channel['channel_id']) + ); + if($z) { + build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); + } + } + } + if($share) proc_run('php',"include/notifier.php","event","$item_id"); @@ -528,6 +545,9 @@ function events_content(&$a) { dbesc($event_id), intval(local_channel()) ); + + $sync_event = $r[0]; + if($r) { $r = q("delete from event where event_hash = '%s' and uid = %d limit 1", dbesc($event_id), @@ -538,6 +558,9 @@ function events_content(&$a) { dbesc($event_id), intval(local_channel()) ); + $sync_event['event_deleted'] = 1; + build_sync_packet(0,array('event' => array($sync_event))); + info( t('Event removed') . EOL); } else { diff --git a/mod/import.php b/mod/import.php index c2ed82a0a..563967aa2 100644 --- a/mod/import.php +++ b/mod/import.php @@ -161,7 +161,6 @@ function import_post(&$a) { } - if($completed < 3) { if($data['photo']) { @@ -169,8 +168,8 @@ function import_post(&$a) { import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],get_account_id(),$channel['channel_id']); } - if(is_array($data['profiles'])) - import_profiles($channel,$data['profiles']); + if(is_array($data['profile'])) + import_profiles($channel,$data['profile']); logger('import step 3'); $_SESSION['import_step'] = 3; @@ -433,65 +432,35 @@ function import_post(&$a) { if(is_array($data['obj'])) import_objs($channel,$data['obj']); + if(is_array($data['likes'])) + import_likes($channel,$data['likes']); + if(is_array($data['app'])) import_apps($channel,$data['app']); + if(is_array($data['chatroom'])) + import_chatrooms($channel,$data['chatroom']); + + if(is_array($data['event'])) + import_events($channel,$data['event']); + + if(is_array($data['event_item'])) + import_items($channel,$data['event_item']); + + if(is_array($data['menu'])) + import_menus($channel,$data['menu']); + + $saved_notification_flags = notifications_off($channel['channel_id']); - if($import_posts && array_key_exists('item',$data) && $data['item']) { - - foreach($data['item'] as $i) { - $item = get_item_elements($i); - - $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1", - dbesc($item['mid']), - intval($channel['channel_id']) - ); - if($r) { - if($item['edited'] > $r[0]['edited']) { - $item['id'] = $r[0]['id']; - $item['uid'] = $channel['channel_id']; - item_store_update($item); - continue; - } - } - else { - $item['aid'] = $channel['channel_account_id']; - $item['uid'] = $channel['channel_id']; - $item_result = item_store($item); - } - - } - - } + if($import_posts && array_key_exists('item',$data) && $data['item']) + import_items($channel,$data['item']); notifications_on($channel['channel_id'],$saved_notification_flags); - if(array_key_exists('item_id',$data) && $data['item_id']) { - foreach($data['item_id'] as $i) { - $r = q("select id from item where mid = '%s' and uid = %d limit 1", - dbesc($i['mid']), - intval($channel['channel_id']) - ); - if(! $r) - continue; - $z = q("select * from item_id where service = '%s' and sid = '%s' and iid = %d and uid = %d limit 1", - dbesc($i['service']), - dbesc($i['sid']), - intval($r[0]['id']), - intval($channel['channel_id']) - ); - if(! $z) { - q("insert into item_id (iid,uid,sid,service) values(%d,%d,'%s','%s')", - intval($r[0]['id']), - intval($channel['channel_id']), - dbesc($i['sid']), - dbesc($i['service']) - ); - } - } - } + if(array_key_exists('item_id',$data) && $data['item_id']) + import_item_ids($channel,$data['item_id']); // FIXME - ensure we have a self entry if somebody is trying to pull a fast one diff --git a/mod/import_items.php b/mod/import_items.php index 1e54c0deb..6b97939c9 100644 --- a/mod/import_items.php +++ b/mod/import_items.php @@ -1,5 +1,6 @@ $r[0]['edited']) { - $item['id'] = $r[0]['id']; - $item['uid'] = $channel['channel_id']; - item_store_update($item); - continue; - } - } - else { - $item['aid'] = $channel['channel_account_id']; - $item['uid'] = $channel['channel_id']; - $item_result = item_store($item); - } - - } - + import_items($channel,$data['item']); } notifications_on($channel['channel_id'],$saved_notification_flags); if(array_key_exists('item_id',$data) && $data['item_id']) { - foreach($data['item_id'] as $i) { - $r = q("select id from item where mid = '%s' and uid = %d limit 1", - dbesc($i['mid']), - intval($channel['channel_id']) - ); - if(! $r) - continue; - $z = q("select * from item_id where service = '%s' and sid = '%s' and iid = %d and uid = %d limit 1", - dbesc($i['service']), - dbesc($i['sid']), - intval($r[0]['id']), - intval($channel['channel_id']) - ); - if(! $z) { - q("insert into item_id (iid,uid,sid,service) values(%d,%d,'%s','%s')", - intval($r[0]['id']), - intval($channel['channel_id']), - dbesc($i['sid']), - dbesc($i['service']) - ); - } - } + import_item_ids($channel,$data['item_id']); } info( t('Import completed') . EOL); diff --git a/mod/item.php b/mod/item.php index c93560771..d0cf59091 100644 --- a/mod/item.php +++ b/mod/item.php @@ -805,6 +805,19 @@ function item_post(&$a) { update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + if(! $parent) { + $r = q("select * from item where id = %d", + intval($post_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $rid = q("select * from item_id where iid = %d", + intval($post_id) + ); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); + } + } if(! $nopush) proc_run('php', "include/notifier.php", 'edit_post', $post_id); @@ -884,14 +897,28 @@ function item_post(&$a) { // NOTREACHED } - if($parent) { + + update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + + if(($parent) && ($parent != $post_id)) { // Store the comment signature information in case we need to relay to Diaspora $ditem = $datarray; $ditem['author'] = $observer; store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); } - - update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + else { + $r = q("select * from item where id = %d", + intval($post_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $rid = q("select * from item_id where iid = %d", + intval($post_id) + ); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); + } + } $datarray['id'] = $post_id; $datarray['llink'] = $a->get_baseurl() . '/display/' . $channel['channel_address'] . '/' . $post_id; @@ -903,6 +930,11 @@ function item_post(&$a) { logger('post_complete'); + + + + + // figure out how to return, depending on from whence we came if($api_source) diff --git a/mod/like.php b/mod/like.php index 42ff9bb8a..ce8bc3063 100755 --- a/mod/like.php +++ b/mod/like.php @@ -219,13 +219,23 @@ function like_content(&$a) { ); if($z) { + $z[0]['deleted'] = 1; + build_sync_packet($ch[0]['channel_id'],array('likes' => $z)); + q("delete from likes where id = %d limit 1", intval($z[0]['id']) ); - drop_item($z[0]['iid'],false); - if($interactive) { - notice( t('Previous action reversed.') . EOL); - return $o; + if($z[0]['i_mid']) { + $r = q("select id from item where mid = '%s' and uid = %d limit 1", + dbesc($z[0]['i_mid']), + intval($ch[0]['channel_id']) + ); + if($r) + drop_item($r[0]['id'],false); + if($interactive) { + notice( t('Previous action reversed.') . EOL); + return $o; + } } killme(); } @@ -490,7 +500,18 @@ function like_content(&$a) { dbesc($obj_id), dbesc(($target) ? $target : $object) ); - }; + $r = q("select * from likes where liker = '%s' and likee = '%s' and i_mid = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' ", + dbesc($observer['xchan_hash']), + dbesc($ch[0]['channel_hash']), + dbesc($mid), + dbesc($activity), + dbesc(($tgttype)? $tgttype : $objtype), + dbesc($obj_id) + ); + if($r) + build_sync_packet($ch[0]['channel_id'],array('likes' => $r)); + + } proc_run('php',"include/notifier.php","like","$post_id"); diff --git a/mod/menu.php b/mod/menu.php index 7763c4ed1..bfc45adef 100644 --- a/mod/menu.php +++ b/mod/menu.php @@ -37,6 +37,7 @@ function menu_post(&$a) { $_REQUEST['menu_id'] = intval(argv(1)); $r = menu_edit($_REQUEST); if($r) { + menu_sync_packet($uid,get_observer_hash(),$menu_id); //info( t('Menu updated.') . EOL); goaway(z_root() . '/mitem/' . $menu_id . (($a->is_sys) ? '?f=&sys=1' : '')); } @@ -45,7 +46,9 @@ function menu_post(&$a) { } else { $r = menu_create($_REQUEST); - if($r) { + if($r) { + menu_sync_packet($uid,get_observer_hash(),$r); + //info( t('Menu created.') . EOL); goaway(z_root() . '/mitem/' . $r . (($a->is_sys) ? '?f=&sys=1' : '')); } @@ -56,6 +59,8 @@ function menu_post(&$a) { } + + function menu_content(&$a) { $uid = local_channel(); @@ -121,6 +126,7 @@ function menu_content(&$a) { if(intval(argv(1))) { if(argc() == 3 && argv(2) == 'drop') { + menu_sync_packet($uid,get_observer_hash(),intval(argv(1)),true); $r = menu_delete_id(intval(argv(1)),$uid); if(!$r) notice( t('Menu could not be deleted.'). EOL); diff --git a/mod/mitem.php b/mod/mitem.php index 0fadd1548..d6572bd56 100644 --- a/mod/mitem.php +++ b/mod/mitem.php @@ -64,6 +64,7 @@ function mitem_post(&$a) { $_REQUEST['mitem_id'] = $mitem_id; $r = menu_edit_item($_REQUEST['menu_id'],$uid,$_REQUEST); if($r) { + menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']); //info( t('Menu element updated.') . EOL); goaway(z_root() . '/mitem/' . $_REQUEST['menu_id'] . (($a->is_sys) ? '?f=&sys=1' : '')); } @@ -74,6 +75,7 @@ function mitem_post(&$a) { else { $r = menu_add_item($_REQUEST['menu_id'],$uid,$_REQUEST); if($r) { + menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']); //info( t('Menu element added.') . EOL); if($_REQUEST['submit']) { goaway(z_root() . '/menu' . (($a->is_sys) ? '?f=&sys=1' : '')); @@ -202,7 +204,9 @@ function mitem_content(&$a) { $lockstate = (($mitem['allow_cid'] || $mitem['allow_gid'] || $mitem['deny_cid'] || $mitem['deny_gid']) ? 'lock' : 'unlock'); if(argc() == 4 && argv(3) == 'drop') { + menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']); $r = menu_del_item($mitem['mitem_menu_id'], $uid, intval(argv(2))); + menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']); if($r) info( t('Menu item deleted.') . EOL); else diff --git a/mod/network.php b/mod/network.php index d5e305687..53de975a4 100644 --- a/mod/network.php +++ b/mod/network.php @@ -115,6 +115,8 @@ function network_content(&$a, $update = 0, $load = false) { $file = ((x($_GET,'file')) ? $_GET['file'] : ''); + $deftag = ''; + if(x($_GET,'search') || x($_GET,'file')) $nouveau = true; if($cid) { @@ -130,7 +132,10 @@ function network_content(&$a, $update = 0, $load = false) { goaway($a->get_baseurl(true) . '/network'); // NOTREACHED } - $def_acl = array('allow_cid' => '<' . $r[0]['abook_xchan'] . '>'); + if($_GET['pf'] === '1') + $deftag = '@' . t('forum') . '+' . intval($cid) . '+'; + else + $def_acl = array('allow_cid' => '<' . $r[0]['abook_xchan'] . '>'); } if(! $update) { @@ -153,17 +158,21 @@ function network_content(&$a, $update = 0, $load = false) { 'deny_gid' => $channel['channel_deny_gid'] ); + $private_editing = ((($group || $cid) && (! intval($_GET['pf']))) ? true : false); + $x = array( 'is_owner' => true, 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], - 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($group || $cid) ? $def_acl : $channel_acl)), - 'bang' => (($group || $cid) ? '!' : ''), + 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl)), + 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel() ); + if($deftag) + $x['pretext'] = $deftag; $status_editor = status_editor($a,$x); $o .= $status_editor; @@ -223,7 +232,7 @@ function network_content(&$a, $update = 0, $load = false) { if($r) { $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) "; $title = replace_macros(get_markup_template("section_title.tpl"),array( - '$title' => t('Connection: ') . $r[0]['xchan_name'] + '$title' => '' . urlencode($r[0]['xchan_name']) . ' ' . $r[0]['xchan_name'] . '' )); $o = $tabs; $o .= $title; diff --git a/mod/photos.php b/mod/photos.php index d06a8e69c..f48603d71 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -85,7 +85,7 @@ function photos_post(&$a) { $owner_record = $s[0]; - $acl = AccessList($a->data['channel']); + $acl = new AccessList($a->data['channel']); if((argc() > 3) && (argv(2) === 'album')) { diff --git a/mod/profile_photo.php b/mod/profile_photo.php index 13923a655..7564a3f69 100644 --- a/mod/profile_photo.php +++ b/mod/profile_photo.php @@ -130,7 +130,7 @@ function profile_photo_post(&$a) { if($r) { $base_image = $r[0]; - $base_image['data'] = dbunescbin($base_image['data']); + $base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data'])); $im = photo_factory($base_image['data'], $base_image['type']); if($im->is_valid()) { @@ -238,16 +238,19 @@ function profile_photo_post(&$a) { notice( t('Image upload failed.') . EOL ); return; } + $os_storage = false; + foreach($i as $ii) { if(intval($ii['scale']) < 2) { $smallest = intval($ii['scale']); + $os_storage = intval($ii['os_storage']); $imagedata = $ii['data']; $filetype = $ii['type']; } } } -// $imagedata = @file_get_contents($src); + $imagedata = (($os_storage) ? @file_get_contents($imagedata) : $imagedata); $ph = photo_factory($imagedata, $filetype); if(! $ph->is_valid()) { @@ -332,7 +335,7 @@ function profile_photo_content(&$a) { goaway($a->get_baseurl() . '/profiles'); } - $r = q("SELECT `data`, `type` FROM photo WHERE id = %d and uid = %d limit 1", + $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel()) @@ -342,9 +345,31 @@ function profile_photo_content(&$a) { return; } - $ph = photo_factory(dbunescbin($r[0]['data']), $r[0]['type']); - // go ahead as if we have just uploaded a new photo to crop - profile_photo_crop_ui_head($a, $ph); + if(intval($r[0]['os_storage'])) + $data = @file_get_contents($r[0]['data']); + else + $data = dbunescbin($r[0]['data']); + + $ph = photo_factory($data, $r[0]['type']); + $smallest = 0; + if($ph->is_valid()) { + // go ahead as if we have just uploaded a new photo to crop + $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale", + dbesc($r[0]['resource_id']), + intval(local_channel()) + ); + + if($i) { + $hash = $i[0]['resource_id']; + foreach($i as $ii) { + if(intval($ii['scale']) < 2) { + $smallest = intval($ii['scale']); + } + } + } + } + + profile_photo_crop_ui_head($a, $ph, $hash, $smallest); } $profiles = q("select id, profile_name as name, is_default from profile where uid = %d", diff --git a/mod/public.php b/mod/public.php index 2106be7a6..45edda6c0 100644 --- a/mod/public.php +++ b/mod/public.php @@ -22,7 +22,7 @@ function public_content(&$a, $update = 0, $load = false) { $maxheight = get_config('system','home_divmore_height'); if(! $maxheight) - $maxheight = 75; + $maxheight = 400; $o .= '
    ' . "\r\n"; $o .= "