From d46dd6aeb872585439e54e2378b726afa51554dc Mon Sep 17 00:00:00 2001 From: nobody Date: Fri, 3 Dec 2021 14:01:39 +1100 Subject: [PATCH] psr12 rewrites, continued --- Zotlabs/Daemon/Addon.php | 12 +- Zotlabs/Daemon/CacheThumb.php | 78 +- Zotlabs/Daemon/Cache_embeds.php | 45 +- Zotlabs/Daemon/Cache_image.php | 19 +- Zotlabs/Daemon/Channel_purge.php | 47 +- Zotlabs/Daemon/Checksites.php | 88 +- Zotlabs/Daemon/Content_importer.php | 73 +- Zotlabs/Daemon/Convo.php | 85 +- Zotlabs/Daemon/Cron.php | 340 +- Zotlabs/Daemon/Cron_daily.php | 158 +- Zotlabs/Daemon/Cron_weekly.php | 120 +- Zotlabs/Daemon/Cronhooks.php | 22 +- Zotlabs/Daemon/CurlAuth.php | 75 +- Zotlabs/Daemon/Deliver.php | 43 +- Zotlabs/Daemon/Deliver_hooks.php | 29 +- Zotlabs/Daemon/Delxitems.php | 20 +- Zotlabs/Daemon/Directory.php | 68 +- Zotlabs/Daemon/Expire.php | 134 +- Zotlabs/Daemon/File_importer.php | 58 +- Zotlabs/Daemon/Gprobe.php | 79 +- Zotlabs/Daemon/Importdoc.php | 84 +- Zotlabs/Daemon/Importfile.php | 74 +- Zotlabs/Daemon/Notifier.php | 1411 ++-- Zotlabs/Daemon/Onedirsync.php | 122 +- Zotlabs/Daemon/Onepoll.php | 259 +- Zotlabs/Daemon/Poller.php | 300 +- Zotlabs/Daemon/Queue.php | 142 +- Zotlabs/Daemon/Run.php | 106 +- Zotlabs/Daemon/Thumbnail.php | 134 +- Zotlabs/Daemon/Xchan_photo.php | 52 +- Zotlabs/Extend/Hook.php | 211 +- Zotlabs/Extend/Route.php | 2 - Zotlabs/Extend/Widget.php | 1 - Zotlabs/Identity/OAuth2Server.php | 53 +- Zotlabs/Identity/OAuth2Storage.php | 103 +- Zotlabs/Import/Friendica.php | 24 +- Zotlabs/Lib/AConfig.php | 32 +- Zotlabs/Lib/ASCollection.php | 2 +- Zotlabs/Lib/AbConfig.php | 127 +- Zotlabs/Lib/AccessList.php | 86 +- Zotlabs/Lib/Activity.php | 488 +- Zotlabs/Lib/ActivityPub.php | 118 +- Zotlabs/Lib/ActivityStreams.php | 13 +- Zotlabs/Lib/Api_router.php | 4 +- Zotlabs/Lib/Apps.php | 122 +- Zotlabs/Lib/Cache.php | 96 +- Zotlabs/Lib/Chatroom.php | 88 +- Zotlabs/Lib/Config.php | 289 +- Zotlabs/Lib/Connect.php | 41 +- Zotlabs/Lib/Crypto.php | 305 +- Zotlabs/Lib/DB_Upgrade.php | 21 +- Zotlabs/Lib/DReport.php | 39 +- Zotlabs/Lib/Enotify.php | 1819 +++-- Zotlabs/Lib/ExtendedZip.php | 80 +- Zotlabs/Lib/Hashpath.php | 6 +- Zotlabs/Lib/IConfig.php | 308 +- Zotlabs/Lib/Img_cache.php | 11 +- Zotlabs/Lib/Img_filesize.php | 17 +- Zotlabs/Lib/JSalmon.php | 6 +- Zotlabs/Lib/Keyutils.php | 147 +- Zotlabs/Lib/LDSignatures.php | 10 +- Zotlabs/Lib/LibBlock.php | 24 +- Zotlabs/Lib/Libprofile.php | 265 +- Zotlabs/Lib/Libsync.php | 193 +- Zotlabs/Lib/Libzot.php | 419 +- Zotlabs/Lib/Libzotdir.php | 99 +- Zotlabs/Lib/Markdown.php | 171 +- Zotlabs/Lib/MarkdownSoap.php | 7 +- Zotlabs/Lib/MastAPI.php | 20 +- Zotlabs/Lib/MessageFilter.php | 149 +- Zotlabs/Lib/Nodeinfo.php | 75 +- Zotlabs/Lib/PConfig.php | 339 +- Zotlabs/Lib/Permcat.php | 267 +- Zotlabs/Lib/PermissionDescription.php | 280 +- Zotlabs/Lib/Queue.php | 94 +- Zotlabs/Lib/SConfig.php | 32 +- Zotlabs/Lib/Share.php | 369 +- Zotlabs/Lib/SvgSanitizer.php | 16 +- Zotlabs/Lib/System.php | 204 +- Zotlabs/Lib/ThreadItem.php | 2076 ++--- Zotlabs/Lib/ThreadListener.php | 94 +- Zotlabs/Lib/ThreadStream.php | 439 +- Zotlabs/Lib/Verify.php | 22 +- Zotlabs/Lib/Webfinger.php | 2 +- Zotlabs/Lib/XConfig.php | 272 +- Zotlabs/Lib/ZotURL.php | 182 +- Zotlabs/Lib/Zotfinger.php | 5 +- Zotlabs/Module/Acl.php | 42 +- Zotlabs/Module/Activity.php | 60 +- Zotlabs/Module/Admin.php | 9 +- Zotlabs/Module/Admin/Account_edit.php | 32 +- Zotlabs/Module/Admin/Accounts.php | 18 +- Zotlabs/Module/Admin/Addons.php | 19 +- Zotlabs/Module/Admin/Channels.php | 40 +- Zotlabs/Module/Admin/Cover_photo.php | 51 +- Zotlabs/Module/Admin/Dbsync.php | 25 +- Zotlabs/Module/Admin/Logs.php | 11 +- Zotlabs/Module/Admin/Profile_photo.php | 57 +- Zotlabs/Module/Admin/Profs.php | 51 +- Zotlabs/Module/Admin/Queue.php | 4 +- Zotlabs/Module/Admin/Security.php | 20 +- Zotlabs/Module/Admin/Site.php | 61 +- Zotlabs/Module/Admin/Themes.php | 28 +- Zotlabs/Module/Affinity.php | 19 +- Zotlabs/Module/Album.php | 12 +- Zotlabs/Module/Ap_probe.php | 4 +- Zotlabs/Module/Api.php | 22 +- Zotlabs/Module/Appman.php | 13 +- Zotlabs/Module/Apps.php | 13 +- Zotlabs/Module/Apschema.php | 5 +- Zotlabs/Module/Attach.php | 17 +- Zotlabs/Module/Authorize.php | 3 - Zotlabs/Module/Block.php | 22 +- Zotlabs/Module/Blocks.php | 23 +- Zotlabs/Module/Ca.php | 4 +- Zotlabs/Module/Cal.php | 67 +- Zotlabs/Module/Calendar.php | 59 +- Zotlabs/Module/Card_edit.php | 15 +- Zotlabs/Module/Cards.php | 37 +- Zotlabs/Module/Categories.php | 4 - Zotlabs/Module/Cdav.php | 97 +- Zotlabs/Module/Changeaddr.php | 15 +- Zotlabs/Module/Channel.php | 55 +- Zotlabs/Module/Chanview.php | 28 +- Zotlabs/Module/Chat.php | 42 +- Zotlabs/Module/Chatsvc.php | 52 +- Zotlabs/Module/Clients.php | 2 - Zotlabs/Module/Cloud.php | 9 +- Zotlabs/Module/Cloud_tiles.php | 8 +- Zotlabs/Module/Comment_control.php | 1 - Zotlabs/Module/Common.php | 16 +- Zotlabs/Module/Connac.php | 5 +- Zotlabs/Module/Connect.php | 30 +- Zotlabs/Module/Connections.php | 38 +- Zotlabs/Module/Connedit.php | 69 +- Zotlabs/Module/Contactgroup.php | 2 +- Zotlabs/Module/Content_filter.php | 7 +- Zotlabs/Module/Conversation.php | 43 +- Zotlabs/Module/Cover_photo.php | 51 +- Zotlabs/Module/Dav.php | 18 +- Zotlabs/Module/Defperms.php | 16 +- Zotlabs/Module/Dircensor.php | 11 +- Zotlabs/Module/Directory.php | 32 +- Zotlabs/Module/Dirsearch.php | 70 +- Zotlabs/Module/Display.php | 92 +- Zotlabs/Module/Drafts.php | 1 - Zotlabs/Module/Dreport.php | 20 +- Zotlabs/Module/Editblock.php | 24 +- Zotlabs/Module/Editlayout.php | 21 +- Zotlabs/Module/Editpost.php | 12 +- Zotlabs/Module/Editwebpage.php | 24 +- Zotlabs/Module/Email_resend.php | 6 - Zotlabs/Module/Email_validation.php | 5 +- Zotlabs/Module/Embedphotos.php | 17 +- Zotlabs/Module/Event.php | 14 +- Zotlabs/Module/Events.php | 144 +- Zotlabs/Module/Expire.php | 3 - Zotlabs/Module/Fastping.php | 2 - Zotlabs/Module/Fbrowser.php | 28 +- Zotlabs/Module/Fedi_id.php | 14 +- Zotlabs/Module/Feed.php | 4 +- Zotlabs/Module/File_upload.php | 9 +- Zotlabs/Module/Filer.php | 14 +- Zotlabs/Module/Filerm.php | 12 +- Zotlabs/Module/Filestorage.php | 15 +- Zotlabs/Module/Finger.php | 2 - Zotlabs/Module/Follow.php | 20 +- Zotlabs/Module/Followers.php | 14 +- Zotlabs/Module/Following.php | 14 +- Zotlabs/Module/Future.php | 2 - Zotlabs/Module/Getfile.php | 29 +- Zotlabs/Module/Hashtags.php | 8 +- Zotlabs/Module/Hcard.php | 19 +- Zotlabs/Module/Help.php | 8 +- Zotlabs/Module/Home.php | 9 +- Zotlabs/Module/Hostxrd.php | 3 +- Zotlabs/Module/Hq.php | 59 +- Zotlabs/Module/Id.php | 23 +- Zotlabs/Module/Impel.php | 53 +- Zotlabs/Module/Import.php | 71 +- Zotlabs/Module/Import_items.php | 33 +- Zotlabs/Module/Inbox.php | 52 +- Zotlabs/Module/Inspect.php | 10 +- Zotlabs/Module/Invite.php | 24 +- Zotlabs/Module/Item.php | 280 +- Zotlabs/Module/Jwks.php | 3 +- Zotlabs/Module/Lang.php | 3 +- Zotlabs/Module/Layouts.php | 29 +- Zotlabs/Module/Like.php | 507 +- Zotlabs/Module/Linkinfo.php | 136 +- Zotlabs/Module/Lists.php | 78 +- Zotlabs/Module/Lockview.php | 52 +- Zotlabs/Module/Locs.php | 33 +- Zotlabs/Module/Login.php | 9 +- Zotlabs/Module/Logout.php | 1 - Zotlabs/Module/Lostpass.php | 27 +- Zotlabs/Module/Magic.php | 10 +- Zotlabs/Module/Manage.php | 31 +- Zotlabs/Module/Manifest.php | 4 +- Zotlabs/Module/Markup.php | 2 - Zotlabs/Module/Menu.php | 35 +- Zotlabs/Module/Mitem.php | 48 +- Zotlabs/Module/Moderate.php | 21 +- Zotlabs/Module/Mood.php | 28 +- Zotlabs/Module/New_channel.php | 26 +- Zotlabs/Module/Notes.php | 15 +- Zotlabs/Module/Notifications.php | 14 +- Zotlabs/Module/Notify.php | 14 +- Zotlabs/Module/Nullbox.php | 2 - Zotlabs/Module/Oauthinfo.php | 3 +- Zotlabs/Module/Oembed.php | 5 +- Zotlabs/Module/Oep.php | 200 +- Zotlabs/Module/Oexchange.php | 3 - Zotlabs/Module/Outbox.php | 97 +- Zotlabs/Module/Owa.php | 10 +- Zotlabs/Module/Page.php | 45 +- Zotlabs/Module/Pconfig.php | 17 +- Zotlabs/Module/Pdledit.php | 18 +- Zotlabs/Module/Permcat.php | 29 +- Zotlabs/Module/Photo.php | 24 +- Zotlabs/Module/Photomap.php | 3 +- Zotlabs/Module/Photos.php | 210 +- Zotlabs/Module/Pin.php | 10 +- Zotlabs/Module/Ping.php | 130 +- Zotlabs/Module/Plike.php | 503 +- Zotlabs/Module/Poco.php | 4 +- Zotlabs/Module/Poke.php | 8 +- Zotlabs/Module/Poster.php | 3 +- Zotlabs/Module/Pretheme.php | 3 +- Zotlabs/Module/Profile.php | 21 +- Zotlabs/Module/Profile_photo.php | 65 +- Zotlabs/Module/Profiles.php | 192 +- Zotlabs/Module/Profperm.php | 53 +- Zotlabs/Module/Pubstream.php | 41 +- Zotlabs/Module/Q.php | 9 +- Zotlabs/Module/Randprof.php | 7 +- Zotlabs/Module/React.php | 23 +- Zotlabs/Module/Register.php | 18 +- Zotlabs/Module/Regmod.php | 15 +- Zotlabs/Module/Removeaccount.php | 2 +- Zotlabs/Module/Removeme.php | 2 +- Zotlabs/Module/Rmagic.php | 11 +- Zotlabs/Module/Rpost.php | 16 +- Zotlabs/Module/Safe.php | 4 +- Zotlabs/Module/Search.php | 23 +- Zotlabs/Module/Search_ac.php | 10 +- Zotlabs/Module/Secrets.php | 1 - Zotlabs/Module/Service_limits.php | 7 +- Zotlabs/Module/Settings.php | 3 +- Zotlabs/Module/Settings/Account.php | 25 +- Zotlabs/Module/Settings/Channel.php | 154 +- Zotlabs/Module/Settings/Display.php | 39 +- Zotlabs/Module/Settings/Featured.php | 15 +- Zotlabs/Module/Settings/Features.php | 6 +- Zotlabs/Module/Settings/Network.php | 8 +- Zotlabs/Module/Settings/Oauth.php | 42 +- Zotlabs/Module/Settings/Oauth2.php | 46 +- Zotlabs/Module/Settings/Permcats.php | 20 +- Zotlabs/Module/Settings/Tokens.php | 63 +- Zotlabs/Module/Setup.php | 17 +- Zotlabs/Module/Share.php | 45 +- Zotlabs/Module/Sharedwithme.php | 24 +- Zotlabs/Module/Siteinfo.php | 7 +- Zotlabs/Module/Sites.php | 18 +- Zotlabs/Module/Smilies.php | 3 +- Zotlabs/Module/Sources.php | 36 +- Zotlabs/Module/Sslify.php | 2 +- Zotlabs/Module/Stream.php | 89 +- Zotlabs/Module/Subthread.php | 22 +- Zotlabs/Module/Suggestions.php | 10 +- Zotlabs/Module/Superblock.php | 34 +- Zotlabs/Module/Tagadelic.php | 4 - Zotlabs/Module/Tagger.php | 24 +- Zotlabs/Module/Tagrm.php | 51 +- Zotlabs/Module/Tasks.php | 14 +- Zotlabs/Module/Theme_info.php | 9 +- Zotlabs/Module/Thing.php | 75 +- Zotlabs/Module/Toggle_safesearch.php | 22 +- Zotlabs/Module/Token.php | 2 - Zotlabs/Module/Uexport.php | 3 +- Zotlabs/Module/Userinfo.php | 1 - Zotlabs/Module/View.php | 6 +- Zotlabs/Module/Viewconnections.php | 7 +- Zotlabs/Module/Viewsrc.php | 10 +- Zotlabs/Module/Vote.php | 25 +- Zotlabs/Module/Wall_attach.php | 15 +- Zotlabs/Module/Wall_upload.php | 19 +- Zotlabs/Module/Webfinger.php | 8 +- Zotlabs/Module/Webpages.php | 54 +- Zotlabs/Module/Well_known.php | 6 +- Zotlabs/Module/Xchan.php | 17 +- Zotlabs/Module/Xref.php | 7 +- Zotlabs/Module/Zot.php | 2 +- Zotlabs/Module/Zot_probe.php | 5 - Zotlabs/Module/Zotfinger.php | 4 +- Zotlabs/Photo/PhotoDriver.php | 925 ++- Zotlabs/Photo/PhotoGd.php | 333 +- Zotlabs/Photo/PhotoImagick.php | 361 +- Zotlabs/Render/Comanche.php | 8 +- Zotlabs/Render/SimpleTemplate.php | 573 +- Zotlabs/Render/SmartyInterface.php | 8 +- Zotlabs/Render/SmartyTemplate.php | 145 +- Zotlabs/Render/TemplateEngine.php | 7 +- Zotlabs/Render/Theme.php | 36 +- Zotlabs/Storage/CalDAVClient.php | 48 +- Zotlabs/Storage/GitRepo.php | 6 +- Zotlabs/Storage/ZotOauth2Pdo.php | 7 +- Zotlabs/Text/Tagadelic.php | 67 +- Zotlabs/Thumbs/Epubthumb.php | 1 - Zotlabs/Thumbs/Mp3audio.php | 1 - Zotlabs/Thumbs/Pdf.php | 2 - Zotlabs/Thumbs/Text.php | 3 +- Zotlabs/Thumbs/Video.php | 2 - Zotlabs/Update/_1000.php | 7 +- Zotlabs/Update/_1001.php | 7 +- Zotlabs/Update/_1002.php | 7 +- Zotlabs/Update/_1003.php | 7 +- Zotlabs/Update/_1004.php | 7 +- Zotlabs/Update/_1005.php | 4 +- Zotlabs/Update/_1006.php | 7 +- Zotlabs/Update/_1007.php | 7 +- Zotlabs/Update/_1008.php | 7 +- Zotlabs/Update/_1009.php | 7 +- Zotlabs/Update/_1010.php | 7 +- Zotlabs/Update/_1011.php | 7 +- Zotlabs/Update/_1012.php | 7 +- Zotlabs/Update/_1013.php | 7 +- Zotlabs/Update/_1014.php | 7 +- Zotlabs/Update/_1015.php | 7 +- Zotlabs/Update/_1016.php | 7 +- Zotlabs/Update/_1017.php | 7 +- Zotlabs/Update/_1018.php | 7 +- Zotlabs/Update/_1019.php | 7 +- Zotlabs/Update/_1020.php | 7 +- Zotlabs/Update/_1021.php | 7 +- Zotlabs/Update/_1022.php | 7 +- Zotlabs/Update/_1023.php | 7 +- Zotlabs/Update/_1024.php | 7 +- Zotlabs/Update/_1025.php | 7 +- Zotlabs/Update/_1026.php | 7 +- Zotlabs/Update/_1027.php | 7 +- Zotlabs/Update/_1028.php | 7 +- Zotlabs/Update/_1029.php | 7 +- Zotlabs/Update/_1030.php | 7 +- Zotlabs/Update/_1031.php | 7 +- Zotlabs/Update/_1032.php | 7 +- Zotlabs/Update/_1033.php | 7 +- Zotlabs/Update/_1034.php | 7 +- Zotlabs/Update/_1035.php | 7 +- Zotlabs/Update/_1036.php | 8 +- Zotlabs/Update/_1037.php | 7 +- Zotlabs/Update/_1038.php | 8 +- Zotlabs/Update/_1039.php | 8 +- Zotlabs/Update/_1040.php | 7 +- Zotlabs/Update/_1041.php | 7 +- Zotlabs/Update/_1042.php | 7 +- Zotlabs/Update/_1043.php | 7 +- Zotlabs/Update/_1044.php | 7 +- Zotlabs/Update/_1045.php | 7 +- Zotlabs/Update/_1046.php | 7 +- Zotlabs/Update/_1047.php | 7 +- Zotlabs/Update/_1048.php | 7 +- Zotlabs/Update/_1049.php | 7 +- Zotlabs/Update/_1050.php | 7 +- Zotlabs/Update/_1051.php | 7 +- Zotlabs/Update/_1052.php | 7 +- Zotlabs/Update/_1053.php | 7 +- Zotlabs/Update/_1054.php | 7 +- Zotlabs/Update/_1055.php | 7 +- Zotlabs/Update/_1056.php | 7 +- Zotlabs/Update/_1057.php | 7 +- Zotlabs/Update/_1058.php | 7 +- Zotlabs/Update/_1059.php | 7 +- Zotlabs/Update/_1060.php | 7 +- Zotlabs/Update/_1061.php | 7 +- Zotlabs/Update/_1062.php | 7 +- Zotlabs/Update/_1063.php | 7 +- Zotlabs/Update/_1064.php | 7 +- Zotlabs/Update/_1065.php | 7 +- Zotlabs/Update/_1066.php | 7 +- Zotlabs/Update/_1067.php | 7 +- Zotlabs/Update/_1068.php | 7 +- Zotlabs/Update/_1069.php | 7 +- Zotlabs/Update/_1070.php | 7 +- Zotlabs/Update/_1071.php | 7 +- Zotlabs/Update/_1072.php | 7 +- Zotlabs/Update/_1073.php | 7 +- Zotlabs/Update/_1074.php | 7 +- Zotlabs/Update/_1075.php | 7 +- Zotlabs/Update/_1076.php | 7 +- Zotlabs/Update/_1077.php | 7 +- Zotlabs/Update/_1078.php | 7 +- Zotlabs/Update/_1079.php | 7 +- Zotlabs/Update/_1080.php | 7 +- Zotlabs/Update/_1081.php | 7 +- Zotlabs/Update/_1082.php | 7 +- Zotlabs/Update/_1083.php | 7 +- Zotlabs/Update/_1084.php | 8 +- Zotlabs/Update/_1085.php | 8 +- Zotlabs/Update/_1086.php | 7 +- Zotlabs/Update/_1087.php | 7 +- Zotlabs/Update/_1088.php | 7 +- Zotlabs/Update/_1089.php | 7 +- Zotlabs/Update/_1090.php | 7 +- Zotlabs/Update/_1091.php | 4 +- Zotlabs/Update/_1092.php | 7 +- Zotlabs/Update/_1093.php | 7 +- Zotlabs/Update/_1094.php | 7 +- Zotlabs/Update/_1095.php | 7 +- Zotlabs/Update/_1096.php | 7 +- Zotlabs/Update/_1097.php | 8 +- Zotlabs/Update/_1098.php | 7 +- Zotlabs/Update/_1099.php | 7 +- Zotlabs/Update/_1100.php | 7 +- Zotlabs/Update/_1101.php | 4 +- Zotlabs/Update/_1102.php | 7 +- Zotlabs/Update/_1103.php | 7 +- Zotlabs/Update/_1104.php | 7 +- Zotlabs/Update/_1105.php | 7 +- Zotlabs/Update/_1106.php | 7 +- Zotlabs/Update/_1107.php | 7 +- Zotlabs/Update/_1108.php | 7 +- Zotlabs/Update/_1109.php | 7 +- Zotlabs/Update/_1110.php | 5 +- Zotlabs/Update/_1111.php | 7 +- Zotlabs/Update/_1112.php | 7 +- Zotlabs/Update/_1113.php | 7 +- Zotlabs/Update/_1114.php | 7 +- Zotlabs/Update/_1115.php | 4 +- Zotlabs/Update/_1116.php | 4 +- Zotlabs/Update/_1117.php | 8 +- Zotlabs/Update/_1118.php | 7 +- Zotlabs/Update/_1119.php | 7 +- Zotlabs/Update/_1120.php | 7 +- Zotlabs/Update/_1121.php | 7 +- Zotlabs/Update/_1122.php | 10 +- Zotlabs/Update/_1123.php | 7 +- Zotlabs/Update/_1124.php | 9 +- Zotlabs/Update/_1125.php | 8 +- Zotlabs/Update/_1126.php | 8 +- Zotlabs/Update/_1127.php | 8 +- Zotlabs/Update/_1128.php | 8 +- Zotlabs/Update/_1129.php | 7 +- Zotlabs/Update/_1130.php | 10 +- Zotlabs/Update/_1131.php | 11 +- Zotlabs/Update/_1132.php | 7 +- Zotlabs/Update/_1133.php | 11 +- Zotlabs/Update/_1134.php | 10 +- Zotlabs/Update/_1135.php | 7 +- Zotlabs/Update/_1136.php | 7 +- Zotlabs/Update/_1137.php | 7 +- Zotlabs/Update/_1138.php | 7 +- Zotlabs/Update/_1139.php | 11 +- Zotlabs/Update/_1140.php | 13 +- Zotlabs/Update/_1141.php | 14 +- Zotlabs/Update/_1142.php | 9 +- Zotlabs/Update/_1143.php | 8 +- Zotlabs/Update/_1144.php | 10 +- Zotlabs/Update/_1145.php | 8 +- Zotlabs/Update/_1146.php | 7 +- Zotlabs/Update/_1147.php | 7 +- Zotlabs/Update/_1148.php | 8 +- Zotlabs/Update/_1149.php | 8 +- Zotlabs/Update/_1150.php | 8 +- Zotlabs/Update/_1151.php | 8 +- Zotlabs/Update/_1152.php | 11 +- Zotlabs/Update/_1153.php | 9 +- Zotlabs/Update/_1154.php | 8 +- Zotlabs/Update/_1155.php | 7 +- Zotlabs/Update/_1156.php | 10 +- Zotlabs/Update/_1157.php | 8 +- Zotlabs/Update/_1158.php | 7 +- Zotlabs/Update/_1159.php | 7 +- Zotlabs/Update/_1160.php | 7 +- Zotlabs/Update/_1161.php | 8 +- Zotlabs/Update/_1162.php | 12 +- Zotlabs/Update/_1163.php | 7 +- Zotlabs/Update/_1164.php | 8 +- Zotlabs/Update/_1165.php | 12 +- Zotlabs/Update/_1166.php | 7 +- Zotlabs/Update/_1167.php | 7 +- Zotlabs/Update/_1168.php | 7 +- Zotlabs/Update/_1169.php | 8 +- Zotlabs/Update/_1170.php | 8 +- Zotlabs/Update/_1171.php | 9 +- Zotlabs/Update/_1172.php | 8 +- Zotlabs/Update/_1173.php | 8 +- Zotlabs/Update/_1174.php | 8 +- Zotlabs/Update/_1175.php | 10 +- Zotlabs/Update/_1176.php | 5 +- Zotlabs/Update/_1177.php | 7 +- Zotlabs/Update/_1178.php | 10 +- Zotlabs/Update/_1179.php | 9 +- Zotlabs/Update/_1180.php | 7 +- Zotlabs/Update/_1181.php | 10 +- Zotlabs/Update/_1182.php | 7 +- Zotlabs/Update/_1183.php | 7 +- Zotlabs/Update/_1184.php | 7 +- Zotlabs/Update/_1185.php | 7 +- Zotlabs/Update/_1186.php | 9 +- Zotlabs/Update/_1187.php | 9 +- Zotlabs/Update/_1188.php | 8 +- Zotlabs/Update/_1189.php | 8 +- Zotlabs/Update/_1190.php | 7 +- Zotlabs/Update/_1191.php | 97 +- Zotlabs/Update/_1192.php | 7 +- Zotlabs/Update/_1193.php | 7 +- Zotlabs/Update/_1194.php | 7 +- Zotlabs/Update/_1195.php | 7 +- Zotlabs/Update/_1196.php | 4 +- Zotlabs/Update/_1197.php | 4 +- Zotlabs/Update/_1198.php | 2 - Zotlabs/Update/_1199.php | 4 +- Zotlabs/Update/_1200.php | 5 +- Zotlabs/Update/_1201.php | 5 +- Zotlabs/Update/_1202.php | 1 - Zotlabs/Update/_1203.php | 5 +- Zotlabs/Update/_1204.php | 5 +- Zotlabs/Update/_1205.php | 6 +- Zotlabs/Update/_1206.php | 5 +- Zotlabs/Update/_1207.php | 5 +- Zotlabs/Update/_1208.php | 5 +- Zotlabs/Update/_1209.php | 5 +- Zotlabs/Update/_1210.php | 5 +- Zotlabs/Update/_1211.php | 5 +- Zotlabs/Update/_1212.php | 2 - Zotlabs/Update/_1213.php | 1 - Zotlabs/Update/_1214.php | 2 - Zotlabs/Update/_1215.php | 1 - Zotlabs/Update/_1216.php | 1 - Zotlabs/Update/_1217.php | 2 - Zotlabs/Update/_1218.php | 5 +- Zotlabs/Update/_1219.php | 4 +- Zotlabs/Update/_1220.php | 4 - Zotlabs/Update/_1221.php | 2 - Zotlabs/Update/_1222.php | 1 - Zotlabs/Update/_1223.php | 11 +- Zotlabs/Update/_1224.php | 3 +- Zotlabs/Update/_1225.php | 2 +- Zotlabs/Update/_1226.php | 3 +- Zotlabs/Update/_1227.php | 2 - Zotlabs/Update/_1228.php | 2 - Zotlabs/Update/_1229.php | 2 - Zotlabs/Update/_1230.php | 2 - Zotlabs/Update/_1231.php | 2 - Zotlabs/Update/_1232.php | 2 - Zotlabs/Update/_1233.php | 2 - Zotlabs/Update/_1234.php | 2 - Zotlabs/Update/_1235.php | 6 +- Zotlabs/Update/_1236.php | 2 - Zotlabs/Update/_1237.php | 6 +- Zotlabs/Update/_1238.php | 3 - Zotlabs/Update/_1239.php | 1 - Zotlabs/Update/_1240.php | 3 +- Zotlabs/Update/_1241.php | 2 - Zotlabs/Update/_1242.php | 3 - Zotlabs/Update/_1243.php | 3 - Zotlabs/Update/_1244.php | 2 - Zotlabs/Update/_1245.php | 2 - Zotlabs/Update/_1246.php | 2 - Zotlabs/Update/_1247.php | 2 - Zotlabs/Update/_1248.php | 2 - Zotlabs/Update/_1249.php | 1 - Zotlabs/Update/_1250.php | 2 - Zotlabs/Update/_1251.php | 2 - Zotlabs/Update/_1252.php | 13 +- Zotlabs/Update/_1253.php | 1 - Zotlabs/Update/_1254.php | 4 +- Zotlabs/Web/Controller.php | 2 - Zotlabs/Web/HTTPHeaders.php | 6 - Zotlabs/Web/HTTPSig.php | 17 +- Zotlabs/Web/HttpMeta.php | 7 +- Zotlabs/Web/Router.php | 4 - Zotlabs/Web/Session.php | 291 +- Zotlabs/Web/SessionHandler.php | 14 +- Zotlabs/Web/SubModule.php | 1 - Zotlabs/Web/WebServer.php | 361 +- Zotlabs/Widget/Activity.php | 8 +- Zotlabs/Widget/Activity_filter.php | 29 +- Zotlabs/Widget/Admin.php | 10 +- Zotlabs/Widget/Affinity.php | 5 +- Zotlabs/Widget/Album.php | 17 +- Zotlabs/Widget/Appcategories.php | 12 +- Zotlabs/Widget/Appcloud.php | 4 +- Zotlabs/Widget/Appstore.php | 1 - Zotlabs/Widget/Archive.php | 11 +- Zotlabs/Widget/Bookmarkedchats.php | 9 +- Zotlabs/Widget/Catcloud.php | 18 +- Zotlabs/Widget/Catcloud_wall.php | 7 +- Zotlabs/Widget/Categories.php | 48 +- Zotlabs/Widget/Cdav.php | 25 +- Zotlabs/Widget/Chatroom_list.php | 3 +- Zotlabs/Widget/Chatroom_members.php | 1 - Zotlabs/Widget/Clock.php | 1 - Zotlabs/Widget/Collections.php | 4 +- Zotlabs/Widget/Common_friends.php | 20 +- Zotlabs/Widget/Cover_photo.php | 30 +- Zotlabs/Widget/Design_tools.php | 5 +- Zotlabs/Widget/Dirtags.php | 2 - Zotlabs/Widget/Eventstools.php | 3 +- Zotlabs/Widget/Filer.php | 15 +- Zotlabs/Widget/Findpeople.php | 3 - Zotlabs/Widget/Follow.php | 4 +- Zotlabs/Widget/Fullprofile.php | 1 - Zotlabs/Widget/Groups.php | 16 +- Zotlabs/Widget/Helpindex.php | 3 +- Zotlabs/Widget/Hq_controls.php | 6 +- Zotlabs/Widget/Item.php | 24 +- Zotlabs/Widget/Mailmenu.php | 3 +- Zotlabs/Widget/Menu_preview.php | 4 +- Zotlabs/Widget/Newmember.php | 6 +- Zotlabs/Widget/Notifications.php | 3 +- Zotlabs/Widget/Photo.php | 20 +- Zotlabs/Widget/Photo_albums.php | 1 - Zotlabs/Widget/Photo_rand.php | 34 +- Zotlabs/Widget/Pinned.php | 5 +- Zotlabs/Widget/Portfolio.php | 36 +- Zotlabs/Widget/Profile.php | 3 +- Zotlabs/Widget/Random_block.php | 18 +- Zotlabs/Widget/Rating.php | 18 +- Zotlabs/Widget/Savedsearch.php | 21 +- Zotlabs/Widget/Sblock.php | 1 - Zotlabs/Widget/Settings_menu.php | 85 +- Zotlabs/Widget/Shortprofile.php | 1 - Zotlabs/Widget/Site_projects.php | 2 - Zotlabs/Widget/Sitesearch.php | 4 +- Zotlabs/Widget/Stream_order.php | 23 +- Zotlabs/Widget/Suggestedchats.php | 7 +- Zotlabs/Widget/Suggestions.php | 3 +- Zotlabs/Widget/Tagcloud.php | 1 - Zotlabs/Widget/Tagcloud_wall.php | 9 +- Zotlabs/Widget/Tasklist.php | 2 - Zotlabs/Widget/Vcard.php | 2 - Zotlabs/Widget/Website_portation_tools.php | 10 +- Zotlabs/Zot6/IHandler.php | 2 - Zotlabs/Zot6/Receiver.php | 7 - Zotlabs/Zot6/Zot6Handler.php | 27 +- include/account.php | 1146 +-- include/acl_selectors.php | 258 +- include/addon.php | 1449 ++-- include/api.php | 414 +- include/api_auth.php | 281 +- include/api_zot.php | 1145 +-- include/attach.php | 4129 +++++----- include/auth.php | 545 +- include/bbcode.php | 3390 ++++---- include/channel.php | 3597 +++++---- include/cli_startup.php | 10 +- include/config.php | 142 +- include/connections.php | 1600 ++-- include/conversation.php | 3465 ++++---- include/datetime.php | 662 +- include/dba/dba_driver.php | 487 +- include/dba/dba_pdo.php | 12 +- include/event.php | 2230 ++--- include/features.php | 945 +-- include/feedutils.php | 564 +- include/help.php | 347 +- include/html2bbcode.php | 472 +- include/html2plain.php | 338 +- include/hubloc.php | 414 +- include/import.php | 3326 ++++---- include/items.php | 7620 +++++++++--------- include/js_strings.php | 229 +- include/language.php | 480 +- include/menu.php | 648 +- include/nav.php | 968 +-- include/network.php | 2698 ++++--- include/oauth.php | 38 +- include/oembed.php | 711 +- include/perm_upgrade.php | 467 +- include/permissions.php | 783 +- include/photo_factory.php | 859 +- include/photos.php | 1804 +++-- include/security.php | 1005 +-- include/sharedwithme.php | 48 +- include/socgraph.php | 1036 +-- include/statistics_fns.php | 92 +- include/system_unavailable.php | 10 +- include/taxonomy.php | 1142 +-- include/text.php | 5106 ++++++------ include/xchan.php | 647 +- include/zid.php | 570 +- install/htconfig.sample.php | 28 +- install/migrate-mypg.php | 593 +- install/testargs.php | 16 +- tests/unit/Access/AccessListTest.php | 272 +- tests/unit/Access/PermissionLimitsTest.php | 81 +- tests/unit/Access/PermissionRolesTest.php | 99 +- tests/unit/Access/PermissionsTest.php | 542 +- tests/unit/AntiXSSTest.php | 110 +- tests/unit/AutonameTest.php | 113 +- tests/unit/ContainsAttributeTest.php | 70 +- tests/unit/DatabaseTestCase.php | 55 +- tests/unit/Lib/MarkdownTest.php | 212 +- tests/unit/Lib/PermissionDescriptionTest.php | 107 +- tests/unit/UnitTestCase.php | 6 +- tests/unit/UploadTest.php | 28 +- tests/unit/expand_acl_test.php | 281 +- tests/unit/get_tags_test.php | 505 +- tests/unit/includes/LanguageTest.php | 251 +- tests/unit/includes/TextTest.php | 193 +- tests/unit/includes/dba/DBATest.php | 51 +- tests/unit/includes/dba/dba_pdoTest.php | 259 +- tests/unit/template_test.php | 438 +- util/docblox_errorchecker.php | 160 +- util/php2po.php | 133 +- util/po2php.php | 279 +- util/precompile_smarty3.php | 53 +- util/strings.php | 108 +- util/typo.php | 132 +- util/typohelper.php | 10 +- 712 files changed, 47242 insertions(+), 43902 deletions(-) diff --git a/Zotlabs/Daemon/Addon.php b/Zotlabs/Daemon/Addon.php index 50afea23b..97c473e53 100644 --- a/Zotlabs/Daemon/Addon.php +++ b/Zotlabs/Daemon/Addon.php @@ -2,12 +2,12 @@ namespace Zotlabs\Daemon; +class Addon +{ -class Addon { + public static function run($argc, $argv) + { - public static function run($argc, $argv) { - - call_hooks('daemon_addon',$argv); - - } + call_hooks('daemon_addon', $argv); + } } diff --git a/Zotlabs/Daemon/CacheThumb.php b/Zotlabs/Daemon/CacheThumb.php index 75f17b707..94a419b14 100644 --- a/Zotlabs/Daemon/CacheThumb.php +++ b/Zotlabs/Daemon/CacheThumb.php @@ -1,50 +1,54 @@ - $max_thumb || $height > $max_thumb) { - $imagick_path = get_config('system','imagick_convert_path'); - if ($imagick_path && @file_exists($imagick_path)) { - $tmp_name = $path . '-001'; - $newsize = photo_calculate_scale(array_merge($is,['max' => $max_thumb])); - $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $path) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); + $max_thumb = get_config('system', 'max_cache_thumbnail', 1024); - for ($x = 0; $x < 4; $x ++) { - exec($cmd); - if (file_exists($tmp_name)) { - break; - } - continue; - } - - if (! file_exists($tmp_name)) { - return; - } - @rename($tmp_name,$path); - } - } - } -} \ No newline at end of file + if ($width > $max_thumb || $height > $max_thumb) { + $imagick_path = get_config('system', 'imagick_convert_path'); + if ($imagick_path && @file_exists($imagick_path)) { + $tmp_name = $path . '-001'; + $newsize = photo_calculate_scale(array_merge($is, ['max' => $max_thumb])); + $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $path) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); + + for ($x = 0; $x < 4; $x++) { + exec($cmd); + if (file_exists($tmp_name)) { + break; + } + continue; + } + + if (! file_exists($tmp_name)) { + return; + } + @rename($tmp_name, $path); + } + } + } +} diff --git a/Zotlabs/Daemon/Cache_embeds.php b/Zotlabs/Daemon/Cache_embeds.php index 353fd048a..1698f9741 100644 --- a/Zotlabs/Daemon/Cache_embeds.php +++ b/Zotlabs/Daemon/Cache_embeds.php @@ -2,33 +2,34 @@ namespace Zotlabs\Daemon; +class Cache_embeds +{ -class Cache_embeds { + public static function run($argc, $argv) + { - public static function run($argc, $argv) { + if (! $argc == 2) { + return; + } - if (! $argc == 2) { - return; - } + $c = q( + "select body, html, created from item where id = %d ", + dbesc(intval($argv[1])) + ); - $c = q("select body, html, created from item where id = %d ", - dbesc(intval($argv[1])) - ); + if (! $c) { + return; + } - if (! $c) { - return; - } + $item = array_shift($c); - $item = array_shift($c); + $cache_expire = intval(get_config('system', 'default_expire_days')); + if ($cache_expire <= 0) { + $cache_expire = 60; + } + $cache_enable = ((($cache_expire) && ($item['created'] < datetime_convert('UTC', 'UTC', 'now - ' . $cache_expire . ' days'))) ? false : true); - $cache_expire = intval(get_config('system', 'default_expire_days')); - if ($cache_expire <= 0) { - $cache_expire = 60; - } - $cache_enable = ((($cache_expire) && ($item['created'] < datetime_convert('UTC','UTC', 'now - ' . $cache_expire . ' days'))) ? false : true); - - $s = bbcode($item['body']); - $s = sslify($s, $cache_enable); - - } + $s = bbcode($item['body']); + $s = sslify($s, $cache_enable); + } } diff --git a/Zotlabs/Daemon/Cache_image.php b/Zotlabs/Daemon/Cache_image.php index e960cf09e..0371c7002 100644 --- a/Zotlabs/Daemon/Cache_image.php +++ b/Zotlabs/Daemon/Cache_image.php @@ -4,15 +4,16 @@ namespace Zotlabs\Daemon; use Zotlabs\Lib\Img_cache; -class Cache_image { +class Cache_image +{ - public static function run($argc, $argv) { + public static function run($argc, $argv) + { - cli_startup(); - logger('caching: ' . $argv[1] . ' to ' . $argv[2]); - if ($argc === 3) { - Img_cache::url_to_cache($argv[1],$argv[2]); - } - - } + cli_startup(); + logger('caching: ' . $argv[1] . ' to ' . $argv[2]); + if ($argc === 3) { + Img_cache::url_to_cache($argv[1], $argv[2]); + } + } } diff --git a/Zotlabs/Daemon/Channel_purge.php b/Zotlabs/Daemon/Channel_purge.php index 0c68c8f86..02f49bb7c 100644 --- a/Zotlabs/Daemon/Channel_purge.php +++ b/Zotlabs/Daemon/Channel_purge.php @@ -2,32 +2,35 @@ namespace Zotlabs\Daemon; +class Channel_purge +{ -class Channel_purge { + public static function run($argc, $argv) + { - public static function run($argc, $argv) { + cli_startup(); - cli_startup(); + $channel_id = intval($argv[1]); - $channel_id = intval($argv[1]); + $channel = q( + "select * from channel where channel_id = %d and channel_removed = 1", + intval($channel_id) + ); - $channel = q("select * from channel where channel_id = %d and channel_removed = 1", - intval($channel_id) - ); + if (! $channel) { + return; + } - if (! $channel) { - return; - } - - do { - $r = q("select id from item where uid = %d and item_deleted = 0 limit 1000", - intval($channel_id) - ); - if ($r) { - foreach ($r as $rv) { - drop_item($rv['id'],false); - } - } - } while ($r); - } + do { + $r = q( + "select id from item where uid = %d and item_deleted = 0 limit 1000", + intval($channel_id) + ); + if ($r) { + foreach ($r as $rv) { + drop_item($rv['id'], false); + } + } + } while ($r); + } } diff --git a/Zotlabs/Daemon/Checksites.php b/Zotlabs/Daemon/Checksites.php index 1cb2c48ad..07d632d82 100644 --- a/Zotlabs/Daemon/Checksites.php +++ b/Zotlabs/Daemon/Checksites.php @@ -1,54 +1,66 @@ - 1) && ($argv[1])) - $site_id = $argv[1]; + logger('checksites: start'); - if($site_id) - $sql_options = " and site_url = '" . dbesc($argv[1]) . "' "; + if (($argc > 1) && ($argv[1])) { + $site_id = $argv[1]; + } - $days = intval(get_config('system','sitecheckdays')); - if($days < 1) - $days = 30; + if ($site_id) { + $sql_options = " and site_url = '" . dbesc($argv[1]) . "' "; + } - $r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ", - db_utcnow(), db_quoteinterval($days . ' DAY'), - intval(SITE_TYPE_ZOT) - ); + $days = intval(get_config('system', 'sitecheckdays')); + if ($days < 1) { + $days = 30; + } - if(! $r) - return; + $r = q( + "select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ", + db_utcnow(), + db_quoteinterval($days . ' DAY'), + intval(SITE_TYPE_ZOT) + ); - foreach($r as $rr) { - if(! strcasecmp($rr['site_url'],z_root())) - continue; + if (! $r) { + return; + } - $x = ping_site($rr['site_url']); - if($x['success']) { - logger('checksites: ' . $rr['site_url']); - q("update site set site_update = '%s' where site_url = '%s' ", - dbesc(datetime_convert()), - dbesc($rr['site_url']) - ); - } - else { - logger('marking dead site: ' . $x['message']); - q("update site set site_dead = 1 where site_url = '%s' ", - dbesc($rr['site_url']) - ); - } - } + foreach ($r as $rr) { + if (! strcasecmp($rr['site_url'], z_root())) { + continue; + } - return; - } + $x = ping_site($rr['site_url']); + if ($x['success']) { + logger('checksites: ' . $rr['site_url']); + q( + "update site set site_update = '%s' where site_url = '%s' ", + dbesc(datetime_convert()), + dbesc($rr['site_url']) + ); + } else { + logger('marking dead site: ' . $x['message']); + q( + "update site set site_dead = 1 where site_url = '%s' ", + dbesc($rr['site_url']) + ); + } + } + + return; + } } diff --git a/Zotlabs/Daemon/Content_importer.php b/Zotlabs/Daemon/Content_importer.php index 08588b26c..c1be35d62 100644 --- a/Zotlabs/Daemon/Content_importer.php +++ b/Zotlabs/Daemon/Content_importer.php @@ -8,52 +8,55 @@ require_once('include/cli_startup.php'); require_once('include/attach.php'); require_once('include/import.php'); -class Content_importer { +class Content_importer +{ - public static function run($argc, $argv) { - cli_startup(); + public static function run($argc, $argv) + { + cli_startup(); - $page = $argv[1]; - $since = $argv[2]; - $until = $argv[3]; - $channel_address = $argv[4]; - $hz_server = urldecode($argv[5]); + $page = $argv[1]; + $since = $argv[2]; + $until = $argv[3]; + $channel_address = $argv[4]; + $hz_server = urldecode($argv[5]); - $m = parse_url($hz_server); + $m = parse_url($hz_server); - $channel = channelx_by_nick($channel_address); - if(! $channel) { - logger('itemhelper: channel not found'); - killme(); - } + $channel = channelx_by_nick($channel_address); + if (! $channel) { + logger('itemhelper: channel not found'); + killme(); + } - $headers = [ - 'X-API-Token' => random_string(), - 'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page , - 'Host' => $m['host'], - '(request-target)' => 'get /api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page , - ]; + $headers = [ + 'X-API-Token' => random_string(), + 'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page , + 'Host' => $m['host'], + '(request-target)' => 'get /api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page , + ]; - $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); + $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512'); - $x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]); + $x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page, false, $redirects, [ 'headers' => $headers ]); - if(! $x['success']) { - logger('no API response',LOGGER_DEBUG); - killme(); - } + if (! $x['success']) { + logger('no API response', LOGGER_DEBUG); + killme(); + } - $j = json_decode($x['body'],true); + $j = json_decode($x['body'], true); - if (! $j) { - killme(); - } + if (! $j) { + killme(); + } - if(! ($j['item'] || count($j['item']))) - killme(); + if (! ($j['item'] || count($j['item']))) { + killme(); + } - import_items($channel,$j['item'],false,((array_key_exists('relocate',$j)) ? $j['relocate'] : null)); + import_items($channel, $j['item'], false, ((array_key_exists('relocate', $j)) ? $j['relocate'] : null)); - killme(); - } + killme(); + } } diff --git a/Zotlabs/Daemon/Convo.php b/Zotlabs/Daemon/Convo.php index b44de178a..7a4f2bd1e 100644 --- a/Zotlabs/Daemon/Convo.php +++ b/Zotlabs/Daemon/Convo.php @@ -1,4 +1,4 @@ -get(); + $obj = new ASCollection($id, $channel); - if ($messages) { - foreach ($messages as $message) { - if (is_string($message)) { - $message = Activity::fetch($message,$channel); - } - // set client flag because comments will probably just be objects and not full blown activities - // and that lets us use implied_create - $AS = new ActivityStreams($message, null, true); - if ($AS->is_valid() && is_array($AS->obj)) { - $item = Activity::decode_note($AS,true); - Activity::store($channel,$contact['abook_xchan'],$AS,$item,true,true); - } - } - } - } + $messages = $obj->get(); + + if ($messages) { + foreach ($messages as $message) { + if (is_string($message)) { + $message = Activity::fetch($message, $channel); + } + // set client flag because comments will probably just be objects and not full blown activities + // and that lets us use implied_create + $AS = new ActivityStreams($message, null, true); + if ($AS->is_valid() && is_array($AS->obj)) { + $item = Activity::decode_note($AS, true); + Activity::store($channel, $contact['abook_xchan'], $AS, $item, true, true); + } + } + } + } } diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index 6d6344cc0..b5672e334 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -1,201 +1,221 @@ - $maxsysload) { - logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.'); - return; - } - } + $maxsysload = intval(get_config('system', 'maxloadavg')); + if ($maxsysload < 1) { + $maxsysload = 50; + } + if (function_exists('sys_getloadavg')) { + $load = sys_getloadavg(); + if (intval($load[0]) > $maxsysload) { + logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.'); + return; + } + } - // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. - $lockfile = 'cache/cron'; - if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) - && (! get_config('system','override_cron_lockfile'))) { - logger("cron: Already running"); - return; - } - - // Create a lockfile. Needs two vars, but $x doesn't need to contain anything. - file_put_contents($lockfile, $x); + // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. + $lockfile = 'cache/cron'; + if ( + (file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) + && (! get_config('system', 'override_cron_lockfile')) + ) { + logger("cron: Already running"); + return; + } - logger('cron: start'); - - // run queue delivery process in the background + // Create a lockfile. Needs two vars, but $x doesn't need to contain anything. + file_put_contents($lockfile, $x); - Run::Summon( [ 'Queue' ] ); + logger('cron: start'); - Run::Summon( [ 'Poller' ] ); + // run queue delivery process in the background - // maintenance for mod sharedwithme - check for updated items and remove them + Run::Summon([ 'Queue' ]); - require_once('include/sharedwithme.php'); - apply_updates(); - - // expire any expired items + Run::Summon([ 'Poller' ]); - $r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s + // maintenance for mod sharedwithme - check for updated items and remove them + + require_once('include/sharedwithme.php'); + apply_updates(); + + // expire any expired items + + $r = q( + "select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s and item_deleted = 0 ", - db_utcnow() - ); - if($r) { - require_once('include/items.php'); - foreach($r as $rr) { - drop_item($rr['id'],false,(($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); - if($rr['item_wall']) { - // The notifier isn't normally invoked unless item_drop is interactive. - Run::Summon( [ 'Notifier', 'drop', $rr['id'] ] ); - } - } - } + db_utcnow() + ); + if ($r) { + require_once('include/items.php'); + foreach ($r as $rr) { + drop_item($rr['id'], false, (($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + if ($rr['item_wall']) { + // The notifier isn't normally invoked unless item_drop is interactive. + Run::Summon([ 'Notifier', 'drop', $rr['id'] ]); + } + } + } - // delete expired access tokens + // delete expired access tokens - $r = q("select atoken_id from atoken where atoken_expires > '%s' and atoken_expires < %s", - dbesc(NULL_DATE), - db_utcnow() - ); - if($r) { - require_once('include/security.php'); - foreach($r as $rr) { - atoken_delete($rr['atoken_id']); - } - } + $r = q( + "select atoken_id from atoken where atoken_expires > '%s' and atoken_expires < %s", + dbesc(NULL_DATE), + db_utcnow() + ); + if ($r) { + require_once('include/security.php'); + foreach ($r as $rr) { + atoken_delete($rr['atoken_id']); + } + } - // Ensure that every channel pings their directory occasionally. + // Ensure that every channel pings their directory occasionally. - $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s and channel_removed = 0", - db_utcnow(), - db_quoteinterval('7 DAY') - ); - if($r) { - foreach($r as $rr) { - Run::Summon( [ 'Directory', $rr['channel_id'], 'force' ] ); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } + $r = q( + "select channel_id from channel where channel_dirdate < %s - INTERVAL %s and channel_removed = 0", + db_utcnow(), + db_quoteinterval('7 DAY') + ); + if ($r) { + foreach ($r as $rr) { + Run::Summon([ 'Directory', $rr['channel_id'], 'force' ]); + if ($interval) { + @time_sleep_until(microtime(true) + (float) $interval); + } + } + } - // publish any applicable items that were set to be published in the future - // (time travel posts). Restrict to items that have come of age in the last - // couple of days to limit the query to something reasonable. + // publish any applicable items that were set to be published in the future + // (time travel posts). Restrict to items that have come of age in the last + // couple of days to limit the query to something reasonable. - $r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ", - db_utcnow(), - dbesc(datetime_convert('UTC','UTC','now - 2 days')) - ); - if($r) { - foreach($r as $rr) { - $x = q("update item set item_delayed = 0 where id = %d", - intval($rr['id']) - ); - if($x) { - $z = q("select * from item where id = %d", - intval($message_id) - ); - if($z) { - xchan_query($z); - $sync_item = fetch_post_tags($z); - Libsync::build_sync_packet($sync_item[0]['uid'], - [ - 'item' => [ encode_item($sync_item[0],true) ] - ] - ); - } - Run::Summon( [ 'Notifier','wall-new',$rr['id'] ] ); - } - } - } + $r = q( + "select id from item where item_delayed = 1 and created <= %s and created > '%s' ", + db_utcnow(), + dbesc(datetime_convert('UTC', 'UTC', 'now - 2 days')) + ); + if ($r) { + foreach ($r as $rr) { + $x = q( + "update item set item_delayed = 0 where id = %d", + intval($rr['id']) + ); + if ($x) { + $z = q( + "select * from item where id = %d", + intval($message_id) + ); + if ($z) { + xchan_query($z); + $sync_item = fetch_post_tags($z); + Libsync::build_sync_packet( + $sync_item[0]['uid'], + [ + 'item' => [ encode_item($sync_item[0], true) ] + ] + ); + } + Run::Summon([ 'Notifier','wall-new',$rr['id'] ]); + } + } + } - require_once('include/attach.php'); - attach_upgrade(); + require_once('include/attach.php'); + attach_upgrade(); - $abandon_days = intval(get_config('system','account_abandon_days')); - if($abandon_days < 1) - $abandon_days = 0; - - - // once daily run birthday_updates and then expire in background - - // FIXME: add birthday updates, both locally and for xprof for use - // by directory servers - - $d1 = intval(get_config('system','last_expire_day')); - $d2 = intval(datetime_convert('UTC','UTC','now','d')); - - // Allow somebody to staggger daily activities if they have more than one site on their server, - // or if it happens at an inconvenient (busy) hour. - - $h1 = intval(get_config('system','cron_hour')); - $h2 = intval(datetime_convert('UTC','UTC','now','G')); + $abandon_days = intval(get_config('system', 'account_abandon_days')); + if ($abandon_days < 1) { + $abandon_days = 0; + } - if(($d2 != $d1) && ($h1 == $h2)) { - Run::Summon( [ 'Cron_daily' ] ); - } + // once daily run birthday_updates and then expire in background - // update any photos which didn't get imported properly - // This should be rare + // FIXME: add birthday updates, both locally and for xprof for use + // by directory servers - $r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = '' + $d1 = intval(get_config('system', 'last_expire_day')); + $d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd')); + + // Allow somebody to staggger daily activities if they have more than one site on their server, + // or if it happens at an inconvenient (busy) hour. + + $h1 = intval(get_config('system', 'cron_hour')); + $h2 = intval(datetime_convert('UTC', 'UTC', 'now', 'G')); + + + if (($d2 != $d1) && ($h1 == $h2)) { + Run::Summon([ 'Cron_daily' ]); + } + + // update any photos which didn't get imported properly + // This should be rare + + $r = q( + "select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = '' and xchan_photo_date < %s - INTERVAL %s", - db_utcnow(), - db_quoteinterval('1 DAY') - ); - if($r) { - require_once('include/photo_factory.php'); - foreach($r as $rr) { - $photos = import_remote_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']); - if ($photos) { - $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' + db_utcnow(), + db_quoteinterval('1 DAY') + ); + if ($r) { + require_once('include/photo_factory.php'); + foreach ($r as $rr) { + $photos = import_remote_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash']); + if ($photos) { + $x = q( + "update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($rr['xchan_hash']) - ); - } - } - } + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($rr['xchan_hash']) + ); + } + } + } - $generation = 0; + $generation = 0; - $restart = false; + $restart = false; - if(($argc > 1) && ($argv[1] == 'restart')) { - $restart = true; - $generation = intval($argv[2]); - if(! $generation) - return; - } + if (($argc > 1) && ($argv[1] == 'restart')) { + $restart = true; + $generation = intval($argv[2]); + if (! $generation) { + return; + } + } - reload_plugins(); + reload_plugins(); - $d = datetime_convert(); + $d = datetime_convert(); - // TODO check to see if there are any cronhooks before wasting a process + // TODO check to see if there are any cronhooks before wasting a process - if(! $restart) - Run::Summon( [ 'Cronhooks' ] ); + if (! $restart) { + Run::Summon([ 'Cronhooks' ]); + } - set_config('system','lastcron',datetime_convert()); + set_config('system', 'lastcron', datetime_convert()); - //All done - clear the lockfile - @unlink($lockfile); + //All done - clear the lockfile + @unlink($lockfile); - return; - } + return; + } } diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php index 65c8a6d3d..9ecb02064 100644 --- a/Zotlabs/Daemon/Cron_daily.php +++ b/Zotlabs/Daemon/Cron_daily.php @@ -1,110 +1,122 @@ - %s - INTERVAL %s and channel_deleted < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('21 DAY'), - db_utcnow(), db_quoteinterval('10 DAY') - ); - if($r) { - foreach($r as $rv) { - channel_remove_final($rv['channel_id']); - } - } + db_utcnow(), + db_quoteinterval('21 DAY'), + db_utcnow(), + db_quoteinterval('10 DAY') + ); + if ($r) { + foreach ($r as $rv) { + channel_remove_final($rv['channel_id']); + } + } - // get rid of really old poco records + // get rid of really old poco records - q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ", - db_utcnow(), db_quoteinterval('14 DAY') - ); + q( + "delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ", + db_utcnow(), + db_quoteinterval('14 DAY') + ); - // Check for dead sites - Run::Summon( ['Checksites' ] ); + // Check for dead sites + Run::Summon(['Checksites' ]); - // clean up image cache - use site expiration or 60 days if not set or zero - - $files = glob('cache/img/*/*'); - $expire_days = intval(get_config('system','default_expire_days')); - if ($expire_days <= 0) { - $expire_days = 60; - } - $now = time(); - $maxage = 86400 * $expire_days; - if ($files) { - foreach ($files as $file) { - if (is_file($file)) { - if ($now - filemtime($file) >= $maxage) { - unlink($file); - } - } - } - } + // clean up image cache - use site expiration or 60 days if not set or zero - // update searchable doc indexes + $files = glob('cache/img/*/*'); + $expire_days = intval(get_config('system', 'default_expire_days')); + if ($expire_days <= 0) { + $expire_days = 60; + } + $now = time(); + $maxage = 86400 * $expire_days; + if ($files) { + foreach ($files as $file) { + if (is_file($file)) { + if ($now - filemtime($file) >= $maxage) { + unlink($file); + } + } + } + } - Run::Summon( [ 'Importdoc'] ); + // update searchable doc indexes - /** - * End Cron Weekly - */ + Run::Summon([ 'Importdoc']); - } -} \ No newline at end of file + /** + * End Cron Weekly + */ + } +} diff --git a/Zotlabs/Daemon/Cronhooks.php b/Zotlabs/Daemon/Cronhooks.php index b0fc4ef38..44d9f159e 100644 --- a/Zotlabs/Daemon/Cronhooks.php +++ b/Zotlabs/Daemon/Cronhooks.php @@ -1,17 +1,21 @@ -start(); + App::$session->start(); - $_SESSION['authenticated'] = 1; - $_SESSION['uid'] = $argv[1]; + $_SESSION['authenticated'] = 1; + $_SESSION['uid'] = $argv[1]; - $x = session_id(); + $x = session_id(); - $f = 'cache/cookie_' . $argv[1]; - $c = 'cache/cookien_' . $argv[1]; + $f = 'cache/cookie_' . $argv[1]; + $c = 'cache/cookien_' . $argv[1]; - $e = file_exists($f); + $e = file_exists($f); - $output = ''; + $output = ''; - if($e) { - $lines = file($f); - if($lines) { - foreach($lines as $line) { - if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) { - $tokens = explode("\t", $line); - $tokens = array_map('trim', $tokens); - if($tokens[4] > time()) { - $output .= $line . "\n"; - } - } - else - $output .= $line; - } - } - } - $t = time() + (24 * 3600); - file_put_contents($f, $output . 'HttpOnly_' . App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0)); + if ($e) { + $lines = file($f); + if ($lines) { + foreach ($lines as $line) { + if (strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) { + $tokens = explode("\t", $line); + $tokens = array_map('trim', $tokens); + if ($tokens[4] > time()) { + $output .= $line . "\n"; + } + } else { + $output .= $line; + } + } + } + } + $t = time() + (24 * 3600); + file_put_contents($f, $output . 'HttpOnly_' . App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0)); - file_put_contents($c,$x); + file_put_contents($c, $x); - return; - } + return; + } } diff --git a/Zotlabs/Daemon/Deliver.php b/Zotlabs/Daemon/Deliver.php index 3a0833562..2aecaa1b9 100644 --- a/Zotlabs/Daemon/Deliver.php +++ b/Zotlabs/Daemon/Deliver.php @@ -1,31 +1,36 @@ - 2) { + if ($argv[2] === 'force') { + $force = true; + } + if ($argv[2] === 'nopush') { + $pushall = false; + } + } - $force = false; - $pushall = true; - - if ($argc > 2) { - if ($argv[2] === 'force') { - $force = true; - } - if ($argv[2] === 'nopush') { - $pushall = false; - } - } + logger('directory update', LOGGER_DEBUG); - logger('directory update', LOGGER_DEBUG); + $channel = channelx_by_n($argv[1]); + if (! $channel) { + return; + } - $channel = channelx_by_n($argv[1]); - if (! $channel) { - return; - } + // update the local directory - was optional, but now done regardless - // update the local directory - was optional, but now done regardless - - Libzotdir::local_dir_update($argv[1],$force); + Libzotdir::local_dir_update($argv[1], $force); - q("update channel set channel_dirdate = '%s' where channel_id = %d", - dbesc(datetime_convert()), - intval($channel['channel_id']) - ); + q( + "update channel set channel_dirdate = '%s' where channel_id = %d", + dbesc(datetime_convert()), + intval($channel['channel_id']) + ); - // Now update all the connections - if ($pushall) { - Run::Summon( [ 'Notifier','refresh_all',$channel['channel_id'] ] ); - } - } + // Now update all the connections + if ($pushall) { + Run::Summon([ 'Notifier','refresh_all',$channel['channel_id'] ]); + } + } } diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index e48b4922a..d1214fca6 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -2,90 +2,94 @@ namespace Zotlabs\Daemon; +class Expire +{ -class Expire { + public static function run($argc, $argv) + { - public static function run($argc, $argv){ + cli_startup(); - cli_startup(); + // perform final cleanup on previously delete items - // perform final cleanup on previously delete items + $r = q( + "select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s", + db_utcnow(), + db_quoteinterval('10 DAY') + ); + if ($r) { + foreach ($r as $rr) { + drop_item($rr['id'], false, DROPITEM_PHASE2); + } + } - $r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('10 DAY') - ); - if ($r) { - foreach ($r as $rr) { - drop_item($rr['id'], false, DROPITEM_PHASE2); - } - } + // physically remove anything that has been deleted for more than two months + /** @FIXME - this is a wretchedly inefficient query */ - // physically remove anything that has been deleted for more than two months - /** @FIXME - this is a wretchedly inefficient query */ + $r = q( + "delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s", + db_utcnow(), + db_quoteinterval('36 DAY') + ); - $r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('36 DAY') - ); + logger('expire: start', LOGGER_DEBUG); - logger('expire: start', LOGGER_DEBUG); + $site_expire = intval(get_config('system', 'default_expire_days')); + $commented_days = intval(get_config('system', 'active_expire_days')); - $site_expire = intval(get_config('system', 'default_expire_days')); - $commented_days = intval(get_config('system','active_expire_days')); + logger('site_expire: ' . $site_expire); - logger('site_expire: ' . $site_expire); + $r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true"); - $r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true"); + if ($r) { + foreach ($r as $rr) { + // expire the sys channel separately + if (intval($rr['channel_system'])) { + continue; + } - if ($r) { - foreach ($r as $rr) { + // service class default (if non-zero) over-rides the site default - // expire the sys channel separately - if (intval($rr['channel_system'])) - continue; + $service_class_expire = service_class_fetch($rr['channel_id'], 'expire_days'); + if (intval($service_class_expire)) { + $channel_expire = $service_class_expire; + } else { + $channel_expire = $site_expire; + } - // service class default (if non-zero) over-rides the site default + if ( + intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) || + intval($rr['channel_expire_days'] == 0) + ) { + $expire_days = $channel_expire; + } else { + $expire_days = $rr['channel_expire_days']; + } - $service_class_expire = service_class_fetch($rr['channel_id'], 'expire_days'); - if (intval($service_class_expire)) { - $channel_expire = $service_class_expire; - } - else { - $channel_expire = $site_expire; - } - - if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) || - intval($rr['channel_expire_days'] == 0)) { - $expire_days = $channel_expire; - } - else { - $expire_days = $rr['channel_expire_days']; - } + // if the site or service class expiration is non-zero and less than person expiration, use that + logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG); + item_expire($rr['channel_id'], $expire_days, $commented_days); + } + } - // if the site or service class expiration is non-zero and less than person expiration, use that - logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG); - item_expire($rr['channel_id'], $expire_days, $commented_days); - } - } + $x = get_sys_channel(); + if ($x) { + // this should probably just fetch the channel_expire_days from the sys channel, + // but there's no convenient way to set it. - $x = get_sys_channel(); - if ($x) { + $expire_days = get_config('system', 'sys_expire_days', 30); - // this should probably just fetch the channel_expire_days from the sys channel, - // but there's no convenient way to set it. + if (intval($site_expire) && (intval($site_expire) < intval($expire_days))) { + $expire_days = $site_expire; + } - $expire_days = get_config('system', 'sys_expire_days',30); + logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG); - if (intval($site_expire) && (intval($site_expire) < intval($expire_days))) { - $expire_days = $site_expire; - } + if ($expire_days) { + item_expire($x['channel_id'], $expire_days, $commented_days); + } - logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG); - - if ($expire_days) { - item_expire($x['channel_id'], $expire_days, $commented_days); - } - - logger('Expire: sys: done', LOGGER_DEBUG); - } - } + logger('Expire: sys: done', LOGGER_DEBUG); + } + } } diff --git a/Zotlabs/Daemon/File_importer.php b/Zotlabs/Daemon/File_importer.php index 60cc57abc..55c4469c6 100644 --- a/Zotlabs/Daemon/File_importer.php +++ b/Zotlabs/Daemon/File_importer.php @@ -8,43 +8,45 @@ require_once('include/cli_startup.php'); require_once('include/attach.php'); require_once('include/import.php'); -class File_importer { +class File_importer +{ - public static function run($argc, $argv) { + public static function run($argc, $argv) + { - cli_startup(); + cli_startup(); - $attach_id = $argv[1]; - $channel_address = $argv[2]; - $hz_server = urldecode($argv[3]); + $attach_id = $argv[1]; + $channel_address = $argv[2]; + $hz_server = urldecode($argv[3]); - $m = parse_url($hz_server); + $m = parse_url($hz_server); - $channel = channelx_by_nick($channel_address); - if(! $channel) { - logger('filehelper: channel not found'); - killme(); - } + $channel = channelx_by_nick($channel_address); + if (! $channel) { + logger('filehelper: channel not found'); + killme(); + } - $headers = [ - 'X-API-Token' => random_string(), - 'X-API-Request' => $hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id, - 'Host' => $m['host'], - '(request-target)' => 'get /api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id, - ]; + $headers = [ + 'X-API-Token' => random_string(), + 'X-API-Request' => $hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id, + 'Host' => $m['host'], + '(request-target)' => 'get /api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id, + ]; - $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),true,'sha512'); - $x = z_fetch_url($hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id,false,$redirects,[ 'headers' => $headers ]); + $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512'); + $x = z_fetch_url($hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id, false, $redirects, [ 'headers' => $headers ]); - if(! $x['success']) { - logger('no API response',LOGGER_DEBUG); - return; - } + if (! $x['success']) { + logger('no API response', LOGGER_DEBUG); + return; + } - $j = json_decode($x['body'],true); + $j = json_decode($x['body'], true); - $r = sync_files($channel,[$j]); + $r = sync_files($channel, [$j]); - killme(); - } + killme(); + } } diff --git a/Zotlabs/Daemon/Gprobe.php b/Zotlabs/Daemon/Gprobe.php index d5415265b..88d43b31c 100644 --- a/Zotlabs/Daemon/Gprobe.php +++ b/Zotlabs/Daemon/Gprobe.php @@ -1,4 +1,6 @@ - 3) ? $argv[3] : ''); - $dstname = (($argc > 4) ? $argv[4] : ''); + $srcfile = $argv[2]; + $folder = (($argc > 3) ? $argv[3] : ''); + $dstname = (($argc > 4) ? $argv[4] : ''); - $hash = random_string(); + $hash = random_string(); - $arr = [ - 'src' => $srcfile, - 'filename' => (($dstname) ? $dstname : basename($srcfile)), - 'hash' => $hash, - 'allow_cid' => $channel['channel_allow_cid'], - 'allow_gid' => $channel['channel_allow_gid'], - 'deny_cid' => $channel['channel_deny_cid'], - 'deny_gid' => $channel['channel_deny_gid'], - 'preserve_original' => true, - 'replace' => true - ]; + $arr = [ + 'src' => $srcfile, + 'filename' => (($dstname) ? $dstname : basename($srcfile)), + 'hash' => $hash, + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'], + 'preserve_original' => true, + 'replace' => true + ]; - if($folder) - $arr['folder'] = $folder; + if ($folder) { + $arr['folder'] = $folder; + } - attach_store($channel,$channel['channel_hash'],'import',$arr); + attach_store($channel, $channel['channel_hash'], 'import', $arr); - $sync = attach_export_data($channel,$hash); - if($sync) - Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync))); - - return; - } + $sync = attach_export_data($channel, $hash); + if ($sync) { + Libsync::build_sync_packet($channel['channel_id'], array('file' => array($sync))); + } + + return; + } } diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index d9b43189e..81abc908b 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -1,8 +1,7 @@ - $argv[4] ]; - self::$encoding = 'zot'; - $normal_mode = false; - } - elseif ($cmd === 'keychange') { - self::$channel = channelx_by_n($item_id); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) - ); - if ($r) { - foreach ($r as $rr) { - self::$recipients[] = $rr['abook_xchan']; - } - } - self::$private = false; - self::$packet_type = 'keychange'; - self::$encoded_item = get_pconfig(self::$channel['channel_id'],'system','keychange'); - self::$encoding = 'zot'; - $normal_mode = false; - } - elseif (in_array($cmd, [ 'permissions_update', 'permissions_reject', 'permissions_accept', 'permissions_create' ])) { - - // Get the (single) recipient - - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0", - intval($item_id) - ); - if ($r) { - - $recip = array_shift($r); - $uid = $recip['abook_channel']; - // Get the sender - self::$channel = channelx_by_n($uid); - if (self::$channel) { - - $perm_update = [ 'sender' => self::$channel, 'recipient' => $recip, 'success' => false, 'deliveries' => '' ]; - - switch ($cmd) { - case 'permissions_create': - ActivityPub::permissions_create($perm_update); - break; - case 'permissions_accept': - ActivityPub::permissions_accept($perm_update); - break; - case 'permissions_update': - ActivityPub::permissions_update($perm_update); - break; - - default: - break; - } - if (! $perm_update['success']) { - call_hooks($cmd,$perm_update); - } - - if ($perm_update['success']) { - if ($perm_update['deliveries']) { - self::$deliveries[] = $perm_update['deliveries']; - do_delivery(self::$deliveries); - } - return; - } - else { - self::$recipients[] = $recip['abook_xchan']; - self::$private = false; - self::$packet_type = 'refresh'; - self::$env_recips = [ $recip['xchan_hash'] ]; - } - } - } - } - elseif ($cmd === 'refresh_all') { - logger('notifier: refresh_all: ' . $item_id); - - self::$channel = channelx_by_n($item_id,true); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) - ); - if ($r) { - foreach ($r as $rr) { - self::$recipients[] = $rr['abook_xchan']; - } - } - self::$recipients[] = self::$channel['channel_hash']; - self::$private = false; - self::$packet_type = 'refresh'; - } - elseif ($cmd === 'purge') { - $xchan = $argv[3]; - logger('notifier: purge: ' . $item_id . ' => ' . $xchan); - if (! $xchan) { - return; - } - - self::$channel = channelx_by_n($item_id,true); - self::$recipients = [ $xchan ]; - self::$private = true; - self::$packet_type = 'purge'; - } - elseif ($cmd === 'purge_all') { - logger('notifier: purge_all: ' . $item_id); - self::$channel = channelx_by_n($item_id,true); - - self::$recipients = []; - $r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0", - intval($item_id) - ); - if (! $r) { - return; - } - foreach ($r as $rr) { - self::$recipients[] = $rr['abook_xchan']; - } - - self::$private = false; - self::$packet_type = 'purge'; - } - else { - - // Normal items - - // Fetch the target item - - $r = q("SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1", - intval($item_id) - ); - - if (! $r) { - return; - } - - xchan_query($r); - $r = fetch_post_tags($r); - - $target_item = array_shift($r); - - if($target_item['author']['xchan_network'] === 'anon') { - logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG); - return; - } - - $deleted_item = false; - - if (intval($target_item['item_deleted'])) { - logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG); - $deleted_item = true; - } - - if (! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST, ITEM_TYPE_MAIL ] )) { - - if (intval($target_item['item_type'] == ITEM_TYPE_CUSTOM)) { - - $hookinfo=[ - 'targetitem' => $target_item, - 'deliver' => false - ]; - - call_hooks('customitem_deliver',$hookinfo); - } - - if (! $hookinfo['deliver']) { - logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG); - return; - } - } - - // Check for non published items, but allow an exclusion for transmitting hidden file activities - - if (intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || - intval($target_item['item_blocked']) || - ( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) { - logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); - return; - } - - if (in_array($target_item['verb'], [ ACTIVITY_FOLLOW, ACTIVITY_IGNORE ])) { - logger('not fowarding follow|unfollow->note activity'); - return; - } - - $s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", - intval($target_item['uid']) - ); - if ($s) { - self::$channel = array_shift($s); - } - - if (self::$channel['channel_hash'] !== $target_item['author_xchan'] && self::$channel['channel_hash'] !== $target_item['owner_xchan']) { - logger("notifier: Sending channel is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING); - return; - } - - $thread_is_public = false; - - if ($target_item['mid'] === $target_item['parent_mid']) { - $parent_item = $target_item; - $top_level_post = true; - } - else { - - // fetch the parent item - $r = q("SELECT * from item where id = %d order by id asc", - intval($target_item['parent']) - ); - - if (! $r) { - return; - } - - xchan_query($r); - $r = fetch_post_tags($r); - - $parent_item = array_shift($r); - $top_level_post = false; - $thread_is_public = ((intval($parent_item['item_private'])) ? false : true) ; - } - - // avoid looping of discover items 12/4/2014 - - if ($sys && $parent_item['uid'] == $sys['channel_id']) { - return; - } - - $m = get_iconfig($target_item,'activitypub','signed_data'); - // Re-use existing signature unless the activity type changed to a Tombstone, which won't verify. - if ($m && (! intval($target_item['item_deleted']))) { - self::$encoded_item = json_decode($m,true); - } - else { - self::$encoded_item = array_merge(['@context' => [ - ACTIVITYSTREAMS_JSONLD_REV, - 'https://w3id.org/security/v1', - Activity::ap_schema() - ]], Activity::encode_activity($target_item,true) - ); - self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item,self::$channel); - } - - - logger('target_item: ' . print_r($target_item,true), LOGGER_DEBUG); - logger('encoded: ' . print_r(self::$encoded_item,true), LOGGER_DEBUG); - - // Send comments to the owner to re-deliver to everybody in the conversation - // We only do this if the item in question originated on this site. This prevents looping. - // To clarify, a site accepting a new comment is responsible for sending it to the owner for relay. - // Relaying should never be initiated on a post that arrived from elsewhere. - - // We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this - // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at - // the hostname in the message_id and provides a second (fallback) opinion. - - $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item) && $cmd !== 'hyper') ? true : false); - - $uplink = false; - - // $cmd === 'relay' indicates the owner is sending it to the original recipients - // don't allow the item in the relay command to relay to owner under any circumstances, it will loop - - logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); - logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); - - // tag_deliver'd post which needs to be sent back to the original author - - if (($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) { - logger('notifier: uplink'); - $uplink = true; - self::$packet_type = 'response'; - } - - if (($relay_to_owner || $uplink) && ($cmd !== 'relay')) { - logger('followup relay (upstream delivery)', LOGGER_DEBUG); - $sendto = ($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']; - self::$recipients = [ $sendto ]; - // over-ride upstream recipients if 'replyTo' was set in the parent. - if ($parent_item['replyto'] && (! $uplink)) { - logger('replyto: over-riding owner ' . $sendto, LOGGER_DEBUG); - // unserialise is a no-op if presented with data that wasn't serialised. - $ptr = unserialise($parent_item['replyto']); - if (is_string($ptr)) { - if (ActivityStreams::is_url($sendto)) { - $sendto = $ptr; - self::$recipients = [ $sendto ]; - } - } - elseif (is_array($ptr)) { - $sendto = []; - foreach ($ptr as $rto) { - if (is_string($rto)) { - $sendto[] = $rto; - } - elseif (is_array($rto) && isset($rto['id'])) { - $sendto[] = $rto['id']; - } - } - self::$recipients = $sendto; - } - } - - logger('replyto: upstream recipients ' . print_r($sendto,true), LOGGER_DEBUG); - - - self::$private = true; - $upstream = true; - self::$packet_type = 'response'; - $is_moderated = their_perms_contains($parent_item['uid'],$sendto,'moderated'); - if ($relay_to_owner && $thread_is_public && (! $is_moderated) && (! is_group($parent_item['uid']))) { - if (get_pconfig($target_item['uid'],'system','hyperdrive',true)) { - Run::Summon([ 'Notifier' , 'hyper', $item_id ]); - } - } - - } - else { - if ($cmd === 'relay') { - logger('owner relay (downstream delivery)'); - } - else { - logger('normal (downstream) distribution', LOGGER_DEBUG); - } - $upstream = false; - - if ($parent_item && $parent_item['item_private'] !== $target_item['item_private']) { - - logger('parent_item: ' . $parent_item['id'] . ' item_private: ' . $parent_item['item_private']); - logger('target_item: ' . $target_item['id'] . ' item_private: ' . $target_item['item_private']); - - logger('conversation privacy mismatch - downstream delivery prevented'); - return; - } - - // if our parent is a tag_delivery recipient, uplink to the original author causing - // a delivery fork. - - if (($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) { - // don't uplink a relayed post to the relay owner - if ($parent_item['source_xchan'] !== $parent_item['owner_xchan']) { - logger('notifier: uplinking this item'); - Run::Summon( [ 'Notifier','uplink',$item_id ] ); - } - } - - if ($thread_is_public && $cmd === 'hyper') { - self::$recipients = []; - $r = q("select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 and not abook_xchan in ( '%s', '%s', '%s' ) ", - intval($target_item['uid']), - dbesc($target_item['author_xchan']), - dbesc($target_item['owner_xchan']), - dbesc($target_item['source_xchan']) - ); - if ($r) { - foreach ($r as $rv) { - self::$recipients[] = $rv['abook_xchan']; - } - } - self::$private = false; - } - else { - self::$private = false; - self::$recipients = collect_recipients($parent_item,self::$private); - } - - // @FIXME add any additional recipients such as mentions, etc. - - if ($top_level_post) { - // remove clones who will receive the post via sync - self::$recipients = array_values(array_diff(self::$recipients, [ $target_item['owner_xchan'] ])); - } - - // don't send deletions onward for other people's stuff - - if (intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) { - logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE); - return; - } - } - } - - // Generic delivery section, we have an encoded item and recipients - // Now start the delivery process - - logger('encoded item: ' . print_r(self::$encoded_item,true), LOGGER_DATA, LOG_DEBUG); - - stringify_array_elms(self::$recipients); - if (! self::$recipients) { - logger('no recipients'); - return; - } - - // logger('recipients: ' . print_r(self::$recipients,true), LOGGER_NORMAL, LOG_DEBUG); - - if (! count(self::$env_recips)) { - self::$env_recips = ((self::$private) ? [] : null); - } - - $recip_list = []; - - $details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan - where xchan_hash in (" . protect_sprintf(implode(',',self::$recipients)) . ")"); - - if ($details) { - foreach ($details as $d) { - $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')'; - if (self::$private) { - self::$env_recips[] = $d['xchan_hash']; - } - } - } - - - $narr = [ - 'channel' => self::$channel, - 'upstream' => $upstream, - 'env_recips' => self::$env_recips, - 'recipients' => self::$recipients, - 'item' => $item, - 'target_item' => $target_item, - 'parent_item' => $parent_item, - 'top_level_post' => $top_level_post, - 'private' => self::$private, - 'relay_to_owner' => $relay_to_owner, - 'uplink' => $uplink, - 'cmd' => $cmd, - 'single' => (($cmd === 'single_activity') ? true : false), - 'request' => $request, - 'normal_mode' => $normal_mode, - 'packet_type' => self::$packet_type, - 'queued' => [] - ]; - - call_hooks('notifier_process', $narr); - if ($narr['queued']) { - foreach ($narr['queued'] as $pq) { - self::$deliveries[] = $pq; - } - } - - // notifier_process can alter the recipient list - - self::$recipients = $narr['recipients']; - self::$env_recips = $narr['env_recips']; - - if ((self::$private) && (! self::$env_recips)) { - // shouldn't happen - logger('private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE); - return; - } - - logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG); - - // Now we have collected recipients (except for external mentions, @FIXME) - // Let's reduce this to a set of hubs; checking that the site is not dead. - - $hubs = q("select hubloc.*, site.site_crypto, site.site_flags from hubloc left join site on site_url = hubloc_url - where hubloc_hash in (" . protect_sprintf(implode(',',self::$recipients)) . ") - and hubloc_error = 0 and hubloc_deleted = 0 " - ); - - // public posts won't make it to the local public stream unless there's a recipient on this site. - // This code block sees if it's a public post and localhost is missing, and if so adds an entry for the local sys channel to the $hubs list - - if (! self::$private) { - $found_localhost = false; - if ($hubs) { - foreach ($hubs as $h) { - if ($h['hubloc_url'] === z_root()) { - $found_localhost = true; - break; - } - } - } - if (! $found_localhost) { - $localhub = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_dead from hubloc +class Notifier +{ + + public static $deliveries = []; + public static $recipients = []; + public static $env_recips = []; + public static $packet_type = 'activity'; + public static $encoding = 'activitystreams'; + public static $encoded_item = null; + public static $channel = null; + public static $private = false; + + public static function run($argc, $argv) + { + + if ($argc < 3) { + return; + } + + logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG, LOG_INFO); + + $cmd = $argv[1]; + + $item_id = $argv[2]; + + if (! $item_id) { + return; + } + + self::$deliveries = []; + self::$recipients = []; + self::$env_recips = []; + self::$packet_type = 'activity'; + self::$encoding = 'activitystreams'; + self::$encoded_item = null; + self::$channel = null; + self::$private = false; + + $sys = get_sys_channel(); + + $top_level = false; + + $url_recipients = []; + $normal_mode = true; + + if ($cmd === 'request') { + $xchan = $argv[3]; + if ($argc < 5) { + return; + } + + self::$channel = channelx_by_n($item_id); + + self::$private = true; + self::$recipients[] = $xchan; + self::$packet_type = 'request'; + self::$encoded_item = [ 'message_id' => $argv[4] ]; + self::$encoding = 'zot'; + $normal_mode = false; + } elseif ($cmd === 'keychange') { + self::$channel = channelx_by_n($item_id); + $r = q( + "select abook_xchan from abook where abook_channel = %d", + intval($item_id) + ); + if ($r) { + foreach ($r as $rr) { + self::$recipients[] = $rr['abook_xchan']; + } + } + self::$private = false; + self::$packet_type = 'keychange'; + self::$encoded_item = get_pconfig(self::$channel['channel_id'], 'system', 'keychange'); + self::$encoding = 'zot'; + $normal_mode = false; + } elseif (in_array($cmd, [ 'permissions_update', 'permissions_reject', 'permissions_accept', 'permissions_create' ])) { + // Get the (single) recipient + + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0", + intval($item_id) + ); + if ($r) { + $recip = array_shift($r); + $uid = $recip['abook_channel']; + // Get the sender + self::$channel = channelx_by_n($uid); + if (self::$channel) { + $perm_update = [ 'sender' => self::$channel, 'recipient' => $recip, 'success' => false, 'deliveries' => '' ]; + + switch ($cmd) { + case 'permissions_create': + ActivityPub::permissions_create($perm_update); + break; + case 'permissions_accept': + ActivityPub::permissions_accept($perm_update); + break; + case 'permissions_update': + ActivityPub::permissions_update($perm_update); + break; + + default: + break; + } + if (! $perm_update['success']) { + call_hooks($cmd, $perm_update); + } + + if ($perm_update['success']) { + if ($perm_update['deliveries']) { + self::$deliveries[] = $perm_update['deliveries']; + do_delivery(self::$deliveries); + } + return; + } else { + self::$recipients[] = $recip['abook_xchan']; + self::$private = false; + self::$packet_type = 'refresh'; + self::$env_recips = [ $recip['xchan_hash'] ]; + } + } + } + } elseif ($cmd === 'refresh_all') { + logger('notifier: refresh_all: ' . $item_id); + + self::$channel = channelx_by_n($item_id, true); + $r = q( + "select abook_xchan from abook where abook_channel = %d", + intval($item_id) + ); + if ($r) { + foreach ($r as $rr) { + self::$recipients[] = $rr['abook_xchan']; + } + } + self::$recipients[] = self::$channel['channel_hash']; + self::$private = false; + self::$packet_type = 'refresh'; + } elseif ($cmd === 'purge') { + $xchan = $argv[3]; + logger('notifier: purge: ' . $item_id . ' => ' . $xchan); + if (! $xchan) { + return; + } + + self::$channel = channelx_by_n($item_id, true); + self::$recipients = [ $xchan ]; + self::$private = true; + self::$packet_type = 'purge'; + } elseif ($cmd === 'purge_all') { + logger('notifier: purge_all: ' . $item_id); + self::$channel = channelx_by_n($item_id, true); + + self::$recipients = []; + $r = q( + "select abook_xchan from abook where abook_channel = %d and abook_self = 0", + intval($item_id) + ); + if (! $r) { + return; + } + foreach ($r as $rr) { + self::$recipients[] = $rr['abook_xchan']; + } + + self::$private = false; + self::$packet_type = 'purge'; + } else { + // Normal items + + // Fetch the target item + + $r = q( + "SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1", + intval($item_id) + ); + + if (! $r) { + return; + } + + xchan_query($r); + $r = fetch_post_tags($r); + + $target_item = array_shift($r); + + if ($target_item['author']['xchan_network'] === 'anon') { + logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG); + return; + } + + $deleted_item = false; + + if (intval($target_item['item_deleted'])) { + logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG); + $deleted_item = true; + } + + if (! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST, ITEM_TYPE_MAIL ])) { + if (intval($target_item['item_type'] == ITEM_TYPE_CUSTOM)) { + $hookinfo=[ + 'targetitem' => $target_item, + 'deliver' => false + ]; + + call_hooks('customitem_deliver', $hookinfo); + } + + if (! $hookinfo['deliver']) { + logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG); + return; + } + } + + // Check for non published items, but allow an exclusion for transmitting hidden file activities + + if (intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || + intval($target_item['item_blocked']) || + ( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) { + logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); + return; + } + + if (in_array($target_item['verb'], [ ACTIVITY_FOLLOW, ACTIVITY_IGNORE ])) { + logger('not fowarding follow|unfollow->note activity'); + return; + } + + $s = q( + "select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", + intval($target_item['uid']) + ); + if ($s) { + self::$channel = array_shift($s); + } + + if (self::$channel['channel_hash'] !== $target_item['author_xchan'] && self::$channel['channel_hash'] !== $target_item['owner_xchan']) { + logger("notifier: Sending channel is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING); + return; + } + + $thread_is_public = false; + + if ($target_item['mid'] === $target_item['parent_mid']) { + $parent_item = $target_item; + $top_level_post = true; + } else { + // fetch the parent item + $r = q( + "SELECT * from item where id = %d order by id asc", + intval($target_item['parent']) + ); + + if (! $r) { + return; + } + + xchan_query($r); + $r = fetch_post_tags($r); + + $parent_item = array_shift($r); + $top_level_post = false; + $thread_is_public = ((intval($parent_item['item_private'])) ? false : true) ; + } + + // avoid looping of discover items 12/4/2014 + + if ($sys && $parent_item['uid'] == $sys['channel_id']) { + return; + } + + $m = get_iconfig($target_item, 'activitypub', 'signed_data'); + // Re-use existing signature unless the activity type changed to a Tombstone, which won't verify. + if ($m && (! intval($target_item['item_deleted']))) { + self::$encoded_item = json_decode($m, true); + } else { + self::$encoded_item = array_merge(['@context' => [ + ACTIVITYSTREAMS_JSONLD_REV, + 'https://w3id.org/security/v1', + Activity::ap_schema() + ]], Activity::encode_activity($target_item, true)); + self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item, self::$channel); + } + + + logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG); + logger('encoded: ' . print_r(self::$encoded_item, true), LOGGER_DEBUG); + + // Send comments to the owner to re-deliver to everybody in the conversation + // We only do this if the item in question originated on this site. This prevents looping. + // To clarify, a site accepting a new comment is responsible for sending it to the owner for relay. + // Relaying should never be initiated on a post that arrived from elsewhere. + + // We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this + // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at + // the hostname in the message_id and provides a second (fallback) opinion. + + $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item) && $cmd !== 'hyper') ? true : false); + + $uplink = false; + + // $cmd === 'relay' indicates the owner is sending it to the original recipients + // don't allow the item in the relay command to relay to owner under any circumstances, it will loop + + logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); + logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); + + // tag_deliver'd post which needs to be sent back to the original author + + if (($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) { + logger('notifier: uplink'); + $uplink = true; + self::$packet_type = 'response'; + } + + if (($relay_to_owner || $uplink) && ($cmd !== 'relay')) { + logger('followup relay (upstream delivery)', LOGGER_DEBUG); + $sendto = ($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']; + self::$recipients = [ $sendto ]; + // over-ride upstream recipients if 'replyTo' was set in the parent. + if ($parent_item['replyto'] && (! $uplink)) { + logger('replyto: over-riding owner ' . $sendto, LOGGER_DEBUG); + // unserialise is a no-op if presented with data that wasn't serialised. + $ptr = unserialise($parent_item['replyto']); + if (is_string($ptr)) { + if (ActivityStreams::is_url($sendto)) { + $sendto = $ptr; + self::$recipients = [ $sendto ]; + } + } elseif (is_array($ptr)) { + $sendto = []; + foreach ($ptr as $rto) { + if (is_string($rto)) { + $sendto[] = $rto; + } elseif (is_array($rto) && isset($rto['id'])) { + $sendto[] = $rto['id']; + } + } + self::$recipients = $sendto; + } + } + + logger('replyto: upstream recipients ' . print_r($sendto, true), LOGGER_DEBUG); + + + self::$private = true; + $upstream = true; + self::$packet_type = 'response'; + $is_moderated = their_perms_contains($parent_item['uid'], $sendto, 'moderated'); + if ($relay_to_owner && $thread_is_public && (! $is_moderated) && (! is_group($parent_item['uid']))) { + if (get_pconfig($target_item['uid'], 'system', 'hyperdrive', true)) { + Run::Summon([ 'Notifier' , 'hyper', $item_id ]); + } + } + } else { + if ($cmd === 'relay') { + logger('owner relay (downstream delivery)'); + } else { + logger('normal (downstream) distribution', LOGGER_DEBUG); + } + $upstream = false; + + if ($parent_item && $parent_item['item_private'] !== $target_item['item_private']) { + logger('parent_item: ' . $parent_item['id'] . ' item_private: ' . $parent_item['item_private']); + logger('target_item: ' . $target_item['id'] . ' item_private: ' . $target_item['item_private']); + + logger('conversation privacy mismatch - downstream delivery prevented'); + return; + } + + // if our parent is a tag_delivery recipient, uplink to the original author causing + // a delivery fork. + + if (($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) { + // don't uplink a relayed post to the relay owner + if ($parent_item['source_xchan'] !== $parent_item['owner_xchan']) { + logger('notifier: uplinking this item'); + Run::Summon([ 'Notifier','uplink',$item_id ]); + } + } + + if ($thread_is_public && $cmd === 'hyper') { + self::$recipients = []; + $r = q( + "select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 and not abook_xchan in ( '%s', '%s', '%s' ) ", + intval($target_item['uid']), + dbesc($target_item['author_xchan']), + dbesc($target_item['owner_xchan']), + dbesc($target_item['source_xchan']) + ); + if ($r) { + foreach ($r as $rv) { + self::$recipients[] = $rv['abook_xchan']; + } + } + self::$private = false; + } else { + self::$private = false; + self::$recipients = collect_recipients($parent_item, self::$private); + } + + // @FIXME add any additional recipients such as mentions, etc. + + if ($top_level_post) { + // remove clones who will receive the post via sync + self::$recipients = array_values(array_diff(self::$recipients, [ $target_item['owner_xchan'] ])); + } + + // don't send deletions onward for other people's stuff + + if (intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) { + logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE); + return; + } + } + } + + // Generic delivery section, we have an encoded item and recipients + // Now start the delivery process + + logger('encoded item: ' . print_r(self::$encoded_item, true), LOGGER_DATA, LOG_DEBUG); + + stringify_array_elms(self::$recipients); + if (! self::$recipients) { + logger('no recipients'); + return; + } + + // logger('recipients: ' . print_r(self::$recipients,true), LOGGER_NORMAL, LOG_DEBUG); + + if (! count(self::$env_recips)) { + self::$env_recips = ((self::$private) ? [] : null); + } + + $recip_list = []; + + $details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan + where xchan_hash in (" . protect_sprintf(implode(',', self::$recipients)) . ")"); + + if ($details) { + foreach ($details as $d) { + $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')'; + if (self::$private) { + self::$env_recips[] = $d['xchan_hash']; + } + } + } + + + $narr = [ + 'channel' => self::$channel, + 'upstream' => $upstream, + 'env_recips' => self::$env_recips, + 'recipients' => self::$recipients, + 'item' => $item, + 'target_item' => $target_item, + 'parent_item' => $parent_item, + 'top_level_post' => $top_level_post, + 'private' => self::$private, + 'relay_to_owner' => $relay_to_owner, + 'uplink' => $uplink, + 'cmd' => $cmd, + 'single' => (($cmd === 'single_activity') ? true : false), + 'request' => $request, + 'normal_mode' => $normal_mode, + 'packet_type' => self::$packet_type, + 'queued' => [] + ]; + + call_hooks('notifier_process', $narr); + if ($narr['queued']) { + foreach ($narr['queued'] as $pq) { + self::$deliveries[] = $pq; + } + } + + // notifier_process can alter the recipient list + + self::$recipients = $narr['recipients']; + self::$env_recips = $narr['env_recips']; + + if ((self::$private) && (! self::$env_recips)) { + // shouldn't happen + logger('private message with no envelope recipients.' . print_r($argv, true), LOGGER_NORMAL, LOG_NOTICE); + return; + } + + logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list, true), LOGGER_DEBUG); + + // Now we have collected recipients (except for external mentions, @FIXME) + // Let's reduce this to a set of hubs; checking that the site is not dead. + + $hubs = q("select hubloc.*, site.site_crypto, site.site_flags from hubloc left join site on site_url = hubloc_url + where hubloc_hash in (" . protect_sprintf(implode(',', self::$recipients)) . ") + and hubloc_error = 0 and hubloc_deleted = 0 "); + + // public posts won't make it to the local public stream unless there's a recipient on this site. + // This code block sees if it's a public post and localhost is missing, and if so adds an entry for the local sys channel to the $hubs list + + if (! self::$private) { + $found_localhost = false; + if ($hubs) { + foreach ($hubs as $h) { + if ($h['hubloc_url'] === z_root()) { + $found_localhost = true; + break; + } + } + } + if (! $found_localhost) { + $localhub = q( + "select hubloc.*, site.site_crypto, site.site_flags, site.site_dead from hubloc left join site on site_url = hubloc_url where hubloc_id_url = '%s' and hubloc_error = 0 and hubloc_deleted = 0 ", - dbesc(z_root() . '/channel/sys') - ); - if ($localhub) { - $hubs = array_merge($hubs,$localhub); - } - } - } + dbesc(z_root() . '/channel/sys') + ); + if ($localhub) { + $hubs = array_merge($hubs, $localhub); + } + } + } - if (! $hubs) { - logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE); - return; - } + if (! $hubs) { + logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE); + return; + } - /** - * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, - * since it may have been a re-install which has not yet been detected and pruned. - * For other networks which don't have or require sitekeys, we'll have to use the URL - */ + /** + * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, + * since it may have been a re-install which has not yet been detected and pruned. + * For other networks which don't have or require sitekeys, we'll have to use the URL + */ - $hublist = []; // this provides an easily printable list for the logs - $dhubs = []; // delivery hubs where we store our resulting unique array - $keys = []; // array of keys to check uniquness for zot hubs - $urls = []; // array of urls to check uniqueness of hubs from other networks - $hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all - $dead = []; // known dead hubs - report them as undeliverable - - foreach ($hubs as $hub) { - if (isset($hub['site_dead']) && intval($hub['site_dead'])) { - $dead[] = $hub; - continue; - } + $hublist = []; // this provides an easily printable list for the logs + $dhubs = []; // delivery hubs where we store our resulting unique array + $keys = []; // array of keys to check uniquness for zot hubs + $urls = []; // array of urls to check uniqueness of hubs from other networks + $hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all + $dead = []; // known dead hubs - report them as undeliverable + + foreach ($hubs as $hub) { + if (isset($hub['site_dead']) && intval($hub['site_dead'])) { + $dead[] = $hub; + continue; + } - if (self::$env_recips) { - foreach (self::$env_recips as $er) { - if ($hub['hubloc_hash'] === $er) { - if (! array_key_exists($hub['hubloc_site_id'], $hub_env)) { - $hub_env[$hub['hubloc_site_id']] = []; - } - $hub_env[$hub['hubloc_site_id']][] = $er; - } - } - } - + if (self::$env_recips) { + foreach (self::$env_recips as $er) { + if ($hub['hubloc_hash'] === $er) { + if (! array_key_exists($hub['hubloc_site_id'], $hub_env)) { + $hub_env[$hub['hubloc_site_id']] = []; + } + $hub_env[$hub['hubloc_site_id']][] = $er; + } + } + } + - if ($hub['hubloc_network'] === 'zot6') { - if (! in_array($hub['hubloc_sitekey'],$keys)) { - $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; - $dhubs[] = $hub; - $keys[] = $hub['hubloc_sitekey']; - } - } - else { - if (! in_array($hub['hubloc_url'],$urls)) { - $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; - $dhubs[] = $hub; - $urls[] = $hub['hubloc_url']; - } - } - } + if ($hub['hubloc_network'] === 'zot6') { + if (! in_array($hub['hubloc_sitekey'], $keys)) { + $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; + $dhubs[] = $hub; + $keys[] = $hub['hubloc_sitekey']; + } + } else { + if (! in_array($hub['hubloc_url'], $urls)) { + $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; + $dhubs[] = $hub; + $urls[] = $hub['hubloc_url']; + } + } + } - logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG); + logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist, true), LOGGER_DEBUG, LOG_DEBUG); - foreach ($dhubs as $hub) { - - logger('notifier_hub: ' . $hub['hubloc_url'],LOGGER_DEBUG, LOG_DEBUG); + foreach ($dhubs as $hub) { + logger('notifier_hub: ' . $hub['hubloc_url'], LOGGER_DEBUG, LOG_DEBUG); - // deliver to any non-zot networks + // deliver to any non-zot networks - if ($hub['hubloc_network'] !== 'zot6') { - $narr = [ - 'channel' => self::$channel, - 'upstream' => $upstream, - 'env_recips' => self::$env_recips, - 'recipients' => self::$recipients, - 'item' => $item, - 'target_item' => $target_item, - 'parent_item' => $parent_item, - 'hub' => $hub, - 'top_level_post' => $top_level_post, - 'private' => self::$private, - 'relay_to_owner' => $relay_to_owner, - 'uplink' => $uplink, - 'cmd' => $cmd, - 'single' => (($cmd === 'single_activity') ? true : false), - 'request' => $request, - 'normal_mode' => $normal_mode, - 'packet_type' => self::$packet_type, - 'queued' => [] - ]; + if ($hub['hubloc_network'] !== 'zot6') { + $narr = [ + 'channel' => self::$channel, + 'upstream' => $upstream, + 'env_recips' => self::$env_recips, + 'recipients' => self::$recipients, + 'item' => $item, + 'target_item' => $target_item, + 'parent_item' => $parent_item, + 'hub' => $hub, + 'top_level_post' => $top_level_post, + 'private' => self::$private, + 'relay_to_owner' => $relay_to_owner, + 'uplink' => $uplink, + 'cmd' => $cmd, + 'single' => (($cmd === 'single_activity') ? true : false), + 'request' => $request, + 'normal_mode' => $normal_mode, + 'packet_type' => self::$packet_type, + 'queued' => [] + ]; - ActivityPub::notifier_process($narr); + ActivityPub::notifier_process($narr); - call_hooks('notifier_hub',$narr); - if($narr['queued']) { - foreach($narr['queued'] as $pq) - self::$deliveries[] = $pq; - } - continue; - } + call_hooks('notifier_hub', $narr); + if ($narr['queued']) { + foreach ($narr['queued'] as $pq) { + self::$deliveries[] = $pq; + } + } + continue; + } // Single deliveries are for non-nomadic federated networks and we're essentially - // delivering only to those that have this site url in their abook_instance - // and only from within a sync operation. This means if you post from a clone, - // and a connection is connected to one of your other clones; assuming that hub - // is running it will receive a sync packet. On receipt of this sync packet it - // will invoke a delivery to those connections which are connected to just that - // hub instance. + // delivering only to those that have this site url in their abook_instance + // and only from within a sync operation. This means if you post from a clone, + // and a connection is connected to one of your other clones; assuming that hub + // is running it will receive a sync packet. On receipt of this sync packet it + // will invoke a delivery to those connections which are connected to just that + // hub instance. - if ($cmd === 'single_activity') { - continue; - } + if ($cmd === 'single_activity') { + continue; + } - // default: zot protocol + // default: zot protocol - // Prevent zot6 delivery of group comment boosts, which are not required for conversational platforms. - // ActivityPub conversational platforms may wish to filter these if they don't want or require them. - // We will assume here that if $target_item exists and has a verb that it is an actual item structure - // so we won't need to check the existence of the other item fields prior to evaluation. + // Prevent zot6 delivery of group comment boosts, which are not required for conversational platforms. + // ActivityPub conversational platforms may wish to filter these if they don't want or require them. + // We will assume here that if $target_item exists and has a verb that it is an actual item structure + // so we won't need to check the existence of the other item fields prior to evaluation. - // This shouldn't produce false positives on comment boosts that were generated on other platforms - // because we won't be delivering them. - - if (isset($target_item) && isset($target_item['verb']) && $target_item['verb'] === 'Announce' && $target_item['author_xchan'] === $target_item['owner_xchan'] && ! intval($target_item['item_thread_top'])) { - continue; - } + // This shouldn't produce false positives on comment boosts that were generated on other platforms + // because we won't be delivering them. + + if (isset($target_item) && isset($target_item['verb']) && $target_item['verb'] === 'Announce' && $target_item['author_xchan'] === $target_item['owner_xchan'] && ! intval($target_item['item_thread_top'])) { + continue; + } - $hash = new_uuid(); + $hash = new_uuid(); - $env = (($hub_env && $hub_env[$hub['hubloc_site_id']]) ? $hub_env[$hub['hubloc_site_id']] : ''); - if ((self::$private) && (! $env)) { - continue; - } + $env = (($hub_env && $hub_env[$hub['hubloc_site_id']]) ? $hub_env[$hub['hubloc_site_id']] : ''); + if ((self::$private) && (! $env)) { + continue; + } - $packet = Libzot::build_packet(self::$channel, self::$packet_type, $env, self::$encoded_item, self::$encoding, - ((self::$private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto']); + $packet = Libzot::build_packet( + self::$channel, + self::$packet_type, + $env, + self::$encoded_item, + self::$encoding, + ((self::$private) ? $hub['hubloc_sitekey'] : null), + $hub['site_crypto'] + ); - Queue::insert( - [ - 'hash' => $hash, - 'account_id' => self::$channel['channel_account_id'], - 'channel_id' => self::$channel['channel_id'], - 'posturl' => $hub['hubloc_callback'], - 'notify' => $packet, - 'msg' => EMPTY_STR - ] - ); + Queue::insert( + [ + 'hash' => $hash, + 'account_id' => self::$channel['channel_account_id'], + 'channel_id' => self::$channel['channel_id'], + 'posturl' => $hub['hubloc_callback'], + 'notify' => $packet, + 'msg' => EMPTY_STR + ] + ); - // only create delivery reports for normal undeleted items - if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) + // only create delivery reports for normal undeleted items + if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system', 'disable_dreport'))) { + q( + "insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) values ( '%s', '%s','%s','%s','%s','%s','%s','%s', '%s' ) ", - dbesc($target_item['mid']), - dbesc($hub['hubloc_host']), - dbesc($hub['hubloc_host']), - dbesc($hub['hubloc_host']), - dbesc('queued'), - dbesc(datetime_convert()), - dbesc(self::$channel['channel_hash']), - dbesc($hash), - dbesc(EMPTY_STR) - ); - } + dbesc($target_item['mid']), + dbesc($hub['hubloc_host']), + dbesc($hub['hubloc_host']), + dbesc($hub['hubloc_host']), + dbesc('queued'), + dbesc(datetime_convert()), + dbesc(self::$channel['channel_hash']), + dbesc($hash), + dbesc(EMPTY_STR) + ); + } - self::$deliveries[] = $hash; - } - - if ($normal_mode) { - // This wastes a process if there are no delivery hooks configured, so check this before launching the new process - $x = q("select * from hook where hook = 'notifier_normal'"); - if ($x) { - Run::Summon( [ 'Deliver_hooks', $target_item['id'] ] ); - } - } + self::$deliveries[] = $hash; + } + + if ($normal_mode) { + // This wastes a process if there are no delivery hooks configured, so check this before launching the new process + $x = q("select * from hook where hook = 'notifier_normal'"); + if ($x) { + Run::Summon([ 'Deliver_hooks', $target_item['id'] ]); + } + } - if (self::$deliveries) { - do_delivery(self::$deliveries); - } + if (self::$deliveries) { + do_delivery(self::$deliveries); + } - if ($dead) { - foreach ($dead as $deceased) { - if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) + if ($dead) { + foreach ($dead as $deceased) { + if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system', 'disable_dreport'))) { + q( + "insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) values ( '%s', '%s','%s','%s','%s','%s','%s','%s','%s' ) ", - dbesc($target_item['mid']), - dbesc($deceased['hubloc_host']), - dbesc($deceased['hubloc_host']), - dbesc($deceased['hubloc_host']), - dbesc('undeliverable/unresponsive site'), - dbesc(datetime_convert()), - dbesc(self::$channel['channel_hash']), - dbesc(new_uuid()), - dbesc(EMPTY_STR) - ); - } - } - } + dbesc($target_item['mid']), + dbesc($deceased['hubloc_host']), + dbesc($deceased['hubloc_host']), + dbesc($deceased['hubloc_host']), + dbesc('undeliverable/unresponsive site'), + dbesc(datetime_convert()), + dbesc(self::$channel['channel_hash']), + dbesc(new_uuid()), + dbesc(EMPTY_STR) + ); + } + } + } - call_hooks('notifier_end',$target_item); + call_hooks('notifier_end', $target_item); - logger('notifer: complete.'); - - - - - return; - - } + logger('notifer: complete.'); + + return; + } } - diff --git a/Zotlabs/Daemon/Onedirsync.php b/Zotlabs/Daemon/Onedirsync.php index bc2e7c4b0..5e3943169 100644 --- a/Zotlabs/Daemon/Onedirsync.php +++ b/Zotlabs/Daemon/Onedirsync.php @@ -1,75 +1,87 @@ - 1) && (intval($argv[1]))) - $update_id = intval($argv[1]); + if (($argc > 1) && (intval($argv[1]))) { + $update_id = intval($argv[1]); + } - if(! $update_id) { - logger('onedirsync: no update'); - return; - } - - $r = q("select * from updates where ud_id = %d limit 1", - intval($update_id) - ); + if (! $update_id) { + logger('onedirsync: no update'); + return; + } - if(! $r) - return; - if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr'])) - return; + $r = q( + "select * from updates where ud_id = %d limit 1", + intval($update_id) + ); - // Have we probed this channel more recently than the other directory server - // (where we received this update from) ? - // If we have, we don't need to do anything except mark any older entries updated + if (! $r) { + return; + } + if (($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr'])) { + return; + } - $x = q("select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1", - dbesc($r[0]['ud_addr']), - dbesc($r[0]['ud_date']), - intval(UPDATE_FLAGS_UPDATED) - ); - if($x) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'", - intval(UPDATE_FLAGS_UPDATED), - dbesc($r[0]['ud_addr']), - intval(UPDATE_FLAGS_UPDATED), - dbesc($x[0]['ud_date']) - ); - return; - } + // Have we probed this channel more recently than the other directory server + // (where we received this update from) ? + // If we have, we don't need to do anything except mark any older entries updated - // ignore doing an update if this ud_addr refers to a known dead hubloc + $x = q( + "select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1", + dbesc($r[0]['ud_addr']), + dbesc($r[0]['ud_date']), + intval(UPDATE_FLAGS_UPDATED) + ); + if ($x) { + $y = q( + "update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'", + intval(UPDATE_FLAGS_UPDATED), + dbesc($r[0]['ud_addr']), + intval(UPDATE_FLAGS_UPDATED), + dbesc($x[0]['ud_date']) + ); + return; + } - $h = q("select * from hubloc where hubloc_addr = '%s' limit 1", - dbesc($r[0]['ud_addr']) - ); - if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ", - intval(UPDATE_FLAGS_UPDATED), - dbesc($r[0]['ud_addr']), - intval(UPDATE_FLAGS_UPDATED) - ); + // ignore doing an update if this ud_addr refers to a known dead hubloc - return; - } + $h = q( + "select * from hubloc where hubloc_addr = '%s' limit 1", + dbesc($r[0]['ud_addr']) + ); + if (($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) { + $y = q( + "update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ", + intval(UPDATE_FLAGS_UPDATED), + dbesc($r[0]['ud_addr']), + intval(UPDATE_FLAGS_UPDATED) + ); - // we might have to pull this out some day, but for now update_directory_entry() - // runs zot_finger() and is kind of zot specific + return; + } - if($h && $h[0]['hubloc_network'] !== 'zot6') - return; + // we might have to pull this out some day, but for now update_directory_entry() + // runs zot_finger() and is kind of zot specific - Libzotdir::update_directory_entry($r[0]); + if ($h && $h[0]['hubloc_network'] !== 'zot6') { + return; + } - return; - } + Libzotdir::update_directory_entry($r[0]); + + return; + } } diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 6c1372643..b9d48ba13 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -1,4 +1,6 @@ - 1) && (intval($argv[1]))) - $contact_id = intval($argv[1]); + logger('onepoll: start'); - if(! $contact_id) { - logger('onepoll: no contact'); - return; - } + if (($argc > 1) && (intval($argv[1]))) { + $contact_id = intval($argv[1]); + } - $d = datetime_convert(); + if (! $contact_id) { + logger('onepoll: no contact'); + return; + } - $contacts = q("SELECT abook.*, xchan.*, account.* + $d = datetime_convert(); + + $contacts = q( + "SELECT abook.*, xchan.*, account.* FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan where abook_id = %d and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0 AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1", - intval($contact_id), - intval(ACCOUNT_OK), - intval(ACCOUNT_UNVERIFIED) - ); + intval($contact_id), + intval(ACCOUNT_OK), + intval(ACCOUNT_UNVERIFIED) + ); - if(! $contacts) { - logger('onepoll: abook_id not found: ' . $contact_id); - return; - } + if (! $contacts) { + logger('onepoll: abook_id not found: ' . $contact_id); + return; + } - $contact = array_shift($contacts); + $contact = array_shift($contacts); - $t = $contact['abook_updated']; + $t = $contact['abook_updated']; - $importer_uid = $contact['abook_channel']; - - $r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", - intval($importer_uid) - ); + $importer_uid = $contact['abook_channel']; - if(! $r) - return; + $r = q( + "SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", + intval($importer_uid) + ); - $importer = $r[0]; + if (! $r) { + return; + } - logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}"); + $importer = $r[0]; - $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE)) - ? datetime_convert('UTC','UTC','now - 7 days') - : datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days') - ); + logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}"); - if($contact['xchan_network'] === 'zot6') { + $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE)) + ? datetime_convert('UTC', 'UTC', 'now - 7 days') + : datetime_convert('UTC', 'UTC', $contact['abook_updated'] . ' - 2 days') + ); - // update permissions + if ($contact['xchan_network'] === 'zot6') { + // update permissions - $x = Libzot::refresh($contact,$importer); + $x = Libzot::refresh($contact, $importer); - $responded = false; - $updated = datetime_convert(); - $connected = datetime_convert(); - if(! $x) { - // mark for death by not updating abook_connected, this is caught in include/poller.php - q("update abook set abook_updated = '%s' where abook_id = %d", - dbesc($updated), - intval($contact['abook_id']) - ); - } - else { - q("update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d", - dbesc($updated), - dbesc($connected), - intval($contact['abook_id']) - ); - $responded = true; - } + $responded = false; + $updated = datetime_convert(); + $connected = datetime_convert(); + if (! $x) { + // mark for death by not updating abook_connected, this is caught in include/poller.php + q( + "update abook set abook_updated = '%s' where abook_id = %d", + dbesc($updated), + intval($contact['abook_id']) + ); + } else { + q( + "update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d", + dbesc($updated), + dbesc($connected), + intval($contact['abook_id']) + ); + $responded = true; + } - if (! $responded) { - return; - } - } - - $fetch_feed = true; + if (! $responded) { + return; + } + } - // They haven't given us permission to see their stream + $fetch_feed = true; - $can_view_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'their_perms','view_stream')); + // They haven't given us permission to see their stream - if (! $can_view_stream) { - $fetch_feed = false; - } + $can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream')); - // we haven't given them permission to send us their stream + if (! $can_view_stream) { + $fetch_feed = false; + } - $can_send_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'my_perms','send_stream')); - - if (! $can_send_stream) { - $fetch_feed = false; - } + // we haven't given them permission to send us their stream - if ($contact['abook_created'] < datetime_convert('UTC','UTC', 'now - 1 week')) { - $fetch_feed = false; - } + $can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream')); - // In previous releases there was a mechanism to fetch 'external' or public stream posts from a site - // (as opposed to a channel). This mechanism was deprecated as there is no reliable/scalable method - // for informing downstream publishers when/if the content has expired or been deleted. - // We can use the ThreadListener interface to implement this on the owner's outbox, however this is still a - // work in progress and may present scaling issues. Making this work correctly with third-party fetches is - // prohibitive as deletion requests would need to be relayed over potentially hostile networks. + if (! $can_send_stream) { + $fetch_feed = false; + } - if($fetch_feed) { - $max = intval(get_config('system','max_imported_posts',20)); - if (intval($max)) { - $cl = get_xconfig($xchan,'activitypub','collections'); - if (is_array($cl) && $cl) { - $url = ((array_key_exists('outbox',$cl)) ? $cl['outbox'] : ''); - if ($url) { - logger('fetching outbox'); - $url = $url . '?date_begin=' . urlencode($last_update); - $obj = new ASCollection($url, $importer, 0, $max); - $messages = $obj->get(); - if ($messages) { - foreach($messages as $message) { - if (is_string($message)) { - $message = Activity::fetch($message,$importer); - } - if (is_array($message)) { - $AS = new ActivityStreams($message,null,true); - if ($AS->is_valid() && is_array($AS->obj)) { - $item = Activity::decode_note($AS,true); - if ($item) { - Activity::store($importer,$contact['abook_xchan'],$AS, $item, true, true); - } - } - } - } - } - } - } - } - } + if ($contact['abook_created'] < datetime_convert('UTC', 'UTC', 'now - 1 week')) { + $fetch_feed = false; + } - // update the poco details for this connection + // In previous releases there was a mechanism to fetch 'external' or public stream posts from a site + // (as opposed to a channel). This mechanism was deprecated as there is no reliable/scalable method + // for informing downstream publishers when/if the content has expired or been deleted. + // We can use the ThreadListener interface to implement this on the owner's outbox, however this is still a + // work in progress and may present scaling issues. Making this work correctly with third-party fetches is + // prohibitive as deletion requests would need to be relayed over potentially hostile networks. - $r = q("SELECT xlink_id from xlink + if ($fetch_feed) { + $max = intval(get_config('system', 'max_imported_posts', 20)); + if (intval($max)) { + $cl = get_xconfig($xchan, 'activitypub', 'collections'); + if (is_array($cl) && $cl) { + $url = ((array_key_exists('outbox', $cl)) ? $cl['outbox'] : ''); + if ($url) { + logger('fetching outbox'); + $url = $url . '?date_begin=' . urlencode($last_update); + $obj = new ASCollection($url, $importer, 0, $max); + $messages = $obj->get(); + if ($messages) { + foreach ($messages as $message) { + if (is_string($message)) { + $message = Activity::fetch($message, $importer); + } + if (is_array($message)) { + $AS = new ActivityStreams($message, null, true); + if ($AS->is_valid() && is_array($AS->obj)) { + $item = Activity::decode_note($AS, true); + if ($item) { + Activity::store($importer, $contact['abook_xchan'], $AS, $item, true, true); + } + } + } + } + } + } + } + } + } + + // update the poco details for this connection + + $r = q( + "SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", - intval($contact['xchan_hash']), - db_utcnow(), db_quoteinterval('7 DAY') - ); - if(! $r) { - poco_load($contact['xchan_hash'],$contact['xchan_connurl']); - } - return; - } + intval($contact['xchan_hash']), + db_utcnow(), + db_quoteinterval('7 DAY') + ); + if (! $r) { + poco_load($contact['xchan_hash'], $contact['xchan_connurl']); + } + return; + } } diff --git a/Zotlabs/Daemon/Poller.php b/Zotlabs/Daemon/Poller.php index ace58b35b..d251f2b13 100644 --- a/Zotlabs/Daemon/Poller.php +++ b/Zotlabs/Daemon/Poller.php @@ -1,79 +1,90 @@ - $maxsysload) { - logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.'); - return; - } - } + $maxsysload = intval(get_config('system', 'maxloadavg')); + if ($maxsysload < 1) { + $maxsysload = 50; + } + if (function_exists('sys_getloadavg')) { + $load = sys_getloadavg(); + if (intval($load[0]) > $maxsysload) { + logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.'); + return; + } + } - $interval = intval(get_config('system','poll_interval')); - if(! $interval) - $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval'))); + $interval = intval(get_config('system', 'poll_interval')); + if (! $interval) { + $interval = ((get_config('system', 'delivery_interval') === false) ? 3 : intval(get_config('system', 'delivery_interval'))); + } - // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. - $lockfile = 'cache/poller'; - if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) - && (! get_config('system','override_poll_lockfile'))) { - logger("poller: Already running"); - return; - } - - // Create a lockfile. - file_put_contents($lockfile, EMPTY_STR); + // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. + $lockfile = 'cache/poller'; + if ( + (file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) + && (! get_config('system', 'override_poll_lockfile')) + ) { + logger("poller: Already running"); + return; + } - logger('poller: start'); - - $manual_id = 0; - $generation = 0; + // Create a lockfile. + file_put_contents($lockfile, EMPTY_STR); - $force = false; - $restart = false; + logger('poller: start'); - if(($argc > 1) && ($argv[1] == 'force')) - $force = true; + $manual_id = 0; + $generation = 0; - if(($argc > 1) && ($argv[1] == 'restart')) { - $restart = true; - $generation = intval($argv[2]); - if(! $generation) - return; - } + $force = false; + $restart = false; - if(($argc > 1) && intval($argv[1])) { - $manual_id = intval($argv[1]); - $force = true; - } + if (($argc > 1) && ($argv[1] == 'force')) { + $force = true; + } + + if (($argc > 1) && ($argv[1] == 'restart')) { + $restart = true; + $generation = intval($argv[2]); + if (! $generation) { + return; + } + } + + if (($argc > 1) && intval($argv[1])) { + $manual_id = intval($argv[1]); + $force = true; + } - $sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : ""); + $sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : ""); - reload_plugins(); + reload_plugins(); - $d = datetime_convert(); + $d = datetime_convert(); - // Only poll from those with suitable relationships + // Only poll from those with suitable relationships -// $abandon_sql = (($abandon_days) -// ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY')) -// : '' -// ); +// $abandon_sql = (($abandon_days) +// ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY')) +// : '' +// ); - $abandon_sql = EMPTY_STR; - - $randfunc = db_getfunc('RAND'); - - $contacts = q("SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed, + $abandon_sql = EMPTY_STR; + + $randfunc = db_getfunc('RAND'); + + $contacts = q( + "SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed, abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending, abook.abook_ignored, abook.abook_blocked, xchan.xchan_network, @@ -83,109 +94,116 @@ class Poller { where abook_self = 0 $sql_extra AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc", - intval(ACCOUNT_OK), - intval(ACCOUNT_UNVERIFIED) // FIXME - ); + intval(ACCOUNT_OK), + intval(ACCOUNT_UNVERIFIED) // FIXME + ); - if($contacts) { + if ($contacts) { + foreach ($contacts as $contact) { + $update = false; - foreach($contacts as $contact) { + $t = $contact['abook_updated']; + $c = $contact['abook_connected']; - $update = false; - - $t = $contact['abook_updated']; - $c = $contact['abook_connected']; - - if(intval($contact['abook_feed'])) { - $min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes'); - if(! $min) - $min = intval(get_config('system','minimum_feedcheck_minutes')); - if(! $min) - $min = 60; - $x = datetime_convert('UTC','UTC',"now - $min minutes"); - if($c < $x) { - Run::Summon( [ 'Onepoll', $contact['abook_id'] ] ); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - continue; - } + if (intval($contact['abook_feed'])) { + $min = service_class_fetch($contact['abook_channel'], 'minimum_feedcheck_minutes'); + if (! $min) { + $min = intval(get_config('system', 'minimum_feedcheck_minutes')); + } + if (! $min) { + $min = 60; + } + $x = datetime_convert('UTC', 'UTC', "now - $min minutes"); + if ($c < $x) { + Run::Summon([ 'Onepoll', $contact['abook_id'] ]); + if ($interval) { + @time_sleep_until(microtime(true) + (float) $interval); + } + } + continue; + } - if($contact['xchan_network'] !== 'zot6') - continue; + if ($contact['xchan_network'] !== 'zot6') { + continue; + } - if($c == $t) { - if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) - $update = true; - } - else { - - // if we've never connected with them, start the mark for death countdown from now - - if($c <= NULL_DATE) { - $r = q("update abook set abook_connected = '%s' where abook_id = %d", - dbesc(datetime_convert()), - intval($contact['abook_id']) - ); - $c = datetime_convert(); - $update = true; - } + if ($c == $t) { + if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) { + $update = true; + } + } else { + // if we've never connected with them, start the mark for death countdown from now - // He's dead, Jim + if ($c <= NULL_DATE) { + $r = q( + "update abook set abook_connected = '%s' where abook_id = %d", + dbesc(datetime_convert()), + intval($contact['abook_id']) + ); + $c = datetime_convert(); + $update = true; + } - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) { - $r = q("update abook set abook_archived = 1 where abook_id = %d", - intval($contact['abook_id']) - ); - $update = false; - continue; - } + // He's dead, Jim - if(intval($contact['abook_archived'])) { - $update = false; - continue; - } + if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 30 day")) > 0) { + $r = q( + "update abook set abook_archived = 1 where abook_id = %d", + intval($contact['abook_id']) + ); + $update = false; + continue; + } - // might be dead, so maybe don't poll quite so often - - // recently deceased, so keep up the regular schedule for 3 days - - if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0) - && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0)) - $update = true; + if (intval($contact['abook_archived'])) { + $update = false; + continue; + } - // After that back off and put them on a morphine drip + // might be dead, so maybe don't poll quite so often - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) { - $update = true; - } + // recently deceased, so keep up the regular schedule for 3 days - } + if ( + (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 3 day")) > 0) + && (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 1 day")) > 0) + ) { + $update = true; + } - if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) - continue; + // After that back off and put them on a morphine drip - if((! $update) && (! $force)) - continue; + if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 2 day")) > 0) { + $update = true; + } + } - Run::Summon( [ 'Onepoll',$contact['abook_id'] ] ); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); + if (intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) { + continue; + } - } - } + if ((! $update) && (! $force)) { + continue; + } - // migrate a few photos - eventually we'll migrate them all but without killing somebody's site - // trying to do them all at once - - migrate_xchan_photos(5); + Run::Summon([ 'Onepoll',$contact['abook_id'] ]); + if ($interval) { + @time_sleep_until(microtime(true) + (float) $interval); + } + } + } - set_config('system','lastpoll',datetime_convert()); + // migrate a few photos - eventually we'll migrate them all but without killing somebody's site + // trying to do them all at once - //All done - clear the lockfile - @unlink($lockfile); + migrate_xchan_photos(5); - return; - } + set_config('system', 'lastpoll', datetime_convert()); + + //All done - clear the lockfile + @unlink($lockfile); + + return; + } } diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php index 7e3c50882..7490724a7 100644 --- a/Zotlabs/Daemon/Queue.php +++ b/Zotlabs/Daemon/Queue.php @@ -1,82 +1,94 @@ - 1) { + $queue_id = $argv[1]; + } else { + $queue_id = EMPTY_STR; + } - if($argc > 1) - $queue_id = $argv[1]; - else - $queue_id = EMPTY_STR; + logger('queue: start'); - logger('queue: start'); + // delete all queue items more than 3 days old + // but first mark these sites dead if we haven't heard from them in a month - // delete all queue items more than 3 days old - // but first mark these sites dead if we haven't heard from them in a month + $r = q( + "select outq_posturl from outq where outq_created < %s - INTERVAL %s", + db_utcnow(), + db_quoteinterval('3 DAY') + ); + if ($r) { + foreach ($r as $rr) { + $site_url = ''; + $h = parse_url($rr['outq_posturl']); + $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : ''); + q( + "update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s", + dbesc($desturl), + db_utcnow(), + db_quoteinterval('1 MONTH') + ); + } + } - $r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('3 DAY') - ); - if($r) { - foreach($r as $rr) { - $site_url = ''; - $h = parse_url($rr['outq_posturl']); - $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : ''); - q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s", - dbesc($desturl), - db_utcnow(), db_quoteinterval('1 MONTH') - ); - } - } + $r = q( + "DELETE FROM outq WHERE outq_created < %s - INTERVAL %s", + db_utcnow(), + db_quoteinterval('3 DAY') + ); - $r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('3 DAY') - ); + if ($queue_id) { + $r = q( + "SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1", + dbesc($queue_id) + ); + } else { + // For the first 12 hours we'll try to deliver every 15 minutes + // After that, we'll only attempt delivery once per hour. + // This currently only handles the default queue drivers ('zot' or '') which we will group by posturl + // so that we don't start off a thousand deliveries for a couple of dead hubs. + // The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made). + // Other drivers will have to do something different here and may need their own query. - if($queue_id) { - $r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1", - dbesc($queue_id) - ); - } - else { - - // For the first 12 hours we'll try to deliver every 15 minutes - // After that, we'll only attempt delivery once per hour. - // This currently only handles the default queue drivers ('zot' or '') which we will group by posturl - // so that we don't start off a thousand deliveries for a couple of dead hubs. - // The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made). - // Other drivers will have to do something different here and may need their own query. - - // Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the - // "every 15 minutes" category. We probably need to prioritise them when inserted into the queue - // or just prior to this query based on recent and long-term delivery history. If we have good reason to believe - // the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once - // or twice a day. + // Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the + // "every 15 minutes" category. We probably need to prioritise them when inserted into the queue + // or just prior to this query based on recent and long-term delivery history. If we have good reason to believe + // the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once + // or twice a day. $sqlrandfunc = db_getfunc('rand'); - - $r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1", - db_utcnow() - ); - while ($r) { - foreach($r as $rv) { - Zlib\Queue::deliver($rv); - } - $r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1", - db_utcnow() - ); - } - } - if(! $r) - return; - foreach($r as $rv) { - Zlib\Queue::deliver($rv); - } - } + $r = q( + "SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1", + db_utcnow() + ); + while ($r) { + foreach ($r as $rv) { + Zlib\Queue::deliver($rv); + } + $r = q( + "SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1", + db_utcnow() + ); + } + } + if (! $r) { + return; + } + + foreach ($r as $rv) { + Zlib\Queue::deliver($rv); + } + } } diff --git a/Zotlabs/Daemon/Run.php b/Zotlabs/Daemon/Run.php index 5b63d845b..86245852a 100644 --- a/Zotlabs/Daemon/Run.php +++ b/Zotlabs/Daemon/Run.php @@ -2,74 +2,76 @@ namespace Zotlabs\Daemon; -if (array_search( __file__ , get_included_files()) === 0) { +if (array_search(__file__, get_included_files()) === 0) { + require_once('include/cli_startup.php'); + array_shift($argv); + $argc = count($argv); - require_once('include/cli_startup.php'); - array_shift($argv); - $argc = count($argv); - - if ($argc) { - Run::Release($argc,$argv); - } - return; + if ($argc) { + Run::Release($argc, $argv); + } + return; } -class Run { +class Run +{ - // These processes should be ignored by addons which enforce timeouts (e.g. queueworker) - // as it could result in corrupt data. Please add additional long running tasks to this list as they arise. - // Ideally the queueworker should probably be provided an allow list rather than a deny list as it will be easier - // to maintain. This was a quick hack to fix truncation of very large synced files when the queueworker addon is installed. - - public static $long_running = [ 'Addon', 'Channel_purge', 'Checksites', 'Content_importer', 'Convo', - 'Cron', 'Cron_daily', 'Cron_weekly', 'Delxitems', 'Expire', 'File_importer', 'Importfile' - ]; + // These processes should be ignored by addons which enforce timeouts (e.g. queueworker) + // as it could result in corrupt data. Please add additional long running tasks to this list as they arise. + // Ideally the queueworker should probably be provided an allow list rather than a deny list as it will be easier + // to maintain. This was a quick hack to fix truncation of very large synced files when the queueworker addon is installed. - public static function Summon($arr) { - if (file_exists('maintenance_lock') || file_exists('cache/maintenance_lock')) { - return; - } + public static $long_running = [ 'Addon', 'Channel_purge', 'Checksites', 'Content_importer', 'Convo', + 'Cron', 'Cron_daily', 'Cron_weekly', 'Delxitems', 'Expire', 'File_importer', 'Importfile' + ]; - $hookinfo = [ - 'argv' => $arr, - 'long_running' => self::$long_running - ]; + public static function Summon($arr) + { + if (file_exists('maintenance_lock') || file_exists('cache/maintenance_lock')) { + return; + } - call_hooks('daemon_summon', $hookinfo); + $hookinfo = [ + 'argv' => $arr, + 'long_running' => self::$long_running + ]; - $arr = $hookinfo['argv']; - $argc = count($arr); + call_hooks('daemon_summon', $hookinfo); - if ((! is_array($arr) || ($argc < 1))) { - logger("Summon handled by hook.", LOGGER_DEBUG); - return; - } + $arr = $hookinfo['argv']; + $argc = count($arr); - proc_run('php','Zotlabs/Daemon/Run.php',$arr); - } + if ((! is_array($arr) || ($argc < 1))) { + logger("Summon handled by hook.", LOGGER_DEBUG); + return; + } - public static function Release($argc, $argv) { - cli_startup(); + proc_run('php', 'Zotlabs/Daemon/Run.php', $arr); + } - $hookinfo = [ - 'argv' => $argv, - 'long_running' => self::$long_running - ]; + public static function Release($argc, $argv) + { + cli_startup(); - call_hooks('daemon_release', $hookinfo); + $hookinfo = [ + 'argv' => $argv, + 'long_running' => self::$long_running + ]; - $argv = $hookinfo['argv']; - $argc = count($argv); + call_hooks('daemon_release', $hookinfo); - if ((! is_array($argv) || ($argc < 1))) { - logger("Release handled by hook.", LOGGER_DEBUG); - return; - } + $argv = $hookinfo['argv']; + $argc = count($argv); - logger('Run: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG); - $cls = '\\Zotlabs\\Daemon\\' . $argv[0]; - $cls::run($argc,$argv); - } + if ((! is_array($argv) || ($argc < 1))) { + logger("Release handled by hook.", LOGGER_DEBUG); + return; + } + + logger('Run: release: ' . print_r($argv, true), LOGGER_ALL, LOG_DEBUG); + $cls = '\\Zotlabs\\Daemon\\' . $argv[0]; + $cls::run($argc, $argv); + } } diff --git a/Zotlabs/Daemon/Thumbnail.php b/Zotlabs/Daemon/Thumbnail.php index 75a9cea92..dfc00f3db 100644 --- a/Zotlabs/Daemon/Thumbnail.php +++ b/Zotlabs/Daemon/Thumbnail.php @@ -1,79 +1,85 @@ - $attach, + 'preview_style' => $preview_style, + 'preview_width' => $preview_width, + 'preview_height' => $preview_height, + 'thumbnail' => null + ]; - $p = [ - 'attach' => $attach, - 'preview_style' => $preview_style, - 'preview_width' => $preview_width, - 'preview_height' => $preview_height, - 'thumbnail' => null - ]; + /** + * @hooks thumbnail + * * \e array \b attach + * * \e int \b preview_style + * * \e int \b preview_width + * * \e int \b preview_height + * * \e string \b thumbnail + */ - /** - * @hooks thumbnail - * * \e array \b attach - * * \e int \b preview_style - * * \e int \b preview_width - * * \e int \b preview_height - * * \e string \b thumbnail - */ + call_hooks('thumbnail', $p); + if ($p['thumbnail']) { + return; + } - call_hooks('thumbnail',$p); - if ($p['thumbnail']) { - return; - } + $default_controller = null; - $default_controller = null; - - $files = glob('Zotlabs/Thumbs/*.php'); - if ($files) { - foreach ($files as $f) { - $clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f,'.php')); - if (class_exists($clsname)) { - $x = new $clsname(); - if (method_exists($x,'Match')) { - $matched = $x->Match($attach['filetype']); - if ($matched) { - $x->Thumb($attach,$preview_style,$preview_width,$preview_height); - } - } - if (method_exists($x,'MatchDefault')) { - $default_matched = $x->MatchDefault(substr($attach['filetype'],0,strpos($attach['filetype'],'/'))); - if ($default_matched) { - $default_controller = $x; - } - } - } - } - } - if (($default_controller) - && ((! file_exists(dbunescbin($attach['content']) . '.thumb')) - || (filectime(dbunescbin($attach['content']) . 'thumb') < (time() - 60)))) { - $default_controller->Thumb($attach,$preview_style,$preview_width,$preview_height); - } - } + $files = glob('Zotlabs/Thumbs/*.php'); + if ($files) { + foreach ($files as $f) { + $clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f, '.php')); + if (class_exists($clsname)) { + $x = new $clsname(); + if (method_exists($x, 'Match')) { + $matched = $x->Match($attach['filetype']); + if ($matched) { + $x->Thumb($attach, $preview_style, $preview_width, $preview_height); + } + } + if (method_exists($x, 'MatchDefault')) { + $default_matched = $x->MatchDefault(substr($attach['filetype'], 0, strpos($attach['filetype'], '/'))); + if ($default_matched) { + $default_controller = $x; + } + } + } + } + } + if ( + ($default_controller) + && ((! file_exists(dbunescbin($attach['content']) . '.thumb')) + || (filectime(dbunescbin($attach['content']) . 'thumb') < (time() - 60))) + ) { + $default_controller->Thumb($attach, $preview_style, $preview_width, $preview_height); + } + } } diff --git a/Zotlabs/Daemon/Xchan_photo.php b/Zotlabs/Daemon/Xchan_photo.php index 8a2b71b6c..f943a498b 100644 --- a/Zotlabs/Daemon/Xchan_photo.php +++ b/Zotlabs/Daemon/Xchan_photo.php @@ -1,35 +1,39 @@ - $v) { - self::register($k,$file,$v); - } - } - } + return $r; + } + + public static function register_array($file, $arr) + { + if ($arr) { + foreach ($arr as $k => $v) { + self::register($k, $file, $v); + } + } + } - public static function unregister($hook, $file, $function, $version = 1, $priority = 0) { - if (is_array($function)) { - $function = serialize($function); - } - $r = q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d", - dbesc($hook), - dbesc($file), - dbesc($function), - intval($priority), - intval($version) - ); + public static function unregister($hook, $file, $function, $version = 1, $priority = 0) + { + if (is_array($function)) { + $function = serialize($function); + } + $r = q( + "DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d", + dbesc($hook), + dbesc($file), + dbesc($function), + intval($priority), + intval($version) + ); - return $r; - } + return $r; + } - /** - * @brief Unregister all hooks with this file component. - * - * Useful for addon upgrades where you want to clean out old interfaces. - * - * @param string $file - */ - - public static function unregister_by_file($file) { - $r = q("DELETE FROM hook WHERE file = '%s' ", - dbesc($file) - ); + /** + * @brief Unregister all hooks with this file component. + * + * Useful for addon upgrades where you want to clean out old interfaces. + * + * @param string $file + */ - return $r; - } + public static function unregister_by_file($file) + { + $r = q( + "DELETE FROM hook WHERE file = '%s' ", + dbesc($file) + ); - /** - * @brief Inserts a hook into a page request. - * - * Insert a short-lived hook into the running page request. - * Hooks are normally persistent so that they can be called - * across asynchronous processes such as delivery and poll - * processes. - * - * insert_hook lets you attach a hook callback immediately - * which will not persist beyond the life of this page request - * or the current process. - * - * @param string $hook - * name of hook to attach callback - * @param string $fn - * function name of callback handler - * @param int $version - * hook interface version, 0 uses two callback params, 1 uses one callback param - * @param int $priority - * currently not implemented in this function, would require the hook array to be resorted - */ - public static function insert($hook, $fn, $version = 0, $priority = 0) { - if (is_array($fn)) { - $fn = serialize($fn); - } + return $r; + } - if (! is_array(App::$hooks)) { - App::$hooks = []; - } + /** + * @brief Inserts a hook into a page request. + * + * Insert a short-lived hook into the running page request. + * Hooks are normally persistent so that they can be called + * across asynchronous processes such as delivery and poll + * processes. + * + * insert_hook lets you attach a hook callback immediately + * which will not persist beyond the life of this page request + * or the current process. + * + * @param string $hook + * name of hook to attach callback + * @param string $fn + * function name of callback handler + * @param int $version + * hook interface version, 0 uses two callback params, 1 uses one callback param + * @param int $priority + * currently not implemented in this function, would require the hook array to be resorted + */ + public static function insert($hook, $fn, $version = 0, $priority = 0) + { + if (is_array($fn)) { + $fn = serialize($fn); + } - if (! array_key_exists($hook, App::$hooks)) { - App::$hooks[$hook] = []; - } + if (! is_array(App::$hooks)) { + App::$hooks = []; + } - App::$hooks[$hook][] = [ '', $fn, $priority, $version ]; - } -} \ No newline at end of file + if (! array_key_exists($hook, App::$hooks)) { + App::$hooks[$hook] = []; + } + + App::$hooks[$hook][] = [ '', $fn, $priority, $version ]; + } +} diff --git a/Zotlabs/Extend/Route.php b/Zotlabs/Extend/Route.php index 096f94598..695c0d2bb 100644 --- a/Zotlabs/Extend/Route.php +++ b/Zotlabs/Extend/Route.php @@ -2,7 +2,6 @@ namespace Zotlabs\Extend; - class Route { @@ -51,4 +50,3 @@ class Route return set_config('system', 'routes', $r); } } - diff --git a/Zotlabs/Extend/Widget.php b/Zotlabs/Extend/Widget.php index 78e3add6d..f261798aa 100644 --- a/Zotlabs/Extend/Widget.php +++ b/Zotlabs/Extend/Widget.php @@ -2,7 +2,6 @@ namespace Zotlabs\Extend; - class Widget { diff --git a/Zotlabs/Identity/OAuth2Server.php b/Zotlabs/Identity/OAuth2Server.php index 9d1763dce..93628d89c 100644 --- a/Zotlabs/Identity/OAuth2Server.php +++ b/Zotlabs/Identity/OAuth2Server.php @@ -8,37 +8,38 @@ use OAuth2\Storage\Memory; use OAuth2\GrantType\ClientCredentials; use OAuth2\OpenID\GrantType\AuthorizationCode; -class OAuth2Server extends Server { +class OAuth2Server extends Server +{ - public function __construct(OAuth2Storage $storage, $config = null) { + public function __construct(OAuth2Storage $storage, $config = null) + { - if (! is_array($config)) { - $config = [ -// 'use_openid_connect' => true, - 'issuer' => System::get_site_name(), -// 'use_jwt_access_tokens' => true, -// 'enforce_state' => false - ]; - } + if (! is_array($config)) { + $config = [ +// 'use_openid_connect' => true, + 'issuer' => System::get_site_name(), +// 'use_jwt_access_tokens' => true, +// 'enforce_state' => false + ]; + } - parent::__construct($storage, $config); + parent::__construct($storage, $config); - // Add the "Client Credentials" grant type (it is the simplest of the grant types) - $this->addGrantType(new ClientCredentials($storage)); + // Add the "Client Credentials" grant type (it is the simplest of the grant types) + $this->addGrantType(new ClientCredentials($storage)); - // Add the "Authorization Code" grant type (this is where the oauth magic happens) - // Need to use OpenID\GrantType to return id_token - // (see:https://github.com/bshaffer/oauth2-server-php/issues/443) - $this->addGrantType(new AuthorizationCode($storage)); + // Add the "Authorization Code" grant type (this is where the oauth magic happens) + // Need to use OpenID\GrantType to return id_token + // (see:https://github.com/bshaffer/oauth2-server-php/issues/443) + $this->addGrantType(new AuthorizationCode($storage)); - $keyStorage = new Memory( [ - 'keys' => [ - 'public_key' => get_config('system', 'pubkey'), - 'private_key' => get_config('system', 'prvkey') - ] - ]); - - $this->addStorage($keyStorage, 'public_key'); - } + $keyStorage = new Memory([ + 'keys' => [ + 'public_key' => get_config('system', 'pubkey'), + 'private_key' => get_config('system', 'prvkey') + ] + ]); + $this->addStorage($keyStorage, 'public_key'); + } } diff --git a/Zotlabs/Identity/OAuth2Storage.php b/Zotlabs/Identity/OAuth2Storage.php index d453f84e4..bd76a8704 100644 --- a/Zotlabs/Identity/OAuth2Storage.php +++ b/Zotlabs/Identity/OAuth2Storage.php @@ -2,10 +2,10 @@ namespace Zotlabs\Identity; - use OAuth2\Storage\Pdo; -class OAuth2Storage extends Pdo { +class OAuth2Storage extends Pdo +{ /** * @param string $username @@ -40,9 +40,8 @@ class OAuth2Storage extends Pdo { protected function checkPassword($user, $password) { - $x = account_verify_password($user,$password); - return((array_key_exists('channel',$x) && ! empty($x['channel'])) ? true : false); - + $x = account_verify_password($user, $password); + return((array_key_exists('channel', $x) && ! empty($x['channel'])) ? true : false); } /** @@ -52,77 +51,80 @@ class OAuth2Storage extends Pdo { public function getUser($username) { - $x = channelx_by_n($username); - if (! $x) { - return false; - } + $x = channelx_by_n($username); + if (! $x) { + return false; + } - $a = q("select * from account where account_id = %d", - intval($x['channel_account_id']) - ); + $a = q( + "select * from account where account_id = %d", + intval($x['channel_account_id']) + ); - $n = explode(' ', $x['channel_name']); + $n = explode(' ', $x['channel_name']); - return( [ - 'webfinger' => channel_reddress($x), - 'portable_id' => $x['channel_hash'], - 'email' => $a[0]['account_email'], - 'username' => $x['channel_address'], - 'user_id' => $x['channel_id'], - 'name' => $x['channel_name'], - 'firstName' => ((count($n) > 1) ? $n[1] : $n[0]), - 'lastName' => ((count($n) > 2) ? $n[count($n) - 1] : ''), - 'picture' => $x['xchan_photo_l'] - ] ); + return( [ + 'webfinger' => channel_reddress($x), + 'portable_id' => $x['channel_hash'], + 'email' => $a[0]['account_email'], + 'username' => $x['channel_address'], + 'user_id' => $x['channel_id'], + 'name' => $x['channel_name'], + 'firstName' => ((count($n) > 1) ? $n[1] : $n[0]), + 'lastName' => ((count($n) > 2) ? $n[count($n) - 1] : ''), + 'picture' => $x['xchan_photo_l'] + ] ); } - public function scopeExists($scope) { + public function scopeExists($scope) + { // Report that the scope is valid even if it's not. // We will only return a very small subset no matter what. // @TODO: Truly validate the scope // see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and // vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php // for more info. - return true; + return true; } - public function getDefaultScope($client_id=null) { + public function getDefaultScope($client_id = null) + { // Do not REQUIRE a scope // see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and // for more info. - return null; + return null; } - public function getUserClaims ($user_id, $claims) { - // Populate the CLAIMS requested (if any). - // @TODO: create a more reasonable/comprehensive list. - // @TODO: present claims on the AUTHORIZATION screen + public function getUserClaims($user_id, $claims) + { + // Populate the CLAIMS requested (if any). + // @TODO: create a more reasonable/comprehensive list. + // @TODO: present claims on the AUTHORIZATION screen $userClaims = []; - $claims = explode (' ', trim($claims)); + $claims = explode(' ', trim($claims)); $validclaims = [ "name", "preferred_username", "webfinger", "portable_id", "email", "picture", "firstName", "lastName" ]; $claimsmap = [ - "webfinger" => 'webfinger', - "portable_id" => 'portable_id', - "name" => 'name', - "email" => 'email', - "preferred_username" => 'username', - "picture" => 'picture', - "given_name" => 'firstName', - "family_name" => 'lastName' - ]; + "webfinger" => 'webfinger', + "portable_id" => 'portable_id', + "name" => 'name', + "email" => 'email', + "preferred_username" => 'username', + "picture" => 'picture', + "given_name" => 'firstName', + "family_name" => 'lastName' + ]; $userinfo = $this->getUser($user_id); foreach ($validclaims as $validclaim) { - if (in_array($validclaim,$claims)) { - $claimkey = $claimsmap[$validclaim]; - $userClaims[$validclaim] = $userinfo[$claimkey]; - } - else { - $userClaims[$validclaim] = $validclaim; + if (in_array($validclaim, $claims)) { + $claimkey = $claimsmap[$validclaim]; + $userClaims[$validclaim] = $userinfo[$claimkey]; + } else { + $userClaims[$validclaim] = $validclaim; } } - $userClaims["sub"]=$user_id; - return $userClaims; + $userClaims["sub"] = $user_id; + return $userClaims; } /** @@ -165,5 +167,4 @@ class OAuth2Storage extends Pdo { // if grant_types are not defined, then none are restricted return true; } - } diff --git a/Zotlabs/Import/Friendica.php b/Zotlabs/Import/Friendica.php index f6682b568..e2aa81aaa 100644 --- a/Zotlabs/Import/Friendica.php +++ b/Zotlabs/Import/Friendica.php @@ -1,4 +1,5 @@ $max_identities) { @@ -225,12 +226,12 @@ class Friendica set_abconfig($newuid, $channel['channel_hash'], 'system', 'my_perms', $x); if (intval($channel['channel_account_id'])) { - // Save our permissions role so we can perhaps call it up and modify it later. if ($role_permissions) { - if (array_key_exists('online', $role_permissions)) + if (array_key_exists('online', $role_permissions)) { set_pconfig($newuid, 'system', 'hide_presence', 1 - intval($role_permissions['online'])); + } if (array_key_exists('perms_auto', $role_permissions)) { $autoperms = intval($role_permissions['perms_auto']); set_pconfig($newuid, 'system', 'autoperms', $autoperms); @@ -246,12 +247,14 @@ class Friendica // if our role_permissions indicate that we're using a default collection ACL, add it. if (is_array($role_permissions) && $role_permissions['default_collection']) { - $r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1", + $r = q( + "select hash from pgrp where uid = %d and gname = '%s' limit 1", intval($newuid), dbesc(t('Friends')) ); if ($r) { - q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", + q( + "update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval($newuid) @@ -270,14 +273,14 @@ class Friendica $accts = get_config('system', 'auto_follow'); if (($accts) && (!$total_identities)) { - if (!is_array($accts)) + if (!is_array($accts)) { $accts = array($accts); + } foreach ($accts as $acct) { if (trim($acct)) { $f = connect_and_sync($channel, trim($acct)); if ($f['success']) { - $can_view_stream = their_perms_contains($channel['channel_id'], $f['abook']['abook_xchan'], 'view_stream'); // If we can view their stream, pull in some posts @@ -357,8 +360,5 @@ class Friendica notice(t('Import complete.') . EOL); goaway(z_root() . '/stream'); - } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/AConfig.php b/Zotlabs/Lib/AConfig.php index 5da554691..417f3034d 100644 --- a/Zotlabs/Lib/AConfig.php +++ b/Zotlabs/Lib/AConfig.php @@ -4,22 +4,26 @@ namespace Zotlabs\Lib; // account configuration storage is built on top of the under-utilised xconfig -class AConfig { +class AConfig +{ - public static function Load($account_id) { - return XConfig::Load('a_' . $account_id); - } + public static function Load($account_id) + { + return XConfig::Load('a_' . $account_id); + } - public static function Get($account_id, $family, $key, $default = false) { - return XConfig::Get('a_' . $account_id,$family,$key, $default); - } + public static function Get($account_id, $family, $key, $default = false) + { + return XConfig::Get('a_' . $account_id, $family, $key, $default); + } - public static function Set($account_id, $family, $key, $value) { - return XConfig::Set('a_' . $account_id,$family,$key,$value); - } - - public static function Delete($account_id, $family, $key) { - return XConfig::Delete('a_' . $account_id,$family,$key); - } + public static function Set($account_id, $family, $key, $value) + { + return XConfig::Set('a_' . $account_id, $family, $key, $value); + } + public static function Delete($account_id, $family, $key) + { + return XConfig::Delete('a_' . $account_id, $family, $key); + } } diff --git a/Zotlabs/Lib/ASCollection.php b/Zotlabs/Lib/ASCollection.php index c45890673..ac328504e 100644 --- a/Zotlabs/Lib/ASCollection.php +++ b/Zotlabs/Lib/ASCollection.php @@ -9,7 +9,7 @@ use Zotlabs\Lib\Activity; * Class for dealing with fetching ActivityStreams collections (ordered or unordered, normal or paged). * Construct with either an existing object or url and an optional channel to sign requests. * $direction is 0 (default) to fetch from the beginning, and 1 to fetch from the end and reverse order the resultant array. - * An optional limit to the number of records returned may also be specified. + * An optional limit to the number of records returned may also be specified. * Use $class->get() to return an array of collection members. */ class ASCollection diff --git a/Zotlabs/Lib/AbConfig.php b/Zotlabs/Lib/AbConfig.php index 581aae9e2..391ae1af9 100644 --- a/Zotlabs/Lib/AbConfig.php +++ b/Zotlabs/Lib/AbConfig.php @@ -2,74 +2,83 @@ namespace Zotlabs\Lib; +class AbConfig +{ -class AbConfig { - - public static function Load($chan, $xhash, $family = '') { - if($family) - $where = sprintf(" and cat = '%s' ",dbesc($family)); - $r = q("select * from abconfig where chan = %d and xchan = '%s' $where", - intval($chan), - dbesc($xhash) - ); - return $r; - } + public static function Load($chan, $xhash, $family = '') + { + if ($family) { + $where = sprintf(" and cat = '%s' ", dbesc($family)); + } + $r = q( + "select * from abconfig where chan = %d and xchan = '%s' $where", + intval($chan), + dbesc($xhash) + ); + return $r; + } - public static function Get($chan, $xhash, $family, $key, $default = false) { - $r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1", - intval($chan), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - if($r) { - return unserialise($r[0]['v']); - } - return $default; - } + public static function Get($chan, $xhash, $family, $key, $default = false) + { + $r = q( + "select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1", + intval($chan), + dbesc($xhash), + dbesc($family), + dbesc($key) + ); + if ($r) { + return unserialise($r[0]['v']); + } + return $default; + } - public static function Set($chan, $xhash, $family, $key, $value) { + public static function Set($chan, $xhash, $family, $key, $value) + { - $dbvalue = ((is_array($value)) ? serialise($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + $dbvalue = ((is_array($value)) ? serialise($value) : $value); + $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - if(self::Get($chan,$xhash,$family,$key) === false) { - $r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ", - intval($chan), - dbesc($xhash), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - } - else { - $r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ", - dbesc($dbvalue), - dbesc($chan), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - } - - if($r) - return $value; - return false; - } + if (self::Get($chan, $xhash, $family, $key) === false) { + $r = q( + "insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ", + intval($chan), + dbesc($xhash), + dbesc($family), + dbesc($key), + dbesc($dbvalue) + ); + } else { + $r = q( + "update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ", + dbesc($dbvalue), + dbesc($chan), + dbesc($xhash), + dbesc($family), + dbesc($key) + ); + } + + if ($r) { + return $value; + } + return false; + } - public static function Delete($chan, $xhash, $family, $key) { + public static function Delete($chan, $xhash, $family, $key) + { - $r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ", - intval($chan), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - - return $r; - } + $r = q( + "delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ", + intval($chan), + dbesc($xhash), + dbesc($family), + dbesc($key) + ); + return $r; + } } diff --git a/Zotlabs/Lib/AccessList.php b/Zotlabs/Lib/AccessList.php index 0714ef621..eaddb69cb 100644 --- a/Zotlabs/Lib/AccessList.php +++ b/Zotlabs/Lib/AccessList.php @@ -1,10 +1,9 @@ - '', 'hash' => '0', 'selected' => '']; @@ -323,7 +339,6 @@ class AccessList foreach ($r as $rr) { $grps[] = ['name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '')]; } - } return replace_macros(get_markup_template('group_selection.tpl'), [ @@ -340,7 +355,8 @@ class AccessList $groups = []; - $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + $r = q( + "SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval($_SESSION['uid']) ); $member_of = []; @@ -379,7 +395,6 @@ class AccessList '$groups' => $groups, '$add' => t('add'), ]); - } @@ -393,7 +408,6 @@ class AccessList $x = []; foreach ($g as $gv) { - // virtual access lists // connections:abc is all the connection sof the channel with channel_hash abc // zot:abc is all of abc's zot6 connections @@ -408,12 +422,14 @@ class AccessList if (strpos($gv, 'activitypub:') === 0) { $sql_extra = " and xchan_network = 'activitypub' "; } - $r = q("select channel_id from channel where channel_hash = '%s' ", + $r = q( + "select channel_id from channel where channel_hash = '%s' ", dbesc($channel_hash) ); if ($r) { foreach ($r as $rv) { - $y = q("select abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 $sql_extra", + $y = q( + "select abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 $sql_extra", intval($rv['channel_id']) ); if ($y) { @@ -438,7 +454,6 @@ class AccessList $ret[] = $rv['xchan']; } } - } } return $ret; @@ -447,7 +462,8 @@ class AccessList public static function member_of($c) { - $r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id + $r = q( + "SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ", dbesc($c) ); @@ -458,17 +474,19 @@ class AccessList public static function containing($uid, $c) { - $r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ", + $r = q( + "SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ", intval($uid), dbesc($c) ); $ret = []; if ($r) { - foreach ($r as $rv) + foreach ($r as $rv) { $ret[] = $rv['gid']; + } } return $ret; } -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 857e19c67..49bb329ec 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -26,7 +26,7 @@ require_once('include/event.php'); class Activity { - static public $ACTOR_CACHE_DAYS = 3; + public static $ACTOR_CACHE_DAYS = 3; // $x (string|array) // if json string, decode it @@ -39,7 +39,7 @@ class Activity if ($x) { if (is_string($x)) { $tmp = json_decode($x, true); - if ($tmp !== NULL) { + if ($tmp !== null) { $x = $tmp; } } @@ -56,7 +56,6 @@ class Activity return self::fetch_profile($x); } if (in_array($x['type'], [ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_ARTICLE])) { - // Use Mastodon-specific note and media hacks if nomadic. Else HTML. // Eventually this needs to be passed in much further up the stack // and base the decision on whether or not we are encoding for ActivityPub or Zot6 @@ -70,7 +69,6 @@ class Activity call_hooks('encode_object', $x); return $x; - } @@ -138,15 +136,16 @@ class Activity } if ($x['success']) { - $y = json_decode($x['body'], true); logger('returned: ' . json_encode($y, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); $site_url = unparse_url(['scheme' => $parsed['scheme'], 'host' => $parsed['host'], 'port' => ((array_key_exists('port', $parsed) && intval($parsed['port'])) ? $parsed['port'] : 0)]); - q("update site set site_update = '%s' where site_url = '%s' and site_update < %s - INTERVAL %s", + q( + "update site set site_update = '%s' where site_url = '%s' and site_update < %s - INTERVAL %s", dbesc(datetime_convert()), dbesc($site_url), - db_utcnow(), db_quoteinterval('1 DAY') + db_utcnow(), + db_quoteinterval('1 DAY') ); // check for a valid signature, but only if this is not an actor object. If it is signed, it must be valid. @@ -180,14 +179,15 @@ class Activity public static function fetch_profile($x) { - $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1", + $r = q( + "select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1", dbesc($x['id']) ); if (!$r) { - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($x['id']) ); - } if (!$r) { return []; @@ -199,7 +199,8 @@ class Activity public static function fetch_thing($x) { - $r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1", + $r = q( + "select * from obj where obj_type = %d and obj_obj = '%s' limit 1", intval(TERM_OBJ_THING), dbesc($x['id']) ); @@ -218,7 +219,6 @@ class Activity $x['image'] = $r[0]['obj_image']; } return $x; - } public static function fetch_item($x, $activitypub = false) @@ -229,7 +229,8 @@ class Activity return $x; } - $r = q("select * from item where mid = '%s' limit 1", + $r = q( + "select * from item where mid = '%s' limit 1", dbesc($x['id']) ); if ($r) { @@ -258,7 +259,6 @@ class Activity $ret['last'] = z_root() . '/' . App::$query_string . '?page=' . $lastpage; return $ret; - } @@ -529,7 +529,8 @@ class Activity $r = false; if ($url) { - $r = q("select xchan_addr from xchan where ( xchan_url = '%s' OR xchan_hash = '%s' ) limit 1", + $r = q( + "select xchan_addr from xchan where ( xchan_url = '%s' OR xchan_hash = '%s' ) limit 1", dbesc($url), dbesc($url) ); @@ -539,13 +540,13 @@ class Activity } } if ($name) { - $r = q("select xchan_addr from xchan where xchan_name = '%s' limit 1", + $r = q( + "select xchan_addr from xchan where xchan_name = '%s' limit 1", dbesc($name) ); if ($r) { return $r[0]['xchan_addr']; } - } return EMPTY_STR; @@ -558,7 +559,8 @@ class Activity // The xchan_url for mastodon is a text/html rendering. This is called from map_mentions where we need // to convert the mention url to an ActivityPub id. If this fails for any reason, return the url we have - $r = q("select * from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", + $r = q( + "select * from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", dbesc($url), dbesc($url) ); @@ -645,19 +647,22 @@ class Activity } foreach ($ptr as $att) { $entry = []; - if (array_key_exists('href', $att) && $att['href']) + if (array_key_exists('href', $att) && $att['href']) { $entry['href'] = $att['href']; - elseif (array_key_exists('url', $att) && $att['url']) + } elseif (array_key_exists('url', $att) && $att['url']) { $entry['href'] = $att['url']; - if (array_key_exists('mediaType', $att) && $att['mediaType']) + } + if (array_key_exists('mediaType', $att) && $att['mediaType']) { $entry['type'] = $att['mediaType']; - elseif (array_key_exists('type', $att) && $att['type'] === 'Image') + } elseif (array_key_exists('type', $att) && $att['type'] === 'Image') { $entry['type'] = 'image/jpeg'; + } if (array_key_exists('name', $att) && $att['name']) { $entry['name'] = html2plain(purify_html($att['name']), 256); } - if ($entry) + if ($entry) { $ret[] = $entry; + } } } elseif (is_string($item['attachment'])) { btlogger('not an array: ' . $item['attachment']); @@ -676,7 +681,6 @@ class Activity $reply = false; if (intval($i['item_deleted']) && (!$recurse)) { - $is_response = ActivityStreams::is_response_activity($i['verb']); if ($is_response) { @@ -689,10 +693,11 @@ class Activity $ret['id'] = str_replace('/item/', '/activity/', $i['mid']) . $fragment; $actor = self::encode_person($i['author'], false); - if ($actor) + if ($actor) { $ret['actor'] = $actor; - else + } else { return []; + } $obj = (($is_response) ? self::encode_activity($i, $activitypub, true) : self::encode_item($i, $activitypub)); if ($obj) { @@ -708,7 +713,6 @@ class Activity $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; return $ret; - } $ret['type'] = self::activity_mapper($i['verb']); @@ -803,10 +807,11 @@ class Activity } $actor = self::encode_person($i['author'], false); - if ($actor) + if ($actor) { $ret['actor'] = $actor; - else + } else { return []; + } $replyto = unserialise($i['replyto']); @@ -862,15 +867,16 @@ class Activity if ($i['obj']) { if (is_string($i['obj'])) { $tmp = json_decode($i['obj'], true); - if ($tmp !== NULL) { + if ($tmp !== null) { $i['obj'] = $tmp; } } $obj = self::encode_object($i['obj']); - if ($obj) + if ($obj) { $ret['object'] = $obj; - else + } else { return []; + } } else { $obj = self::encode_item($i, $activitypub); if ($obj) { @@ -883,7 +889,7 @@ class Activity if ($i['target']) { if (is_string($i['target'])) { $tmp = json_decode($i['target'], true); - if ($tmp !== NULL) { + if ($tmp !== null) { $i['target'] = $tmp; } } @@ -901,7 +907,6 @@ class Activity // addressing madness if ($activitypub) { - $parent_i = []; $public = (($i['item_private']) ? false : true); $top_level = (($reply) ? false : true); @@ -928,7 +933,6 @@ class Activity $ret['cc'] = array_values(array_unique(array_merge($ret['cc'], $parent_i['cc']))); } } else { - // private activity if ($top_level) { @@ -945,7 +949,8 @@ class Activity if ($ret['tag']) { foreach ($ret['tag'] as $mention) { if (is_array($mention) && array_key_exists('ttype', $mention) && in_array($mention['ttype'], [TERM_FORUM, TERM_MENTION]) && array_key_exists('href', $mention) && $mention['href']) { - $h = q("select * from hubloc where hubloc_id_url = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_id_url = '%s' limit 1", dbesc($mention['href']) ); if ($h) { @@ -962,7 +967,8 @@ class Activity } } - $d = q("select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d limit 1", + $d = q( + "select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d limit 1", dbesc($i['parent_mid']), intval($i['uid']) ); @@ -1006,7 +1012,8 @@ class Activity public static function nomadic_locations($item) { $synchubs = []; - $h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url + $h = q( + "select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_network = 'zot6' and hubloc_deleted = 0", dbesc($item['author_xchan']) ); @@ -1016,7 +1023,8 @@ class Activity } foreach ($h as $x) { - $y = q("select site_dead from site where site_url = '%s' limit 1", + $y = q( + "select site_dead from site where site_url = '%s' limit 1", dbesc($x['hubloc_url']) ); @@ -1051,7 +1059,7 @@ class Activity if (isset($i['obj']) && $i['obj']) { if (is_string($i['obj'])) { $tmp = json_decode($i['obj'], true); - if ($tmp !== NULL) { + if ($tmp !== null) { $i['obj'] = $tmp; } } @@ -1084,15 +1092,15 @@ class Activity $ret['id'] = $i['mid']; -// $token = IConfig::get($i,'ocap','relay'); -// if ($token) { -// if (defined('USE_BEARCAPS')) { -// $ret['id'] = 'bear:?u=' . $ret['id'] . '&t=' . $token; -// } -// else { -// $ret['id'] = $ret['id'] . '?token=' . $token; -// } -// } +// $token = IConfig::get($i,'ocap','relay'); +// if ($token) { +// if (defined('USE_BEARCAPS')) { +// $ret['id'] = 'bear:?u=' . $ret['id'] . '&t=' . $token; +// } +// else { +// $ret['id'] = $ret['id'] . '?token=' . $token; +// } +// } $ret['published'] = datetime_convert('UTC', 'UTC', $i['created'], ATOM_TIME); if ($i['created'] !== $i['edited']) { @@ -1151,7 +1159,8 @@ class Activity $reply = true; if ($i['item_private']) { - $d = q("select xchan_url, xchan_addr, xchan_name from item left join xchan on xchan_hash = author_xchan where id = %d limit 1", + $d = q( + "select xchan_url, xchan_addr, xchan_name from item left join xchan on xchan_hash = author_xchan where id = %d limit 1", intval($i['parent']) ); if ($d) { @@ -1331,7 +1340,6 @@ class Activity // addressing madness if ($activitypub) { - $parent_i = []; $ret['to'] = []; $ret['cc'] = []; @@ -1340,12 +1348,12 @@ class Activity $top_level = (($i['mid'] === $i['parent_mid']) ? true : false); if (!$top_level) { - if (intval($i['parent'])) { $recips = get_iconfig($i['parent'], 'activitypub', 'recips'); } else { // if we are encoding this item for storage there won't be a parent. - $p = q("select parent from item where parent_mid = '%s' and uid = %d", + $p = q( + "select parent from item where parent_mid = '%s' and uid = %d", dbesc($i['parent_mid']), intval($i['uid']) ); @@ -1371,9 +1379,7 @@ class Activity if (isset($parent_i['cc']) && is_array($parent_i['cc'])) { $ret['cc'] = array_values(array_unique(array_merge($ret['cc'], $parent_i['cc']))); } - } else { - // private activity if ($top_level) { @@ -1389,7 +1395,8 @@ class Activity if ($ret['tag']) { foreach ($ret['tag'] as $mention) { if (is_array($mention) && array_key_exists('ttype', $mention) && in_array($mention['ttype'], [TERM_FORUM, TERM_MENTION]) && array_key_exists('href', $mention) && $mention['href']) { - $h = q("select * from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", dbesc($mention['href']), dbesc($mention['href']) ); @@ -1408,7 +1415,8 @@ class Activity } - $d = q("select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d limit 1", + $d = q( + "select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d limit 1", dbesc($i['parent_mid']), intval($i['uid']) ); @@ -1487,7 +1495,8 @@ class Activity } if ($i['mid'] !== $i['parent_mid']) { - $i = q("select * from item where parent_mid = '%s' and uid = %d", + $i = q( + "select * from item where parent_mid = '%s' and uid = %d", dbesc($i['parent_mid']), intval($i['uid']) ); @@ -1535,7 +1544,6 @@ class Activity } return array_values(array_unique($ret)); - } @@ -1544,8 +1552,9 @@ class Activity $ret = []; - if (!$p['xchan_url']) + if (!$p['xchan_url']) { return $ret; + } if (!$extended) { return $p['xchan_url']; @@ -1572,8 +1581,9 @@ class Activity } else { $ret['id'] = ((strpos($p['xchan_hash'], 'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); } - if ($p['xchan_addr'] && strpos($p['xchan_addr'], '@')) + if ($p['xchan_addr'] && strpos($p['xchan_addr'], '@')) { $ret['preferredUsername'] = substr($p['xchan_addr'], 0, strpos($p['xchan_addr'], '@')); + } $ret['name'] = $p['xchan_name']; $ret['updated'] = datetime_convert('UTC', 'UTC', $p['xchan_name_date'], ATOM_TIME); $ret['icon'] = [ @@ -1592,7 +1602,6 @@ class Activity $ret['tag'] = [['type' => 'PropertyValue', 'name' => 'Protocol', 'value' => 'zot6']]; if ($activitypub && get_config('system', 'activitypub', ACTIVITYPUB_ENABLED)) { - if ($c) { if (get_pconfig($c['channel_id'], 'system', 'activitypub', ACTIVITYPUB_ENABLED)) { $ret['inbox'] = z_root() . '/inbox/' . $c['channel_address']; @@ -1654,16 +1663,19 @@ class Activity } // only fill in profile information if the profile is publicly visible if (perm_is_allowed($c['channel_id'], EMPTY_STR, 'view_profile')) { - $dp = q("select * from profile where uid = %d and is_default = 1", + $dp = q( + "select * from profile where uid = %d and is_default = 1", intval($c['channel_id']) ); if ($dp) { if ($dp[0]['about']) { $ret['summary'] = bbcode($dp[0]['about'], ['export' => true]); } - foreach (['pdesc', 'address', 'locality', 'region', 'postal_code', 'country_name', + foreach ( + ['pdesc', 'address', 'locality', 'region', 'postal_code', 'country_name', 'hometown', 'gender', 'marital', 'sexual', 'politic', 'religion', 'pronouns', - 'homepage', 'contact', 'dob'] as $k) { + 'homepage', 'contact', 'dob'] as $k + ) { if ($dp[0][$k]) { $key = $k; if ($key === 'pdesc') { @@ -1797,20 +1809,23 @@ class Activity // Reactions will just map to normal activities - if (strpos($verb, ACTIVITY_REACT) !== false) + if (strpos($verb, ACTIVITY_REACT) !== false) { return 'Create'; - if (strpos($verb, ACTIVITY_MOOD) !== false) + } + if (strpos($verb, ACTIVITY_MOOD) !== false) { return 'Create'; + } - if (strpos($verb, ACTIVITY_POKE) !== false) + if (strpos($verb, ACTIVITY_POKE) !== false) { return 'Activity'; + } // We should return false, however this will trigger an uncaught exception and crash // the delivery system if encountered by the JSON-LDSignature library logger('Unmapped activity: ' . $verb); return 'Create'; - // return false; + // return false; } @@ -1853,8 +1868,7 @@ class Activity logger('Unmapped activity object: ' . $obj); return 'Note'; - // return false; - + // return false; } @@ -1870,11 +1884,11 @@ class Activity } /* - * - * if $act->type === 'Follow', actor is now following $channel - * if $act->type === 'Accept', actor has approved a follow request from $channel - * - */ + * + * if $act->type === 'Follow', actor is now following $channel + * if $act->type === 'Accept', actor has approved a follow request from $channel + * + */ $person_obj = $act->actor; @@ -1885,14 +1899,14 @@ class Activity } if (is_array($person_obj)) { - // store their xchan and hubloc self::actor_store($person_obj['id'], $person_obj); // Find any existing abook record - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($person_obj['id']), intval($channel['channel_id']) ); @@ -1914,15 +1928,12 @@ class Activity if ($contact && $contact['abook_id']) { - // A relationship of some form already exists on this site. switch ($act->type) { - case 'Follow': case 'Invite': case 'Join': - // A second Follow request, but we haven't approved the first one if ($contact['abook_pending']) { @@ -1938,7 +1949,6 @@ class Activity return; case 'Accept': - // They accepted our Follow request - set default permissions set_abconfig($channel['channel_id'], $contact['abook_xchan'], 'system', 'their_perms', $their_perms); @@ -1946,11 +1956,13 @@ class Activity $abook_instance = $contact['abook_instance']; if (strpos($abook_instance, z_root()) === false) { - if ($abook_instance) + if ($abook_instance) { $abook_instance .= ','; + } $abook_instance .= z_root(); - $r = q("update abook set abook_instance = '%s', abook_not_here = 0 + $r = q( + "update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d and abook_channel = %d", dbesc($abook_instance), intval($contact['abook_id']), @@ -1961,7 +1973,6 @@ class Activity return; default: return; - } } @@ -1979,7 +1990,8 @@ class Activity // The xchan should have been created by actor_store() above - $r = q("select * from xchan where xchan_hash = '%s' and xchan_network = 'activitypub' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' and xchan_network = 'activitypub' limit 1", dbesc($person_obj['id']) ); @@ -2024,17 +2036,20 @@ class Activity ] ); - if ($my_perms) + if ($my_perms) { AbConfig::Set($channel['channel_id'], $ret['xchan_hash'], 'system', 'my_perms', $my_perms); + } - if ($their_perms) + if ($their_perms) { AbConfig::Set($channel['channel_id'], $ret['xchan_hash'], 'system', 'their_perms', $their_perms); + } if ($r) { logger("New ActivityPub follower for {$channel['channel_name']}"); - $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", + $new_connection = q( + "select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($channel['channel_id']), dbesc($ret['xchan_hash']) ); @@ -2085,7 +2100,6 @@ class Activity } return; - } @@ -2099,8 +2113,8 @@ class Activity $person_obj = $act->actor; if (is_array($person_obj)) { - - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($person_obj['id']), intval($channel['channel_id']) ); @@ -2121,7 +2135,7 @@ class Activity return; } -// logger('person_obj: ' . print_r($person_obj,true)); +// logger('person_obj: ' . print_r($person_obj,true)); if (array_key_exists('movedTo', $person_obj) && $person_obj['movedTo'] && !is_array($person_obj['movedTo'])) { $tgt = self::fetch($person_obj['movedTo']); @@ -2173,10 +2187,12 @@ class Activity XConfig::Set($url, 'system', 'actor_record', $person_obj); $name = escape_tags($person_obj['name']); - if (!$name) + if (!$name) { $name = escape_tags($person_obj['preferredUsername']); - if (!$name) + } + if (!$name) { $name = escape_tags(t('Unknown')); + } $username = escape_tags($person_obj['preferredUsername']); $h = parse_url($url); @@ -2186,9 +2202,9 @@ class Activity if ($person_obj['icon']) { if (is_array($person_obj['icon'])) { - if (array_key_exists('url', $person_obj['icon'])) + if (array_key_exists('url', $person_obj['icon'])) { $icon = $person_obj['icon']['url']; - else { + } else { if (is_string($person_obj['icon'][0])) { $icon = $person_obj['icon'][0]; } elseif (array_key_exists('url', $person_obj['icon'][0])) { @@ -2309,7 +2325,8 @@ class Activity $xchan_type = self::get_xchan_type($person_obj['type']); $about = ((isset($person_obj['summary'])) ? html2bbcode(purify_html($person_obj['summary'])) : EMPTY_STR); - $p = q("select * from xchan where xchan_url = '%s' and xchan_network = 'zot6' limit 1", + $p = q( + "select * from xchan where xchan_url = '%s' and xchan_network = 'zot6' limit 1", dbesc($url) ); if ($p) { @@ -2322,7 +2339,8 @@ class Activity // once extended xchan_type directory filtering is implemented. $censored = ((strpos($profile, 'instance_actor') || strpos($profile, '/internal/fetch')) ? 1 : 0); - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($url) ); if (!$r) { @@ -2350,7 +2368,6 @@ class Activity ] ); } else { - // Record exists. Cache existing records for a set number of days // then refetch to catch updated profile photos, names, etc. @@ -2359,7 +2376,8 @@ class Activity } // update existing record - $u = q("update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_pubkey = '%s', xchan_network = '%s', xchan_name_date = '%s', xchan_hidden = %d, xchan_type = %d, xchan_censored = %d where xchan_hash = '%s'", + $u = q( + "update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_pubkey = '%s', xchan_network = '%s', xchan_name_date = '%s', xchan_hidden = %d, xchan_type = %d, xchan_censored = %d where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($name), dbesc($pubkey), @@ -2372,7 +2390,8 @@ class Activity ); if (strpos($username, '@') && ($r[0]['xchan_addr'] !== $username)) { - $r = q("update xchan set xchan_addr = '%s' where xchan_hash = '%s'", + $r = q( + "update xchan set xchan_addr = '%s' where xchan_hash = '%s'", dbesc($username), dbesc($url) ); @@ -2393,11 +2412,13 @@ class Activity $version = ((array_path_exists('software/version', $ni)) ? $ni['software']['version'] : ''); $register = $ni['openRegistrations']; - $site = q("select * from site where site_url = '%s'", + $site = q( + "select * from site where site_url = '%s'", dbesc($site_url) ); if ($site) { - q("update site set site_project = '%s', site_update = '%s', site_version = '%s' where site_url = '%s'", + q( + "update site set site_project = '%s', site_update = '%s', site_version = '%s' where site_url = '%s'", dbesc($software), dbesc(datetime_convert()), dbesc($version), @@ -2405,7 +2426,8 @@ class Activity ); // it may have been saved originally as an unknown type, but we now know what it is if (intval($site[0]['site_type']) === SITE_TYPE_UNKNOWN) { - q("update site set site_type = %d where site_url = '%s'", + q( + "update site set site_type = %d where site_url = '%s'", intval(SITE_TYPE_NOTZOT), dbesc($site_url) ); @@ -2433,7 +2455,8 @@ class Activity set_xconfig($url, 'activitypub', 'collections', $collections); } - $h = q("select * from hubloc where hubloc_hash = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($url) ); @@ -2461,24 +2484,28 @@ class Activity ); } else { if (strpos($username, '@') && ($h[0]['hubloc_addr'] !== $username)) { - $r = q("update hubloc set hubloc_addr = '%s' where hubloc_hash = '%s'", + $r = q( + "update hubloc set hubloc_addr = '%s' where hubloc_hash = '%s'", dbesc($username), dbesc($url) ); } if ($inbox !== $h[0]['hubloc_callback']) { - $r = q("update hubloc set hubloc_callback = '%s' where hubloc_hash = '%s'", + $r = q( + "update hubloc set hubloc_callback = '%s' where hubloc_hash = '%s'", dbesc($inbox), dbesc($url) ); } if ($profile !== $h[0]['hubloc_id_url']) { - $r = q("update hubloc set hubloc_id_url = '%s' where hubloc_hash = '%s'", + $r = q( + "update hubloc set hubloc_id_url = '%s' where hubloc_hash = '%s'", dbesc($profile), dbesc($url) ); } - $r = q("update hubloc set hubloc_updated = '%s' where hubloc_hash = '%s'", + $r = q( + "update hubloc set hubloc_updated = '%s' where hubloc_hash = '%s'", dbesc(datetime_convert()), dbesc($url) ); @@ -2493,7 +2520,8 @@ class Activity // and adding zot discovery urls to the actor record will cause federation to fail with the 20-30 projects which don't accept arrays in the url field. if (strpos($url, '/channel/') !== false) { - $zx = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6'", + $zx = q( + "select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6'", dbesc($url) ); if (($username) && strpos($username, '@') && (!$zx)) { @@ -2502,7 +2530,6 @@ class Activity } Run::Summon(['Xchan_photo', bin2hex($icon), bin2hex($url)]); - } public static function update_protocols($xchan, $str) @@ -2517,7 +2544,8 @@ class Activity public static function drop($channel, $observer, $act) { - $r = q("select * from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select * from item where mid = '%s' and uid = %d limit 1", dbesc((is_array($act->obj)) ? $act->obj['id'] : $act->obj), intval($channel['channel_id']) ); @@ -2531,7 +2559,6 @@ class Activity } elseif (in_array($act->actor['id'], [$r[0]['author_xchan'], $r[0]['owner_xchan']])) { drop_item($r[0]['id'], false); } - } @@ -2539,8 +2566,9 @@ class Activity public static function vid_sort($a, $b) { - if ($a['width'] === $b['width']) + if ($a['width'] === $b['width']) { return 0; + } return (($a['width'] > $b['width']) ? -1 : 1); } @@ -2567,7 +2595,8 @@ class Activity public static function get_actor_bbmention($id) { - $x = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' or hubloc_id_url = '%s' limit 1", + $x = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' or hubloc_id_url = '%s' limit 1", dbesc($id), dbesc($id) ); @@ -2581,7 +2610,6 @@ class Activity return sprintf('@[zrl=%s]%s[/zrl]', $x[0]['xchan_url'], $x[0]['xchan_name']); } return '@{' . $id . '}'; - } public static function update_poll($item, $post) @@ -2602,7 +2630,8 @@ class Activity $multi = true; } - $r = q("select mid, title from item where parent_mid = '%s' and author_xchan = '%s' and mid != parent_mid ", + $r = q( + "select mid, title from item where parent_mid = '%s' and author_xchan = '%s' and mid != parent_mid ", dbesc($item['mid']), dbesc($post['author_xchan']) ); @@ -2675,7 +2704,8 @@ class Activity logger('updated_poll: ' . print_r($o, true), LOGGER_DATA); if ($answer_found && !$found) { - $x = q("update item set obj = '%s', edited = '%s' where id = %d", + $x = q( + "update item set obj = '%s', edited = '%s' where id = %d", dbesc(json_encode($o)), dbesc(datetime_convert()), intval($item['id']) @@ -2731,8 +2761,10 @@ class Activity // These activities should have been handled separately in the Inbox module and should not be turned into posts - if (in_array($act->type, ['Follow', 'Accept', 'Reject', 'Create', 'Update']) && is_array($act->obj) && array_key_exists('type', $act->obj) - && ($act->obj['type'] === 'Follow' || ActivityStreams::is_an_actor($act->obj['type']))) { + if ( + in_array($act->type, ['Follow', 'Accept', 'Reject', 'Create', 'Update']) && is_array($act->obj) && array_key_exists('type', $act->obj) + && ($act->obj['type'] === 'Follow' || ActivityStreams::is_an_actor($act->obj['type'])) + ) { return false; } @@ -2794,7 +2826,6 @@ class Activity } if (ActivityStreams::is_response_activity($act->type)) { - $response_activity = true; $s['mid'] = $act->id; @@ -2970,8 +3001,10 @@ class Activity $generator = $act->get_property_obj('generator', $act->obj); } - if ($generator && array_key_exists('type', $generator) - && in_array($generator['type'], ['Application', 'Service']) && array_key_exists('name', $generator)) { + if ( + $generator && array_key_exists('type', $generator) + && in_array($generator['type'], ['Application', 'Service']) && array_key_exists('name', $generator) + ) { $s['app'] = escape_tags($generator['name']); } @@ -3041,7 +3074,6 @@ class Activity if (!$response_activity) { if ($act->obj['type'] === 'Video') { - $vtypes = [ 'video/mp4', 'video/ogg', @@ -3117,7 +3149,6 @@ class Activity } if ($act->obj['type'] === 'Audio') { - $atypes = [ 'audio/mpeg', 'audio/ogg', @@ -3152,7 +3183,6 @@ class Activity } if ($act->obj['type'] === 'Image' && strpos($s['body'], 'zrl=') === false) { - $ptr = null; if (array_key_exists('url', $act->obj)) { @@ -3178,7 +3208,6 @@ class Activity if ($act->obj['type'] === 'Page' && !$s['body']) { - $ptr = null; $purl = EMPTY_STR; @@ -3268,7 +3297,6 @@ class Activity if ($cacheable) { if ((!array_key_exists('mimetype', $s)) || (in_array($s['mimetype'], ['text/bbcode', 'text/x-multicode']))) { - // preserve the original purified HTML content *unless* we've modified $s['body'] // within this function (to add attachments or reaction descriptions or mention rewrites). // This avoids/bypasses some markdown rendering issues which can occur when @@ -3295,7 +3323,6 @@ class Activity $s = $hookinfo['s']; return $s; - } public static function rewrite_mentions_sub(&$s, $pref, &$obj = null) @@ -3306,7 +3333,8 @@ class Activity $txt = EMPTY_STR; if (intval($tag['ttype']) === TERM_MENTION) { // some platforms put the identity url into href rather than the profile url. Accept either form. - $x = q("select * from xchan where xchan_url = '%s' or xchan_hash = '%s' limit 1", + $x = q( + "select * from xchan where xchan_url = '%s' or xchan_hash = '%s' limit 1", dbesc($tag['url']), dbesc($tag['url']) ); @@ -3331,43 +3359,75 @@ class Activity } if ($txt) { - // the Markdown filter will get tripped up and think this is a markdown link // if $txt begins with parens so put it behind a zero-width space if (substr($txt, 0, 1) === '(') { $txt = htmlspecialchars_decode('​', ENT_QUOTES) . $txt; } - $s['body'] = preg_replace('/\@\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/zrl\]/ism', - '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', $s['body']); - $s['body'] = preg_replace('/\@\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/url\]/ism', - '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', $s['body']); - $s['body'] = preg_replace('/\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\]@(.*?)\[\/zrl\]/ism', - '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', $s['body']); - $s['body'] = preg_replace('/\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\]@(.*?)\[\/url\]/ism', - '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', $s['body']); + $s['body'] = preg_replace( + '/\@\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/zrl\]/ism', + '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\@\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/url\]/ism', + '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\]@(.*?)\[\/zrl\]/ism', + '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\]@(.*?)\[\/url\]/ism', + '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', + $s['body'] + ); // replace these just in case the sender (in this case Friendica) got it wrong - $s['body'] = preg_replace('/\@\[zrl\=' . preg_quote($x[0]['xchan_hash'], '/') . '\](.*?)\[\/zrl\]/ism', - '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', $s['body']); - $s['body'] = preg_replace('/\@\[url\=' . preg_quote($x[0]['xchan_hash'], '/') . '\](.*?)\[\/url\]/ism', - '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', $s['body']); - $s['body'] = preg_replace('/\[zrl\=' . preg_quote($x[0]['xchan_hash'], '/') . '\]@(.*?)\[\/zrl\]/ism', - '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', $s['body']); - $s['body'] = preg_replace('/\[url\=' . preg_quote($x[0]['xchan_hash'], '/') . '\]@(.*?)\[\/url\]/ism', - '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', $s['body']); + $s['body'] = preg_replace( + '/\@\[zrl\=' . preg_quote($x[0]['xchan_hash'], '/') . '\](.*?)\[\/zrl\]/ism', + '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\@\[url\=' . preg_quote($x[0]['xchan_hash'], '/') . '\](.*?)\[\/url\]/ism', + '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\[zrl\=' . preg_quote($x[0]['xchan_hash'], '/') . '\]@(.*?)\[\/zrl\]/ism', + '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', + $s['body'] + ); + $s['body'] = preg_replace( + '/\[url\=' . preg_quote($x[0]['xchan_hash'], '/') . '\]@(.*?)\[\/url\]/ism', + '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', + $s['body'] + ); if ($obj && $txt) { if (!is_array($obj)) { $obj = json_decode($obj, true); } if (array_path_exists('source/content', $obj)) { - $obj['source']['content'] = preg_replace('/\@\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/zrl\]/ism', - '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', $obj['source']['content']); - $obj['source']['content'] = preg_replace('/\@\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/url\]/ism', - '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', $obj['source']['content']); + $obj['source']['content'] = preg_replace( + '/\@\[zrl\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/zrl\]/ism', + '@[zrl=' . $x[0]['xchan_url'] . ']' . $txt . '[/zrl]', + $obj['source']['content'] + ); + $obj['source']['content'] = preg_replace( + '/\@\[url\=' . preg_quote($x[0]['xchan_url'], '/') . '\](.*?)\[\/url\]/ism', + '@[url=' . $x[0]['xchan_url'] . ']' . $txt . '[/url]', + $obj['source']['content'] + ); } - $obj['content'] = preg_replace('/\@(.*?)\(.*?)\<\/a\>/ism', - '@$1' . $txt . '', $obj['content']); + $obj['content'] = preg_replace( + '/\@(.*?)\(.*?)\<\/a\>/ism', + '@$1' . $txt . '', + $obj['content'] + ); } } } @@ -3448,7 +3508,8 @@ class Activity $permit_mentions = intval(PConfig::Get($channel['channel_id'], 'system', 'permit_all_mentions') && i_am_mentioned($channel, $item)); if ($is_child_node) { - $p = q("select * from item where mid = '%s' and uid = %d and item_wall = 1", + $p = q( + "select * from item where mid = '%s' and uid = %d and item_wall = 1", dbesc($item['parent_mid']), intval($channel['channel_id']) ); @@ -3498,7 +3559,6 @@ class Activity $item['item_blocked'] = ITEM_MODERATED; } } else { - // By default if we allow you to send_stream and comments and this is a comment, it is allowed. // A side effect of this action is that if you take away send_stream permission, comments to those // posts you previously allowed will still be accepted. It is possible but might be difficult to fix this. @@ -3550,7 +3610,6 @@ class Activity } if ($is_sys_channel) { - if (!check_pubstream_channelallowed($observer_hash)) { $allowed = false; $reason[] = 'pubstream channel blocked'; @@ -3558,7 +3617,8 @@ class Activity // don't allow pubstream posts if the sender even has a clone on a pubstream denied site - $h = q("select hubloc_url from hubloc where hubloc_hash = '%s'", + $h = q( + "select hubloc_url from hubloc where hubloc_hash = '%s'", dbesc($observer_hash) ); if ($h) { @@ -3620,7 +3680,8 @@ class Activity // due to this channel's filtering rules for content // provided by either of these entities. - $abook = q("select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ", + $abook = q( + "select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ", dbesc($item['author_xchan']), dbesc($item['owner_xchan']), intval($channel['channel_id']) @@ -3661,8 +3722,8 @@ class Activity $parent = null; if ($is_child_node) { - - $parent = q("select * from item where mid = '%s' and uid = %d limit 1", + $parent = q( + "select * from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) ); @@ -3675,7 +3736,8 @@ class Activity $fetch = (($fetch_parents) ? self::fetch_and_store_parents($channel, $observer_hash, $act, $item) : false); } if ($fetch) { - $parent = q("select * from item where mid = '%s' and uid = %d limit 1", + $parent = q( + "select * from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) ); @@ -3698,11 +3760,11 @@ class Activity $item['parent_mid'] = $parent[0]['parent_mid']; /* - * - * Check for conversation privacy mismatches - * We can only do this if we have a channel and we have fetched the parent - * - */ + * + * Check for conversation privacy mismatches + * We can only do this if we have a channel and we have fetched the parent + * + */ // public conversation, but this comment went rogue and was published privately // hide it from everybody except the channel owner @@ -3721,12 +3783,12 @@ class Activity if (intval($parent[0]['item_private']) !== 0 && $act->recips && (in_array(ACTIVITY_PUBLIC_INBOX, $act->recips) || in_array('Public', $act->recips) || in_array('as:Public', $act->recips))) { $item['item_restrict'] = $item['item_restrict'] | 2; } - } self::rewrite_mentions($item); - $r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select id, created, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($item['uid']) ); @@ -3747,30 +3809,30 @@ class Activity // can fetch the 'context'. For other platforms it's a wild guess. Additionally when we tested this, it started an infinite // recursion and has been disabled until the recursive behaviour is tracked down and fixed. -// if ($fetch_parents && $parent && ! intval($parent[0]['item_private'])) { -// logger('topfetch', LOGGER_DEBUG); -// // if the thread owner is a connnection, we will already receive any additional comments to their posts -// // but if they are not we can try to fetch others in the background -// $x = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash -// WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1", -// intval($channel['channel_id']), -// dbesc($parent[0]['owner_xchan']) -// ); -// if (! $x) { -// // determine if the top-level post provides a replies collection -// if ($parent[0]['obj']) { -// $parent[0]['obj'] = json_decode($parent[0]['obj'],true); -// } -// logger('topfetch: ' . print_r($parent[0],true), LOGGER_ALL); -// $id = ((array_path_exists('obj/replies/id',$parent[0])) ? $parent[0]['obj']['replies']['id'] : false); -// if (! $id) { -// $id = ((array_path_exists('obj/replies',$parent[0]) && is_string($parent[0]['obj']['replies'])) ? $parent[0]['obj']['replies'] : false); -// } -// if ($id) { -// Run::Summon( [ 'Convo', $id, $channel['channel_id'], $observer_hash ] ); -// } -// } -// } +// if ($fetch_parents && $parent && ! intval($parent[0]['item_private'])) { +// logger('topfetch', LOGGER_DEBUG); +// // if the thread owner is a connnection, we will already receive any additional comments to their posts +// // but if they are not we can try to fetch others in the background +// $x = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash +// WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1", +// intval($channel['channel_id']), +// dbesc($parent[0]['owner_xchan']) +// ); +// if (! $x) { +// // determine if the top-level post provides a replies collection +// if ($parent[0]['obj']) { +// $parent[0]['obj'] = json_decode($parent[0]['obj'],true); +// } +// logger('topfetch: ' . print_r($parent[0],true), LOGGER_ALL); +// $id = ((array_path_exists('obj/replies/id',$parent[0])) ? $parent[0]['obj']['replies']['id'] : false); +// if (! $id) { +// $id = ((array_path_exists('obj/replies',$parent[0]) && is_string($parent[0]['obj']['replies'])) ? $parent[0]['obj']['replies'] : false); +// } +// if ($id) { +// Run::Summon( [ 'Convo', $id, $channel['channel_id'], $observer_hash ] ); +// } +// } +// } if (is_array($x) && $x['item_id']) { if ($is_child_node) { @@ -3778,7 +3840,8 @@ class Activity // We are the owner of this conversation, so send all received comments back downstream Run::Summon(['Notifier', 'comment-import', $x['item_id']]); } - $r = q("select * from item where id = %d limit 1", + $r = q( + "select * from item where id = %d limit 1", intval($x['item_id']) ); if ($r) { @@ -3787,14 +3850,14 @@ class Activity } sync_an_item($channel['channel_id'], $x['item_id']); } - } public static function find_best_identity($xchan) { - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1", + $r = q( + "select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1", dbesc($xchan) ); if ($r) { @@ -3821,8 +3884,10 @@ class Activity } // set client flag to convert objects to implied activities $a = new ActivityStreams($n, null, true); - if ($a->type === 'Announce' && is_array($a->obj) - && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) { + if ( + $a->type === 'Announce' && is_array($a->obj) + && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj) + ) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); @@ -3856,7 +3921,6 @@ class Activity $item = $hookinfo['item']; if ($item) { - // don't leak any private conversations to the public stream // even if they contain publicly addressed comments/reactions @@ -3946,7 +4010,8 @@ class Activity $s_alt = htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); - if ((strpos($body, ']' . $s . '[/img]') === false) && + if ( + (strpos($body, ']' . $s . '[/img]') === false) && (strpos($body, ']' . $s . '[/zmg]') === false) && (strpos($body, ']' . $s . '[/video]') === false) && (strpos($body, ']' . $s . '[/zvideo]') === false) && @@ -3957,7 +4022,8 @@ class Activity (strpos($body, ']' . $s_alt . '[/video]') === false) && (strpos($body, ']' . $s_alt . '[/zvideo]') === false) && (strpos($body, ']' . $s_alt . '[/audio]') === false) && - (strpos($body, ']' . $s_alt . '[/zaudio]') === false)) { + (strpos($body, ']' . $s_alt . '[/zaudio]') === false) + ) { return true; } return false; @@ -4077,9 +4143,9 @@ class Activity $content = false; - if (array_key_exists($field, $act) && $act[$field]) + if (array_key_exists($field, $act) && $act[$field]) { $content = (($binary) ? $act[$field] : purify_html($act[$field])); - elseif (array_key_exists($field . 'Map', $act) && $act[$field . 'Map']) { + } elseif (array_key_exists($field . 'Map', $act) && $act[$field . 'Map']) { foreach ($act[$field . 'Map'] as $k => $v) { $content[escape_tags($k)] = (($binary) ? $v : purify_html($v)); } @@ -4090,7 +4156,8 @@ class Activity public static function send_rejection_activity($channel, $observer_hash, $item) { - $recip = q("select * from hubloc where hubloc_hash = '%s' limit 1", + $recip = q( + "select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($observer_hash) ); if (!$recip) { @@ -4114,7 +4181,6 @@ class Activity $queue_id = ActivityPub::queue_message(json_encode($msg, JSON_UNESCAPED_SLASHES), $channel, $recip[0]); do_delivery([$queue_id]); - } // Find either an Authorization: Bearer token or 'token' request variable @@ -4187,18 +4253,21 @@ class Activity switch (trim($options_arr[0])) { case 'activitypub': - $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' $sql_options ", + $hublocs = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' $sql_options ", dbesc($url) ); break; case 'zot6': - $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_id_url = '%s' $sql_options ", + $hublocs = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_id_url = '%s' $sql_options ", dbesc($url) ); break; case 'all': default: - $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_id_url = '%s' OR hubloc_hash = '%s' ) $sql_options ", + $hublocs = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_id_url = '%s' OR hubloc_hash = '%s' ) $sql_options ", dbesc($url), dbesc($url) ); @@ -4261,8 +4330,5 @@ class Activity 'capabilities' => 'litepub:capabilities', 'acceptsJoins' => 'litepub:acceptsJoins', ]; - } - - } diff --git a/Zotlabs/Lib/ActivityPub.php b/Zotlabs/Lib/ActivityPub.php index 101552042..ee09c1ba9 100644 --- a/Zotlabs/Lib/ActivityPub.php +++ b/Zotlabs/Lib/ActivityPub.php @@ -1,4 +1,5 @@ channel_url($arr['channel']) . '?operation=delete', 'actor' => channel_url($arr['channel']), @@ -71,7 +69,6 @@ class ActivityPub logger('ActivityPub_encoded (purge_all): ' . json_encode($msg, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $jmsg = json_encode($msg, JSON_UNESCAPED_SLASHES); - } else { $target_item = $arr['target_item']; @@ -85,7 +82,6 @@ class ActivityPub if ($signed_msg) { $jmsg = $signed_msg; } else { - // Rewrite outbound mentions so they match the ActivityPub convention, which // is to pretend that the preferred display name doesn't exist and instead use // the username or webfinger address when displaying names. This is likely to @@ -101,18 +97,18 @@ class ActivityPub return; } -// $token = IConfig::get($target_item['id'],'ocap','relay'); -// if ($token) { -// if (defined('USE_BEARCAPS')) { -// $ti['id'] = 'bear:?u=' . $ti['id'] . '&t=' . $token; -// } -// else { -// $ti['id'] = $ti['id'] . '?token=' . $token; -// } -// if ($ti['url'] && is_string($ti['url'])) { -// $ti['url'] .= '?token=' . $token; -// } -// } +// $token = IConfig::get($target_item['id'],'ocap','relay'); +// if ($token) { +// if (defined('USE_BEARCAPS')) { +// $ti['id'] = 'bear:?u=' . $ti['id'] . '&t=' . $token; +// } +// else { +// $ti['id'] = $ti['id'] . '?token=' . $token; +// } +// if ($ti['url'] && is_string($ti['url'])) { +// $ti['url'] .= '?token=' . $token; +// } +// } $msg = array_merge(['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, @@ -136,7 +132,8 @@ class ActivityPub $hashes[] = "'" . $recip . "'"; } - $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_url = '%s' + $r = q( + "select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_url = '%s' and xchan_hash in (" . implode(',', $hashes) . ") and xchan_network = 'activitypub' ", dbesc($arr['hub']['hubloc_url']) ); @@ -147,7 +144,6 @@ class ActivityPub } foreach ($r as $contact) { - // is $contact connected with this channel - and if the channel is cloned, also on this hub? // 2018-10-19 this probably doesn't apply to activitypub anymore, just send the thing. // They'll reject it if they don't like it. @@ -163,9 +159,7 @@ class ActivityPub } continue; } - } else { - // public message // See if we can deliver all of them at once @@ -179,8 +173,8 @@ class ActivityPub $arr['queued'][] = $qi; } } else { - - $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_url = '%s' and xchan_network = 'activitypub' ", + $r = q( + "select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_url = '%s' and xchan_network = 'activitypub' ", dbesc($arr['hub']['hubloc_url']) ); @@ -190,7 +184,6 @@ class ActivityPub } foreach ($r as $contact) { - // $single = deliverable_singleton($arr['channel']['channel_id'],$contact); $qi = self::queue_message($jmsg, $arr['channel'], $contact, $target_item['mid']); @@ -202,7 +195,6 @@ class ActivityPub } return; - } @@ -233,7 +225,8 @@ class ActivityPub ]); if ($message_id && (!get_config('system', 'disable_dreport'))) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) values ( '%s','%s','%s','%s','%s','%s','%s','%s' ) ", + q( + "insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue, dreport_log ) values ( '%s','%s','%s','%s','%s','%s','%s','%s' ) ", dbesc($message_id), dbesc($dest_url), dbesc($dest_url), @@ -277,18 +270,20 @@ class ActivityPub $orig_follow = get_abconfig($x['sender']['channel_id'], $x['recipient']['xchan_hash'], 'activitypub', 'their_follow_id'); $orig_follow_type = get_abconfig($x['sender']['channel_id'], $x['recipient']['xchan_hash'], 'activitypub', 'their_follow_type'); - $msg = array_merge(['@context' => [ + $msg = array_merge( + ['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', Activity::ap_schema() - ]], + ]], [ 'id' => z_root() . '/follow/' . $x['recipient']['abook_id'] . (($orig_follow) ? '/' . md5($orig_follow) : EMPTY_STR), 'type' => (($orig_follow_type) ? $orig_follow_type : 'Follow'), 'actor' => $p, 'object' => $x['recipient']['xchan_hash'], 'to' => [$x['recipient']['xchan_hash']] - ]); + ] + ); // for Group actors, send both a Follow and a Join because some platforms only support one and there's // no way of discovering/knowing in advance which type they support @@ -305,7 +300,8 @@ class ActivityPub $msg['signature'] = LDSignatures::sign($msg, $x['sender']); $jmsg = json_encode($msg, JSON_UNESCAPED_SLASHES); - $h = q("select * from hubloc where hubloc_hash = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($x['recipient']['xchan_hash']) ); @@ -348,11 +344,12 @@ class ActivityPub return; } - $msg = array_merge(['@context' => [ + $msg = array_merge( + ['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', Activity::ap_schema() - ]], + ]], [ 'id' => z_root() . '/follow/' . $x['recipient']['abook_id'] . '/' . md5($accept), 'type' => 'Accept', @@ -364,13 +361,15 @@ class ActivityPub 'object' => z_root() . '/channel/' . $x['sender']['channel_address'] ], 'to' => [$x['recipient']['xchan_hash']] - ]); + ] + ); $msg['signature'] = LDSignatures::sign($msg, $x['sender']); $jmsg = json_encode($msg, JSON_UNESCAPED_SLASHES); - $h = q("select * from hubloc where hubloc_hash = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($x['recipient']['xchan_hash']) ); @@ -382,18 +381,19 @@ class ActivityPub } $x['success'] = true; - } public static function contact_remove($channel_id, $abook) { - $recip = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d", + $recip = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d", intval($abook['abook_id']) ); - if ((!$recip) || $recip[0]['xchan_network'] !== 'activitypub') + if ((!$recip) || $recip[0]['xchan_network'] !== 'activitypub') { return; + } $channel = channelx_by_n($recip[0]['abook_channel']); if (!$channel) { @@ -410,14 +410,14 @@ class ActivityPub $orig_activity = get_abconfig($recip[0]['abook_channel'], $recip[0]['xchan_hash'], 'activitypub', 'follow_id'); if ($orig_activity && $recip[0]['abook_pending']) { - // was never approved - $msg = array_merge(['@context' => [ + $msg = array_merge( + ['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', Activity::ap_schema() - ]], + ]], [ 'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . '/' . md5($orig_activity) . '?operation=reject', 'type' => 'Reject', @@ -429,18 +429,18 @@ class ActivityPub 'object' => $p ], 'to' => [$recip[0]['xchan_hash']] - ]); + ] + ); del_abconfig($recip[0]['abook_channel'], $recip[0]['xchan_hash'], 'activitypub', 'follow_id'); - } else { - // send an unfollow - $msg = array_merge(['@context' => [ + $msg = array_merge( + ['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', Activity::ap_schema() - ]], + ]], [ 'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . (($orig_activity) ? '/' . md5($orig_activity) : EMPTY_STR) . '?operation=unfollow', 'type' => 'Undo', @@ -452,14 +452,16 @@ class ActivityPub 'object' => $recip[0]['xchan_hash'] ], 'to' => [$recip[0]['xchan_hash']] - ]); + ] + ); } $msg['signature'] = LDSignatures::sign($msg, $channel); $jmsg = json_encode($msg, JSON_UNESCAPED_SLASHES); - $h = q("select * from hubloc where hubloc_hash = '%s' limit 1", + $h = q( + "select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($recip[0]['xchan_hash']) ); @@ -488,7 +490,6 @@ class ActivityPub } if (isset($person_obj)) { - Activity::actor_store($person_obj['id'], $person_obj, $force); return $person_obj['id']; } @@ -531,13 +532,15 @@ class ActivityPub if ($approvals) { foreach ($approvals as $approval) { if ($approval === $src_xchan) { - $abooks = q("select abook_channel from abook where abook_xchan = '%s'", + $abooks = q( + "select abook_channel from abook where abook_xchan = '%s'", dbesc($src_xchan) ); if ($abooks) { foreach ($abooks as $abook) { // check to see if we already performed this action - $x = q("select * from abook where abook_xchan = '%s' and abook_channel = %d", + $x = q( + "select * from abook where abook_xchan = '%s' and abook_channel = %d", dbesc($dst_xchan), intval($abook['abook_channel']) ); @@ -545,23 +548,27 @@ class ActivityPub continue; } // update the local abook - q("update abconfig set xchan = '%s' where chan = %d and xchan = '%s'", + q( + "update abconfig set xchan = '%s' where chan = %d and xchan = '%s'", dbesc($dst_xchan), intval($abook['abook_channel']), dbesc($src_xchan) ); - q("update pgrp_member set xchan = '%s' where uid = %d and xchan = '%s'", + q( + "update pgrp_member set xchan = '%s' where uid = %d and xchan = '%s'", dbesc($dst_xchan), intval($abook['abook_channel']), dbesc($src_xchan) ); - $r = q("update abook set abook_xchan = '%s' where abook_xchan = '%s' and abook_channel = %d ", + $r = q( + "update abook set abook_xchan = '%s' where abook_xchan = '%s' and abook_channel = %d ", dbesc($dst_xchan), dbesc($src_xchan), intval($abook['abook_channel']) ); - $r = q("SELECT abook.*, xchan.* + $r = q( + "SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(abook['abook_channel']), @@ -584,5 +591,4 @@ class ActivityPub } } } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php index c42cd8d6c..72342288a 100644 --- a/Zotlabs/Lib/ActivityStreams.php +++ b/Zotlabs/Lib/ActivityStreams.php @@ -4,7 +4,6 @@ namespace Zotlabs\Lib; use Zotlabs\Web\HTTPSig; - /** * @brief ActivityStreams class. * @@ -57,7 +56,6 @@ class ActivityStreams } if ($this->data) { - // verify and unpack JSalmon signature if present // This will only be the case for Zot6 packets @@ -90,7 +88,6 @@ class ActivityStreams $this->valid = false; } } - } // Attempt to assemble an Activity from what we were given. @@ -108,8 +105,10 @@ class ActivityStreams $this->ldsig = $this->get_compound_property('signature'); if ($this->ldsig) { $this->signer = $this->get_compound_property('creator', $this->ldsig); - if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) - && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) { + if ( + $this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) + && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem'] + ) { $this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']); } } @@ -199,7 +198,7 @@ class ActivityStreams } // not yet ready for prime time -// $x = $this->expand($x,$base,$namespace); +// $x = $this->expand($x,$base,$namespace); return $x; } @@ -472,4 +471,4 @@ class ActivityStreams return (($x) ? true : false); } -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Api_router.php b/Zotlabs/Lib/Api_router.php index 5b75698b3..4c238a49d 100644 --- a/Zotlabs/Lib/Api_router.php +++ b/Zotlabs/Lib/Api_router.php @@ -2,7 +2,6 @@ namespace Zotlabs\Lib; - class Api_router { @@ -32,5 +31,4 @@ class Api_router { return self::$routes; } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index 11158a208..53d3ecfe6 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -53,7 +53,6 @@ class Apps call_hooks('get_system_apps', $ret); return $ret; - } public static function get_base_apps() @@ -107,7 +106,8 @@ class Apps self::$available_apps = q("select * from app where app_channel = 0"); - self::$installed_apps = q("select * from app where app_channel = %d", + self::$installed_apps = q( + "select * from app where app_channel = %d", intval(local_channel()) ); @@ -130,7 +130,8 @@ class Apps } if ($id !== true) { // if we already installed this app, but it changed, preserve any categories we created - $r = q("select term from term where otype = %d and oid = %d", + $r = q( + "select term from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($id) ); @@ -142,7 +143,6 @@ class Apps $app['guid'] = hash('whirlpool', $app['name']); $app['system'] = 1; self::app_install(local_channel(), $app); - } } } @@ -161,13 +161,17 @@ class Apps foreach (self::$available_apps as $iapp) { if ($iapp['app_id'] == hash('whirlpool', $app['name'])) { $notfound = false; - if ((isset($app['version']) && $iapp['app_version'] !== $app['version']) - || ((isset($app['plugin']) && $app['plugin']) && (!(isset($iapp['app_plugin']) && $iapp['app_plugin'])))) { + if ( + (isset($app['version']) && $iapp['app_version'] !== $app['version']) + || ((isset($app['plugin']) && $app['plugin']) && (!(isset($iapp['app_plugin']) && $iapp['app_plugin']))) + ) { return intval($iapp['app_id']); } - if (($iapp['app_url'] !== $app['url']) - || ($iapp['app_photo'] !== $app['photo'])) { + if ( + ($iapp['app_url'] !== $app['url']) + || ($iapp['app_photo'] !== $app['photo']) + ) { return intval($iapp['app_id']); } } @@ -188,8 +192,10 @@ class Apps foreach (self::$installed_apps as $iapp) { if ($iapp['app_id'] == hash('whirlpool', $app['name'])) { $installed = true; - if (($iapp['app_version'] != $app['version']) - || (isset($app['plugin']) && $app['plugin'] && (!(isset($iapp['app_plugin']) && $iapp['app_plugin'])))) { + if ( + ($iapp['app_version'] != $app['version']) + || (isset($app['plugin']) && $app['plugin'] && (!(isset($iapp['app_plugin']) && $iapp['app_plugin']))) + ) { return intval($iapp['app_id']); } } @@ -629,7 +635,8 @@ class Apps { if (!is_array($app)) { - $r = q("select * from app where app_name = '%s' and app_channel = 0", + $r = q( + "select * from app where app_name = '%s' and app_channel = 0", dbesc($app) ); if (!$r) { @@ -648,14 +655,16 @@ class Apps } if ($x['success']) { - $r = q("select * from app where app_id = '%s' and app_channel = %d limit 1", + $r = q( + "select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($x['app_id']), intval($uid) ); if ($r) { if (($app['uid']) && (!$r[0]['app_system'])) { if ($app['categories'] && (!$app['term'])) { - $r[0]['term'] = q("select * from term where otype = %d and oid = %d", + $r[0]['term'] = q( + "select * from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($r[0]['id']) ); @@ -695,8 +704,8 @@ class Apps { if ($uid && $app['guid']) { - - $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", + $x = q( + "select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['guid']), intval($uid) ); @@ -704,17 +713,20 @@ class Apps if (!intval($x[0]['app_deleted'])) { $x[0]['app_deleted'] = 1; if (self::can_delete($uid, $app)) { - $r = q("delete from app where app_id = '%s' and app_channel = %d", + $r = q( + "delete from app where app_id = '%s' and app_channel = %d", dbesc($app['guid']), intval($uid) ); - q("delete from term where otype = %d and oid = %d", + q( + "delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($x[0]['id']) ); call_hooks('app_destroy', $x[0]); } else { - $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", + $r = q( + "update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", dbesc($app['guid']), intval($uid) ); @@ -729,7 +741,6 @@ class Apps } } } - } public static function app_undestroy($uid, $app) @@ -738,14 +749,15 @@ class Apps // undelete a system app if ($uid && $app['guid']) { - - $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", + $x = q( + "select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['guid']), intval($uid) ); if ($x) { if ($x[0]['app_system']) { - $r = q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d", + $r = q( + "update app set app_deleted = 0 where app_id = '%s' and app_channel = %d", dbesc($app['guid']), intval($uid) ); @@ -756,19 +768,22 @@ class Apps public static function app_feature($uid, $app, $term) { - $r = q("select id from app where app_id = '%s' and app_channel = %d limit 1", + $r = q( + "select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['guid']), intval($uid) ); - $x = q("select * from term where otype = %d and oid = %d and term = '%s' limit 1", + $x = q( + "select * from term where otype = %d and oid = %d and term = '%s' limit 1", intval(TERM_OBJ_APP), intval($r[0]['id']), dbesc($term) ); if ($x) { - q("delete from term where otype = %d and oid = %d and term = '%s'", + q( + "delete from term where otype = %d and oid = %d and term = '%s'", intval(TERM_OBJ_APP), intval($x[0]['oid']), dbesc($term) @@ -781,7 +796,8 @@ class Apps public static function app_installed($uid, $app, $bypass_filter = false) { - $r = q("select id from app where app_id = '%s' and app_channel = %d limit 1", + $r = q( + "select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc((array_key_exists('guid', $app)) ? $app['guid'] : ''), intval($uid) ); @@ -796,13 +812,13 @@ class Apps } return (($r) ? true : false); - } public static function addon_app_installed($uid, $app, $bypass_filter = false) { - $r = q("select id from app where app_plugin = '%s' and app_channel = %d limit 1", + $r = q( + "select id from app where app_plugin = '%s' and app_channel = %d limit 1", dbesc($app), intval($uid) ); @@ -817,13 +833,13 @@ class Apps } return (($r) ? true : false); - } public static function system_app_installed($uid, $app, $bypass_filter = false) { - $r = q("select id from app where app_id = '%s' and app_channel = %d and app_deleted = 0 limit 1", + $r = q( + "select id from app where app_id = '%s' and app_channel = %d and app_deleted = 0 limit 1", dbesc(hash('whirlpool', $app)), intval($uid) ); @@ -848,19 +864,20 @@ class Apps $sql_extra = " and app_deleted = 0 "; } if ($cats) { - $cat_sql_extra = " and ( "; foreach ($cats as $cat) { - if (strpos($cat_sql_extra, 'term')) + if (strpos($cat_sql_extra, 'term')) { $cat_sql_extra .= "or "; + } $cat_sql_extra .= "term = '" . dbesc($cat) . "' "; } $cat_sql_extra .= ") "; - $r = q("select oid from term where otype = %d $cat_sql_extra", + $r = q( + "select oid from term where otype = %d $cat_sql_extra", intval(TERM_OBJ_APP) ); if (!$r) { @@ -869,7 +886,8 @@ class Apps $sql_extra .= " and app.id in ( " . array_elm_to_str($r, 'oid') . ') '; } - $r = q("select * from app where app_channel = %d $sql_extra order by app_name asc", + $r = q( + "select * from app where app_channel = %d $sql_extra order by app_name asc", intval($uid) ); @@ -881,7 +899,8 @@ class Apps if (!$r[$x]['app_system']) { $r[$x]['type'] = 'personal'; } - $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", + $r[$x]['term'] = q( + "select * from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($r[$x]['id']) ); @@ -898,7 +917,8 @@ class Apps // not yet finished // somehow need to account for translations - $r = q("select * from app where app_channel = 0 $sql_extra order by app_name asc", + $r = q( + "select * from app where app_channel = 0 $sql_extra order by app_name asc", intval($uid) ); @@ -909,8 +929,9 @@ class Apps public static function app_order($uid, $apps, $menu) { - if (!$apps) + if (!$apps) { return $apps; + } $conf = (($menu === 'nav_featured_app') ? 'app_order' : 'app_pin_order'); @@ -938,7 +959,6 @@ class Apps } } return $ret; - } public static function find_app_in_array($name, $arr) @@ -999,7 +1019,6 @@ class Apps } set_pconfig($uid, 'system', $conf, implode(',', $narr)); - } public static function movedown($uid, $guid, $menu) @@ -1047,7 +1066,6 @@ class Apps } set_pconfig($uid, 'system', $conf, implode(',', $narr)); - } public static function app_decode($s) @@ -1074,7 +1092,6 @@ class Apps $arr['url'] = str_replace(array('$baseurl', '$nick'), array($baseurl, $address), $arr['url']); $arr['photo'] = str_replace(array('$baseurl', '$nick'), array($baseurl, $address), $arr['photo']); - } @@ -1128,7 +1145,8 @@ class Apps $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, app_system, app_plugin, app_deleted, app_options ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d )", + $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, app_system, app_plugin, app_deleted, app_options ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d )", dbesc($darray['app_id']), dbesc($darray['app_sig']), dbesc($darray['app_author']), @@ -1156,7 +1174,8 @@ class Apps } if ($arr['categories']) { - $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", + $x = q( + "select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc($darray['app_id']), intval($darray['app_channel']) ); @@ -1218,7 +1237,8 @@ class Apps $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', app_system = %d, app_plugin = '%s', app_deleted = %d, app_options = %d where app_id = '%s' and app_channel = %d", + $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', app_system = %d, app_plugin = '%s', app_deleted = %d, app_options = %d where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), @@ -1243,18 +1263,21 @@ class Apps $ret['app_id'] = $darray['app_id']; } - $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", + $x = q( + "select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc($darray['app_id']), intval($darray['app_channel']) ); // if updating an embed app and we don't have a 0 channel_id don't mess with any existing categories - if (array_key_exists('embed', $arr) && intval($arr['embed']) && (intval($darray['app_channel']))) + if (array_key_exists('embed', $arr) && intval($arr['embed']) && (intval($darray['app_channel']))) { return $ret; + } if ($x) { - q("delete from term where otype = %d and oid = %d", + q( + "delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($x[0]['id']) ); @@ -1272,7 +1295,6 @@ class Apps } return $ret; - } @@ -1350,7 +1372,6 @@ class Apps $j = json_encode($ret); return '[app]' . chunk_split(base64_encode($j), 72, "\n") . '[/app]'; - } @@ -1358,7 +1379,4 @@ class Apps { return chunk_split(base64_encode(json_encode($papp)), 72, "\n"); } - } - - diff --git a/Zotlabs/Lib/Cache.php b/Zotlabs/Lib/Cache.php index cea075659..f3c227261 100644 --- a/Zotlabs/Lib/Cache.php +++ b/Zotlabs/Lib/Cache.php @@ -1,51 +1,63 @@ -= $limit)) { $ret['message'] = upgrade_message(); return $ret; } - if (!array_key_exists('expire', $arr)) + if (!array_key_exists('expire', $arr)) { $arr['expire'] = 120; // minutes, e.g. 2 hours + } $created = datetime_convert(); - $x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid ) + $x = q( + "insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid ) values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel['channel_id']), @@ -67,8 +73,9 @@ class Chatroom dbesc($arr['deny_gid']) ); - if ($x) + if ($x) { $ret['success'] = true; + } return $ret; } @@ -79,16 +86,17 @@ class Chatroom $ret = array('success' => false); - if (intval($arr['cr_id'])) + if (intval($arr['cr_id'])) { $sql_extra = " and cr_id = " . intval($arr['cr_id']) . " "; - elseif (trim($arr['cr_name'])) + } elseif (trim($arr['cr_name'])) { $sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' "; - else { + } else { $ret['message'] = t('Invalid room specifier.'); return $ret; } - $r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1", + $r = q( + "select * from chatroom where cr_uid = %d $sql_extra limit 1", intval($channel['channel_id']) ); if (!$r) { @@ -98,14 +106,17 @@ class Chatroom Libsync::build_sync_packet($channel['channel_id'], array('chatroom' => $r)); - q("delete from chatroom where cr_id = %d", + q( + "delete from chatroom where cr_id = %d", intval($r[0]['cr_id']) ); if ($r[0]['cr_id']) { - q("delete from chatpresence where cp_room = %d", + q( + "delete from chatpresence where cp_room = %d", intval($r[0]['cr_id']) ); - q("delete from chat where chat_room = %d", + q( + "delete from chat where chat_room = %d", intval($r[0]['cr_id']) ); } @@ -118,10 +129,12 @@ class Chatroom public static function enter($observer_xchan, $room_id, $status, $client) { - if (!$room_id || !$observer_xchan) + if (!$room_id || !$observer_xchan) { return; + } - $r = q("select * from chatroom where cr_id = %d limit 1", + $r = q( + "select * from chatroom where cr_id = %d limit 1", intval($room_id) ); if (!$r) { @@ -131,7 +144,8 @@ class Chatroom require_once('include/security.php'); $sql_extra = permissions_sql($r[0]['cr_uid']); - $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", + $x = q( + "select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", intval($room_id), intval($r[0]['cr_uid']) ); @@ -142,7 +156,8 @@ class Chatroom $limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom'); if ($limit !== false) { - $y = q("select count(*) as total from chatpresence where cp_room = %d", + $y = q( + "select count(*) as total from chatpresence where cp_room = %d", intval($room_id) ); if ($y && $y[0]['total'] > $limit) { @@ -152,19 +167,22 @@ class Chatroom } if (intval($x[0]['cr_expire'])) { - $r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d", + $r = q( + "delete from chat where created < %s - INTERVAL %s and chat_room = %d", db_utcnow(), db_quoteinterval(intval($x[0]['cr_expire']) . ' MINUTE'), intval($x[0]['cr_id']) ); } - $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1", + $r = q( + "select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1", dbesc($observer_xchan), intval($room_id) ); if ($r) { - q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'", + q( + "update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'", dbesc(datetime_convert()), intval($r[0]['cp_id']), dbesc($client) @@ -172,7 +190,8 @@ class Chatroom return true; } - $r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client ) + $r = q( + "insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client ) values ( %d, '%s', '%s', '%s', '%s' )", intval($room_id), dbesc($observer_xchan), @@ -187,16 +206,19 @@ class Chatroom public function leave($observer_xchan, $room_id, $client) { - if (!$room_id || !$observer_xchan) + if (!$room_id || !$observer_xchan) { return; + } - $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1", + $r = q( + "select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1", dbesc($observer_xchan), intval($room_id), dbesc($client) ); if ($r) { - q("delete from chatpresence where cp_id = %d", + q( + "delete from chatpresence where cp_id = %d", intval($r[0]['cp_id']) ); } @@ -210,7 +232,8 @@ class Chatroom require_once('include/security.php'); $sql_extra = permissions_sql($uid); - $r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name", + $r = q( + "select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name", intval($uid) ); @@ -222,7 +245,8 @@ class Chatroom require_once('include/security.php'); $sql_extra = permissions_sql($uid); - $r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra", + $r = q( + "select count(*) as total from chatroom where cr_uid = %d $sql_extra", intval($uid) ); @@ -245,17 +269,20 @@ class Chatroom $ret = array('success' => false); - if (!$text) + if (!$text) { return; + } $sql_extra = permissions_sql($uid); - $r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra", + $r = q( + "select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra", intval($uid), intval($room_id) ); - if (!$r) + if (!$r) { return $ret; + } $arr = [ 'chat_room' => $room_id, @@ -271,7 +298,8 @@ class Chatroom */ call_hooks('chat_message', $arr); - $x = q("insert into chat ( chat_room, chat_xchan, created, chat_text ) + $x = q( + "insert into chat ( chat_room, chat_xchan, created, chat_text ) values( %d, '%s', '%s', '%s' )", intval($room_id), dbesc($xchan), diff --git a/Zotlabs/Lib/Config.php b/Zotlabs/Lib/Config.php index 5997968cc..6aba9b319 100644 --- a/Zotlabs/Lib/Config.php +++ b/Zotlabs/Lib/Config.php @@ -2,163 +2,174 @@ namespace Zotlabs\Lib; - use App; -class Config { +class Config +{ - /** - * @brief Loads the hub's configuration from database to a cached storage. - * - * Retrieve a category ($family) of config variables from database to a cached - * storage in the global App::$config[$family]. - * - * @param string $family - * The category of the configuration value - */ - public static function Load($family) { - if(! array_key_exists($family, App::$config)) - App::$config[$family] = []; + /** + * @brief Loads the hub's configuration from database to a cached storage. + * + * Retrieve a category ($family) of config variables from database to a cached + * storage in the global App::$config[$family]. + * + * @param string $family + * The category of the configuration value + */ + public static function Load($family) + { + if (! array_key_exists($family, App::$config)) { + App::$config[$family] = []; + } - if(! array_key_exists('config_loaded', App::$config[$family])) { - $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family)); - if($r !== false) { - if($r) { - foreach($r as $rr) { - $k = $rr['k']; - App::$config[$family][$k] = $rr['v']; - } - } - App::$config[$family]['config_loaded'] = true; - } - } - } + if (! array_key_exists('config_loaded', App::$config[$family])) { + $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family)); + if ($r !== false) { + if ($r) { + foreach ($r as $rr) { + $k = $rr['k']; + App::$config[$family][$k] = $rr['v']; + } + } + App::$config[$family]['config_loaded'] = true; + } + } + } - /** - * @brief Sets a configuration value for the hub. - * - * Stores a config value ($value) in the category ($family) under the key ($key). - * - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to set - * @param mixed $value - * The value to store in the configuration - * @return mixed - * Return the set value, or false if the database update failed - */ - public static function Set($family, $key, $value) { - // manage array value - $dbvalue = ((is_array($value)) ? serialise($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + /** + * @brief Sets a configuration value for the hub. + * + * Stores a config value ($value) in the category ($family) under the key ($key). + * + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to set + * @param mixed $value + * The value to store in the configuration + * @return mixed + * Return the set value, or false if the database update failed + */ + public static function Set($family, $key, $value) + { + // manage array value + $dbvalue = ((is_array($value)) ? serialise($value) : $value); + $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) { - $ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ", - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - if($ret) { - App::$config[$family][$key] = $value; - $ret = $value; - } - return $ret; - } + if (self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) { + $ret = q( + "INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ", + dbesc($family), + dbesc($key), + dbesc($dbvalue) + ); + if ($ret) { + App::$config[$family][$key] = $value; + $ret = $value; + } + return $ret; + } - $ret = q("UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s'", - dbesc($dbvalue), - dbesc($family), - dbesc($key) - ); + $ret = q( + "UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s'", + dbesc($dbvalue), + dbesc($family), + dbesc($key) + ); - if($ret) { - App::$config[$family][$key] = $value; - $ret = $value; - } + if ($ret) { + App::$config[$family][$key] = $value; + $ret = $value; + } - return $ret; - } + return $ret; + } - /** - * @brief Get a particular config variable given the category name ($family) - * and a key. - * - * Get a particular config variable from the given category ($family) and the - * $key from a cached storage in App::$config[$family]. If a key is found in the - * DB but does not exist in local config cache, pull it into the cache so we - * do not have to hit the DB again for this item. - * - * Returns false if not set. - * - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @param string $default (optional) default false - * @return mixed Return value or false on error or if not set - */ - public static function Get($family, $key, $default = false) { - if((! array_key_exists($family, App::$config)) || (! array_key_exists('config_loaded', App::$config[$family]))) - self::Load($family); + /** + * @brief Get a particular config variable given the category name ($family) + * and a key. + * + * Get a particular config variable from the given category ($family) and the + * $key from a cached storage in App::$config[$family]. If a key is found in the + * DB but does not exist in local config cache, pull it into the cache so we + * do not have to hit the DB again for this item. + * + * Returns false if not set. + * + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to query + * @param string $default (optional) default false + * @return mixed Return value or false on error or if not set + */ + public static function Get($family, $key, $default = false) + { + if ((! array_key_exists($family, App::$config)) || (! array_key_exists('config_loaded', App::$config[$family]))) { + self::Load($family); + } - if(array_key_exists('config_loaded', App::$config[$family])) { - if(! array_key_exists($key, App::$config[$family])) { - return $default; - } - return unserialise(App::$config[$family][$key]); - } + if (array_key_exists('config_loaded', App::$config[$family])) { + if (! array_key_exists($key, App::$config[$family])) { + return $default; + } + return unserialise(App::$config[$family][$key]); + } - return $default; - } + return $default; + } - /** - * @brief Deletes the given key from the hub's configuration database. - * - * Removes the configured value from the stored cache in App::$config[$family] - * and removes it from the database. - * - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to delete - * @return mixed - */ - public static function Delete($family, $key) { + /** + * @brief Deletes the given key from the hub's configuration database. + * + * Removes the configured value from the stored cache in App::$config[$family] + * and removes it from the database. + * + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to delete + * @return mixed + */ + public static function Delete($family, $key) + { - $ret = false; + $ret = false; - if(array_key_exists($family, App::$config) && array_key_exists($key, App::$config[$family])) - unset(App::$config[$family][$key]); + if (array_key_exists($family, App::$config) && array_key_exists($key, App::$config[$family])) { + unset(App::$config[$family][$key]); + } - $ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'", - dbesc($family), - dbesc($key) - ); + $ret = q( + "DELETE FROM config WHERE cat = '%s' AND k = '%s'", + dbesc($family), + dbesc($key) + ); - return $ret; - } + return $ret; + } - /** - * @brief Returns a record directly from the database configuration storage. - * - * This function queries directly the database and bypasses the cached storage - * from get_config($family, $key). - * - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @return mixed - */ - private static function get_from_storage($family, $key) { - $ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1", - dbesc($family), - dbesc($key) - ); - - return $ret; - } + /** + * @brief Returns a record directly from the database configuration storage. + * + * This function queries directly the database and bypasses the cached storage + * from get_config($family, $key). + * + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to query + * @return mixed + */ + private static function get_from_storage($family, $key) + { + $ret = q( + "SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1", + dbesc($family), + dbesc($key) + ); + return $ret; + } } diff --git a/Zotlabs/Lib/Connect.php b/Zotlabs/Lib/Connect.php index a855afdd4..30fd33bce 100644 --- a/Zotlabs/Lib/Connect.php +++ b/Zotlabs/Lib/Connect.php @@ -1,4 +1,6 @@ - 'sha1', - 'private_key_bits' => $bits, - 'encrypt_key' => false - ]; + $openssl_options = [ + 'digest_alg' => 'sha1', + 'private_key_bits' => $bits, + 'encrypt_key' => false + ]; - $conf = get_config('system','openssl_conf_file'); - - if ($conf) { - $openssl_options['config'] = $conf; - } + $conf = get_config('system', 'openssl_conf_file'); - $result = openssl_pkey_new($openssl_options); + if ($conf) { + $openssl_options['config'] = $conf; + } - if (empty($result)) { - return false; - } + $result = openssl_pkey_new($openssl_options); - // Get private key + if (empty($result)) { + return false; + } - $response = [ 'prvkey' => '', 'pubkey' => '' ]; + // Get private key - openssl_pkey_export($result, $response['prvkey']); + $response = [ 'prvkey' => '', 'pubkey' => '' ]; - // Get public key - $pkey = openssl_pkey_get_details($result); - $response['pubkey'] = $pkey["key"]; + openssl_pkey_export($result, $response['prvkey']); - return $response; + // Get public key + $pkey = openssl_pkey_get_details($result); + $response['pubkey'] = $pkey["key"]; - } + return $response; + } - public static function sign($data, $key, $alg = 'sha256') { + public static function sign($data, $key, $alg = 'sha256') + { - if (! $key) { - return false; - } + if (! $key) { + return false; + } - $sig = ''; - openssl_sign($data,$sig,$key,$alg); - return $sig; - } + $sig = ''; + openssl_sign($data, $sig, $key, $alg); + return $sig; + } - public static function verify($data, $sig, $key, $alg = 'sha256') { + public static function verify($data, $sig, $key, $alg = 'sha256') + { - if (! $key) { - return false; - } + if (! $key) { + return false; + } - try { - $verify = openssl_verify($data,$sig,$key,$alg); - } - catch (Exception $e) { - $verify = (-1); - } + try { + $verify = openssl_verify($data, $sig, $key, $alg); + } catch (Exception $e) { + $verify = (-1); + } - if ($verify === (-1)) { - while ($msg = openssl_error_string()) { - logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); - } - btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); - } + if ($verify === (-1)) { + while ($msg = openssl_error_string()) { + logger('openssl_verify: ' . $msg, LOGGER_NORMAL, LOG_ERR); + } + btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); + } - return (($verify > 0) ? true : false); - } + return (($verify > 0) ? true : false); + } - public static function encapsulate($data, $pubkey, $alg) { + public static function encapsulate($data, $pubkey, $alg) + { - if (! ($alg && $pubkey)) { - return $data; - } + if (! ($alg && $pubkey)) { + return $data; + } - $alg_base = $alg; - $padding = OPENSSL_PKCS1_PADDING; + $alg_base = $alg; + $padding = OPENSSL_PKCS1_PADDING; - $exts = explode('.',$alg); - if (count($exts) > 1) { - switch ($exts[1]) { - case 'oaep': - $padding = OPENSSL_PKCS1_OAEP_PADDING; - break; - default: - break; - } - $alg_base = $exts[0]; - } + $exts = explode('.', $alg); + if (count($exts) > 1) { + switch ($exts[1]) { + case 'oaep': + $padding = OPENSSL_PKCS1_OAEP_PADDING; + break; + default: + break; + } + $alg_base = $exts[0]; + } - $method = null; + $method = null; - foreach (self::$openssl_algorithms as $ossl) { - if ($ossl[0] === $alg_base) { - $method = $ossl; - break; - } - } + foreach (self::$openssl_algorithms as $ossl) { + if ($ossl[0] === $alg_base) { + $method = $ossl; + break; + } + } - if ($method) { - $result = [ 'encrypted' => true ]; + if ($method) { + $result = [ 'encrypted' => true ]; - $key = openssl_random_pseudo_bytes(256); - $iv = openssl_random_pseudo_bytes(256); + $key = openssl_random_pseudo_bytes(256); + $iv = openssl_random_pseudo_bytes(256); - $key1 = substr($key, 0, $method[2]); - $iv1 = substr($iv, 0, $method[3]); + $key1 = substr($key, 0, $method[2]); + $iv1 = substr($iv, 0, $method[3]); - $result['data'] = base64url_encode(openssl_encrypt($data,$method[1],$key1,OPENSSL_RAW_DATA,$iv1),true); + $result['data'] = base64url_encode(openssl_encrypt($data, $method[1], $key1, OPENSSL_RAW_DATA, $iv1), true); - openssl_public_encrypt($key, $k, $pubkey, $padding); - openssl_public_encrypt($iv, $i, $pubkey, $padding); + openssl_public_encrypt($key, $k, $pubkey, $padding); + openssl_public_encrypt($iv, $i, $pubkey, $padding); - $result['alg'] = $alg; - $result['key'] = base64url_encode($k,true); - $result['iv'] = base64url_encode($i,true); - return $result; + $result['alg'] = $alg; + $result['key'] = base64url_encode($k, true); + $result['iv'] = base64url_encode($i, true); + return $result; + } else { + $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ]; + call_hooks('crypto_encapsulate', $x); + return $x['result']; + } + } - } - else { - $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ]; - call_hooks('crypto_encapsulate', $x); - return $x['result']; - } - } + public static function unencapsulate($data, $prvkey) + { - public static function unencapsulate($data, $prvkey) { + if (! (is_array($data) && array_key_exists('encrypted', $data) && array_key_exists('alg', $data) && $data['alg'])) { + logger('not encrypted'); - if (! (is_array($data) && array_key_exists('encrypted',$data) && array_key_exists('alg',$data) && $data['alg'])) { - logger('not encrypted'); + return $data; + } - return $data; - } + $alg_base = $data['alg']; + $padding = OPENSSL_PKCS1_PADDING; - $alg_base = $data['alg']; - $padding = OPENSSL_PKCS1_PADDING; + $exts = explode('.', $data['alg']); + if (count($exts) > 1) { + switch ($exts[1]) { + case 'oaep': + $padding = OPENSSL_PKCS1_OAEP_PADDING; + break; + default: + break; + } + $alg_base = $exts[0]; + } - $exts = explode('.',$data['alg']); - if (count($exts) > 1) { - switch ($exts[1]) { - case 'oaep': - $padding = OPENSSL_PKCS1_OAEP_PADDING; - break; - default: - break; - } - $alg_base = $exts[0]; - } + $method = null; - $method = null; + foreach (self::$openssl_algorithms as $ossl) { + if ($ossl[0] === $alg_base) { + $method = $ossl; + break; + } + } - foreach (self::$openssl_algorithms as $ossl) { - if ($ossl[0] === $alg_base) { - $method = $ossl; - break; - } - } - - if ($method) { - openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey,$padding); - openssl_private_decrypt(base64url_decode($data['iv']), $i,$prvkey,$padding); - return openssl_decrypt(base64url_decode($data['data']),$method[1],substr($k,0,$method[2]),OPENSSL_RAW_DATA,substr($i,0,$method[3])); - } - else { - $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data ]; - call_hooks('crypto_unencapsulate',$x); - return $x['result']; - } - } + if ($method) { + openssl_private_decrypt(base64url_decode($data['key']), $k, $prvkey, $padding); + openssl_private_decrypt(base64url_decode($data['iv']), $i, $prvkey, $padding); + return openssl_decrypt(base64url_decode($data['data']), $method[1], substr($k, 0, $method[2]), OPENSSL_RAW_DATA, substr($i, 0, $method[3])); + } else { + $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data ]; + call_hooks('crypto_unencapsulate', $x); + return $x['result']; + } + } } diff --git a/Zotlabs/Lib/DB_Upgrade.php b/Zotlabs/Lib/DB_Upgrade.php index 692ca98fb..56d8fc88b 100644 --- a/Zotlabs/Lib/DB_Upgrade.php +++ b/Zotlabs/Lib/DB_Upgrade.php @@ -2,7 +2,6 @@ namespace Zotlabs\Lib; - use App; class DB_Upgrade @@ -18,8 +17,9 @@ class DB_Upgrade $this->func_prefix = '_'; $build = get_config('system', 'db_version', 0); - if (!intval($build)) + if (!intval($build)) { $build = set_config('system', 'db_version', $db_revision); + } if ($build == $db_revision) { // Nothing to be done. @@ -34,7 +34,6 @@ class DB_Upgrade $current = intval($db_revision); if ($stored < $current) { - // The last update we performed was $stored. // Start at $stored + 1 and continue until we have completed $current @@ -55,8 +54,9 @@ class DB_Upgrade Config::Load('database'); - if (get_config('database', $s)) + if (get_config('database', $s)) { break; + } set_config('database', $s, '1'); @@ -65,8 +65,6 @@ class DB_Upgrade $retval = $c->run(); if ($retval != UPDATE_SUCCESS) { - - $source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php'); @@ -75,13 +73,15 @@ class DB_Upgrade $lockfile = 'cache/mailsent'; - if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400))) + if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400))) { return; + } @unlink($lockfile); //send the administrator an e-mail file_put_contents($lockfile, $x); - $r = q("select account_language from account where account_email = '%s' limit 1", + $r = q( + "select account_language from account where account_email = '%s' limit 1", dbesc(App::$config['system']['admin_email']) ); push_lang(($r) ? $r[0]['account_language'] : 'en'); @@ -89,7 +89,8 @@ class DB_Upgrade [ 'toEmail' => App::$config['system']['admin_email'], 'messageSubject' => sprintf(t('Update Error at %s'), z_root()), - 'textVersion' => replace_macros(get_intltext_template('update_fail_eml.tpl'), + 'textVersion' => replace_macros( + get_intltext_template('update_fail_eml.tpl'), [ '$sitename' => App::$config['system']['sitename'], '$siteurl' => z_root(), @@ -113,4 +114,4 @@ class DB_Upgrade set_config('system', 'db_version', $db_revision); } } -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/DReport.php b/Zotlabs/Lib/DReport.php index b023fc7fd..d0330e098 100644 --- a/Zotlabs/Lib/DReport.php +++ b/Zotlabs/Lib/DReport.php @@ -1,4 +1,5 @@ ' . t('Notification Settings') . ''); - $sender_name = $product; - $hostname = App::get_hostname(); - if(strpos($hostname,':')) - $hostname = substr($hostname,0,strpos($hostname,':')); - - // Do not translate 'noreply' as it must be a legal 7-bit email address - - $reply_email = get_config('system','reply_address'); - if(! $reply_email) - $reply_email = 'noreply' . '@' . $hostname; - - $sender_email = get_config('system','from_email'); - if(! $sender_email) - $sender_email = 'Administrator' . '@' . $hostname; - - $sender_name = get_config('system','from_email_name'); - if(! $sender_name) - $sender_name = System::get_site_name(); - - - $additional_mail_header = ""; - - if(array_key_exists('item', $params)) { - require_once('include/conversation.php'); - // if it's a normal item... - if (array_key_exists('verb', $params['item'])) { - // localize_item() alters the original item so make a copy first - $i = $params['item']; - logger('calling localize'); - localize_item($i); - $title = $i['title']; - $body = $i['body']; - $private = (($i['item_private']) || intval($i['item_obscured'])); - } - else { - $title = $params['item']['title']; - $body = $params['item']['body']; - } - if($params['item']['created'] < datetime_convert('UTC','UTC','now - 1 month')) { - logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO); - return; - } - } - else { - $title = $body = ''; - } - - - $always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices'); - $vnotify = get_pconfig($recip['channel_id'],'system','vnotify'); - - $salutation = $recip['channel_name']; - - // e.g. "your post", "David's photo", etc. - $possess_desc = t('%s '); - - if ($params['type'] == NOTIFY_MAIL) { - logger('notification: mail'); - $subject = sprintf( t('[$Projectname:Notify] New mail received at %s'),$sitename); - - if ($params['item']['mid'] === $params['item']['parent_mid']) { - $preamble = sprintf( t('%1$s sent you a new private message at %2$s.'), $sender['xchan_name'],$sitename); - $epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); - } - else { - $preamble = sprintf( t('%1$s replied to a private message at %2$s.'), $sender['xchan_name'],$sitename); - $epreamble = sprintf( t('%1$s replied to %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); - } - $sitelink = t('Please visit %s to view and/or reply to your private messages.'); - - $tsitelink = sprintf( $sitelink, $siteurl . '/display/' . gen_link_id($params['item']['mid']) ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = z_root() . '/display/' . gen_link_id($params['item']['mid']); - } - - if (in_array(intval($params['type']), [ NOTIFY_COMMENT, NOTIFY_RESHARE ] )) { - // logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); - - $moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false); - - $itemlink = $params['link']; - - $action = t('commented on'); - - if(array_key_exists('item',$params) && in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) { - - if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { - logger('notification: not a visible activity. Ignoring.'); - pop_lang(); - return; - } - - if(activity_match($params['verb'], ACTIVITY_LIKE)) - $action = t('liked'); - - if(activity_match($params['verb'], ACTIVITY_DISLIKE)) - $action = t('disliked'); - - } - - $parent_mid = $params['parent_mid']; - - // Check to see if there was already a notify for this post. - // If so don't create a second notification - - $p = null; - $p = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($params['link']), - intval($recip['channel_id']) - ); - if ($p) { - logger('notification: comment already notified'); - pop_lang(); - return; - } - - - // if it's a post figure out who's post it is. - - $p = null; - - if($params['otype'] === 'item' && $parent_mid) { - $p = q("select * from item where mid = '%s' and uid = %d limit 1", - dbesc($parent_mid), - intval($recip['channel_id']) - ); - } - - xchan_query($p); - - $item_post_type = item_post_type($p[0]); -// $private = $p[0]['item_private']; - $parent_id = $p[0]['id']; - - $parent_item = $p[0]; - - //$possess_desc = str_replace('',$possess_desc); - - // "a post" - $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]a %4$s[/zrl]'), - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $action, - $itemlink, - $item_post_type); - - // "George Bull's post" - if($p) - $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]%4$s\'s %5$s[/zrl]'), - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $action, - $itemlink, - $p[0]['author']['xchan_name'], - $item_post_type); - - // "your post" - if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) - $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'), - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $action, - $itemlink, - $item_post_type); - - // Some mail softwares relies on subject field for threading. - // So, we cannot have different subjects for notifications of the same thread. - // Before this we have the name of the replier on the subject rendering - // differents subjects for messages on the same thread. - - if($moderated) { - $subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); - $itemlink = z_root() . '/moderate/' . gen_link_id($params['item']['mid']); - } - else - $subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); - $preamble = sprintf( t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']); - $epreamble = $dest_str; - - if ($moderated) { - $epreamble .= ' ' . t('(Moderated)'); - } - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - if($moderated) { - $tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' ); - $hsitelink .= "

" . sprintf( t('Please visit %s to approve or reject this comment.'), '' . z_root() . '/moderate' ); - } - - } - - if ($params['type'] == NOTIFY_LIKE) { -// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); - - $itemlink = $params['link']; - - if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) { - if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { - logger('notification: not a visible activity. Ignoring.'); - pop_lang(); - return; - } - } - - $parent_mid = $params['parent_mid']; - - // Check to see if there was already a notify for this post. - // If so don't create a second notification - - $p = null; - $p = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($params['link']), - intval($recip['channel_id']) - ); - if ($p) { - logger('notification: like already notified'); - pop_lang(); - return; - } - - - // if it's a post figure out who's post it is. - - $p = null; - - if($params['otype'] === 'item' && $parent_mid) { - $p = q("select * from item where mid = '%s' and uid = %d limit 1", - dbesc($parent_mid), - intval($recip['channel_id']) - ); - } - - xchan_query($p); - - - $item_post_type = item_post_type($p[0]); -// $private = $p[0]['item_private']; - $parent_id = $p[0]['id']; - - $parent_item = $p[0]; - - - // "your post" - if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) - $dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'), - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink, - $item_post_type); - else { - pop_lang(); - return; - } - - // Some mail softwares relies on subject field for threading. - // So, we cannot have different subjects for notifications of the same thread. - // Before this we have the name of the replier on the subject rendering - // differents subjects for messages on the same thread. - - $subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); - $preamble = sprintf( t('%1$s liked an item/conversation you created.'), $sender['xchan_name']); - $epreamble = $dest_str; - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - } - - - - if($params['type'] == NOTIFY_WALL) { - $subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']); - - $moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false); - - $itemlink = (($moderated) ? z_root() . '/moderate/' . gen_link_id($params['item']['mid']) : $params['link']); - - $preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $sender['xchan_name'], $sitename); - - $epreamble = sprintf( t('%1$s posted to [zrl=%2$s]your wall[/zrl]') , - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink); - - - if($moderated) { - $subject .= t(' - ') . t('Moderated'); - $epreamble .= t(' - ') . t('Moderated'); - } - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - - if($moderated) { - $tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this post.'), z_root() . '/moderate' ); - $hsitelink .= "

" . sprintf( t('Please visit %s to approve or reject this post.'), '' . z_root() . '/moderate' ); - } - - } - - if ($params['type'] == NOTIFY_TAGSELF) { - - $p = null; - $p = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($params['link']), - intval($recip['channel_id']) - ); - if ($p) { - logger('enotify: tag: already notified about this post'); - pop_lang(); - return; - } - - $subject = sprintf( t('[$Projectname:Notify] %s tagged you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s tagged you at %2$s') , $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s [zrl=%2$s]tagged you[/zrl].') , - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $params['link']); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_POKE) { - $subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s poked you at %2$s') , $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s [zrl=%2$s]poked you[/zrl].') , - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $params['link']); - - $subject = str_replace('poked', t($params['activity']), $subject); - $preamble = str_replace('poked', t($params['activity']), $preamble); - $epreamble = str_replace('poked', t($params['activity']), $epreamble); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_TAGSHARE) { - $subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') , - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_INTRO) { - $subject = sprintf( t('[$Projectname:Notify] Introduction received')); - $preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'), - $siteurl . '/connections/ifpending', - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); - $body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']); - - $sitelink = t('Please visit %s to approve or reject the connection request.'); - $tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending'); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_SUGGEST) { - $subject = sprintf( t('[$Projectname:Notify] Friend suggestion received')); - $preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'), - $itemlink, - '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]', - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); - - $body = t('Name:') . ' ' . $params['item']['name'] . "\n"; - $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n"; - $body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']); - - $sitelink = t('Please visit %s to approve or reject the suggestion.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_CONFIRM) { - // ? - } - - if ($params['type'] == NOTIFY_SYSTEM) { - // ? - } - - $h = array( - 'params' => $params, - 'subject' => $subject, - 'preamble' => $preamble, - 'epreamble' => $epreamble, - 'body' => $body, - 'sitelink' => $sitelink, - 'sitename' => $sitename, - 'tsitelink' => $tsitelink, - 'hsitelink' => $hsitelink, - 'itemlink' => $itemlink, - 'sender' => $sender, - 'recipient' => $recip - ); - - call_hooks('enotify', $h); - - $subject = $h['subject']; - $preamble = $h['preamble']; - $epreamble = $h['epreamble']; - $body = $h['body']; - $sitelink = $h['sitelink']; - $tsitelink = $h['tsitelink']; - $hsitelink = $h['hsitelink']; - $itemlink = $h['itemlink']; - - - require_once('include/html2bbcode.php'); - - do { - $dups = false; - $hash = random_string(); - $r = q("SELECT id FROM notify WHERE hash = '%s' LIMIT 1", - dbesc($hash)); - if ($r) - $dups = true; - } while ($dups === true); - - - $datarray = []; - $datarray['hash'] = $hash; - $datarray['sender_hash'] = $sender['xchan_hash']; - $datarray['xname'] = $sender['xchan_name']; - $datarray['url'] = $sender['xchan_url']; - $datarray['photo'] = $sender['xchan_photo_s']; - $datarray['created'] = datetime_convert(); - $datarray['aid'] = $recip['channel_account_id']; - $datarray['uid'] = $recip['channel_id']; - $datarray['link'] = $itemlink; - $datarray['parent'] = $parent_mid; - $datarray['parent_item'] = $parent_item; - $datarray['ntype'] = $params['type']; - $datarray['verb'] = $params['verb']; - $datarray['otype'] = $params['otype']; - $datarray['abort'] = false; - - $datarray['item'] = $params['item']; - - if (LibBlock::fetch_by_entity($datarray['uid'],$datarray['sender_hash'])) { - pop_lang(); - return; - } - - if (is_array($datarray['parent_item'])) { - if (LibBlock::fetch_by_entity($datarray['uid'],$datarray['parent_item']['author_xchan']) || LibBlock::fetch_by_entity($datarray['uid'],$datarray['parent_item']['owner_xchan'])) { - pop_lang(); - return; - } - } - - call_hooks('enotify_store', $datarray); - - if ($datarray['abort']) { - pop_lang(); - return; - } - - - // create notification entry in DB - $seen = 0; - - // Mark some notifications as seen right away - // Note! The notification have to be created, because they are used to send emails - // So easiest solution to hide them from Notices is to mark them as seen right away. - // Another option would be to not add them to the DB, and change how emails are handled - // (probably would be better that way) - - if (!$always_show_in_notices) { - if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_INTRO)) { - $seen = 1; - } - // set back to unseen for moderated wall posts - if($params['type'] == NOTIFY_WALL && $params['item']['item_blocked'] == ITEM_MODERATED) { - $seen = 0; - } - - } - - $e = q("select * from notify where otype = '%s' and xname = '%s' and verb = '%s' and link = '%s' and ntype = %d limit 1", - dbesc($datarray['otype']), - dbesc($datarray['xname']), - dbesc($datarray['verb']), - dbesc($datarray['link']), - intval($datarray['ntype']) - ); - if($e) { - logger('duplicated notification'); - pop_lang(); - return; - } - - $r = q("insert into notify (hash,xname,url,photo,created,msg,aid,uid,link,parent,seen,ntype,verb,otype) + dbesc($params['to_xchan']) + ); + } + if ($x && $y) { + $sender = $x[0]; + $recip = $y[0]; + } else { + logger('notification: no sender or recipient.'); + logger('sender: ' . $params['from_xchan']); + logger('recip: ' . $params['to_xchan']); + return; + } + + + + // from here on everything is in the recipients language + + push_lang($recip['account_language']); // should probably have a channel language + + $banner = t('$Projectname Notification'); + $product = t('$projectname'); // PLATFORM_NAME; + $siteurl = z_root(); + $thanks = t('Thank You,'); + $sitename = get_config('system', 'sitename'); + $site_admin = sprintf(t('%s Administrator'), $sitename); + $opt_out1 = sprintf(t('This email was sent by %1$s at %2$s.'), t('$Projectname'), App::get_hostname()); + $opt_out2 = sprintf(t('To stop receiving these messages, please adjust your Notification Settings at %s'), z_root() . '/settings'); + $hopt_out2 = sprintf(t('To stop receiving these messages, please adjust your %s.'), '' . t('Notification Settings') . ''); + $sender_name = $product; + $hostname = App::get_hostname(); + if (strpos($hostname, ':')) { + $hostname = substr($hostname, 0, strpos($hostname, ':')); + } + + // Do not translate 'noreply' as it must be a legal 7-bit email address + + $reply_email = get_config('system', 'reply_address'); + if (! $reply_email) { + $reply_email = 'noreply' . '@' . $hostname; + } + + $sender_email = get_config('system', 'from_email'); + if (! $sender_email) { + $sender_email = 'Administrator' . '@' . $hostname; + } + + $sender_name = get_config('system', 'from_email_name'); + if (! $sender_name) { + $sender_name = System::get_site_name(); + } + + + $additional_mail_header = ""; + + if (array_key_exists('item', $params)) { + require_once('include/conversation.php'); + // if it's a normal item... + if (array_key_exists('verb', $params['item'])) { + // localize_item() alters the original item so make a copy first + $i = $params['item']; + logger('calling localize'); + localize_item($i); + $title = $i['title']; + $body = $i['body']; + $private = (($i['item_private']) || intval($i['item_obscured'])); + } else { + $title = $params['item']['title']; + $body = $params['item']['body']; + } + if ($params['item']['created'] < datetime_convert('UTC', 'UTC', 'now - 1 month')) { + logger('notification invoked for an old item which may have been refetched.', LOGGER_DEBUG, LOG_INFO); + return; + } + } else { + $title = $body = ''; + } + + + $always_show_in_notices = get_pconfig($recip['channel_id'], 'system', 'always_show_in_notices'); + $vnotify = get_pconfig($recip['channel_id'], 'system', 'vnotify'); + + $salutation = $recip['channel_name']; + + // e.g. "your post", "David's photo", etc. + $possess_desc = t('%s '); + + if ($params['type'] == NOTIFY_MAIL) { + logger('notification: mail'); + $subject = sprintf(t('[$Projectname:Notify] New mail received at %s'), $sitename); + + if ($params['item']['mid'] === $params['item']['parent_mid']) { + $preamble = sprintf(t('%1$s sent you a new private message at %2$s.'), $sender['xchan_name'], $sitename); + $epreamble = sprintf(t('%1$s sent you %2$s.'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); + } else { + $preamble = sprintf(t('%1$s replied to a private message at %2$s.'), $sender['xchan_name'], $sitename); + $epreamble = sprintf(t('%1$s replied to %2$s.'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); + } + $sitelink = t('Please visit %s to view and/or reply to your private messages.'); + + $tsitelink = sprintf($sitelink, $siteurl . '/display/' . gen_link_id($params['item']['mid'])); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = z_root() . '/display/' . gen_link_id($params['item']['mid']); + } + + if (in_array(intval($params['type']), [ NOTIFY_COMMENT, NOTIFY_RESHARE ])) { + // logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); + + $moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false); + + $itemlink = $params['link']; + + $action = t('commented on'); + + if (array_key_exists('item', $params) && in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) { + if (! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { + logger('notification: not a visible activity. Ignoring.'); + pop_lang(); + return; + } + + if (activity_match($params['verb'], ACTIVITY_LIKE)) { + $action = t('liked'); + } + + if (activity_match($params['verb'], ACTIVITY_DISLIKE)) { + $action = t('disliked'); + } + } + + $parent_mid = $params['parent_mid']; + + // Check to see if there was already a notify for this post. + // If so don't create a second notification + + $p = null; + $p = q( + "select id from notify where link = '%s' and uid = %d limit 1", + dbesc($params['link']), + intval($recip['channel_id']) + ); + if ($p) { + logger('notification: comment already notified'); + pop_lang(); + return; + } + + + // if it's a post figure out who's post it is. + + $p = null; + + if ($params['otype'] === 'item' && $parent_mid) { + $p = q( + "select * from item where mid = '%s' and uid = %d limit 1", + dbesc($parent_mid), + intval($recip['channel_id']) + ); + } + + xchan_query($p); + + $item_post_type = item_post_type($p[0]); + // $private = $p[0]['item_private']; + $parent_id = $p[0]['id']; + + $parent_item = $p[0]; + + //$possess_desc = str_replace('',$possess_desc); + + // "a post" + $dest_str = sprintf( + t('%1$s %2$s [zrl=%3$s]a %4$s[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $action, + $itemlink, + $item_post_type + ); + + // "George Bull's post" + if ($p) { + $dest_str = sprintf( + t('%1$s %2$s [zrl=%3$s]%4$s\'s %5$s[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $action, + $itemlink, + $p[0]['author']['xchan_name'], + $item_post_type + ); + } + + // "your post" + if ($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) { + $dest_str = sprintf( + t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $action, + $itemlink, + $item_post_type + ); + } + + // Some mail softwares relies on subject field for threading. + // So, we cannot have different subjects for notifications of the same thread. + // Before this we have the name of the replier on the subject rendering + // differents subjects for messages on the same thread. + + if ($moderated) { + $subject = sprintf(t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); + $itemlink = z_root() . '/moderate/' . gen_link_id($params['item']['mid']); + } else { + $subject = sprintf(t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); + } + $preamble = sprintf(t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']); + $epreamble = $dest_str; + + if ($moderated) { + $epreamble .= ' ' . t('(Moderated)'); + } + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + if ($moderated) { + $tsitelink .= "\n\n" . sprintf(t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate'); + $hsitelink .= "

" . sprintf(t('Please visit %s to approve or reject this comment.'), '' . z_root() . '/moderate'); + } + } + + if ($params['type'] == NOTIFY_LIKE) { + // logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); + + $itemlink = $params['link']; + + if (array_key_exists('item', $params) && (! activity_match($params['item']['verb'], ACTIVITY_LIKE))) { + if (! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { + logger('notification: not a visible activity. Ignoring.'); + pop_lang(); + return; + } + } + + $parent_mid = $params['parent_mid']; + + // Check to see if there was already a notify for this post. + // If so don't create a second notification + + $p = null; + $p = q( + "select id from notify where link = '%s' and uid = %d limit 1", + dbesc($params['link']), + intval($recip['channel_id']) + ); + if ($p) { + logger('notification: like already notified'); + pop_lang(); + return; + } + + + // if it's a post figure out who's post it is. + + $p = null; + + if ($params['otype'] === 'item' && $parent_mid) { + $p = q( + "select * from item where mid = '%s' and uid = %d limit 1", + dbesc($parent_mid), + intval($recip['channel_id']) + ); + } + + xchan_query($p); + + + $item_post_type = item_post_type($p[0]); + // $private = $p[0]['item_private']; + $parent_id = $p[0]['id']; + + $parent_item = $p[0]; + + + // "your post" + if ($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) { + $dest_str = sprintf( + t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $itemlink, + $item_post_type + ); + } else { + pop_lang(); + return; + } + + // Some mail softwares relies on subject field for threading. + // So, we cannot have different subjects for notifications of the same thread. + // Before this we have the name of the replier on the subject rendering + // differents subjects for messages on the same thread. + + $subject = sprintf(t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); + $preamble = sprintf(t('%1$s liked an item/conversation you created.'), $sender['xchan_name']); + $epreamble = $dest_str; + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + } + + + + if ($params['type'] == NOTIFY_WALL) { + $subject = sprintf(t('[$Projectname:Notify] %s posted to your profile wall'), $sender['xchan_name']); + + $moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false); + + $itemlink = (($moderated) ? z_root() . '/moderate/' . gen_link_id($params['item']['mid']) : $params['link']); + + $preamble = sprintf(t('%1$s posted to your profile wall at %2$s'), $sender['xchan_name'], $sitename); + + $epreamble = sprintf( + t('%1$s posted to [zrl=%2$s]your wall[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $itemlink + ); + + + if ($moderated) { + $subject .= t(' - ') . t('Moderated'); + $epreamble .= t(' - ') . t('Moderated'); + } + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + + if ($moderated) { + $tsitelink .= "\n\n" . sprintf(t('Please visit %s to approve or reject this post.'), z_root() . '/moderate'); + $hsitelink .= "

" . sprintf(t('Please visit %s to approve or reject this post.'), '' . z_root() . '/moderate'); + } + } + + if ($params['type'] == NOTIFY_TAGSELF) { + $p = null; + $p = q( + "select id from notify where link = '%s' and uid = %d limit 1", + dbesc($params['link']), + intval($recip['channel_id']) + ); + if ($p) { + logger('enotify: tag: already notified about this post'); + pop_lang(); + return; + } + + $subject = sprintf(t('[$Projectname:Notify] %s tagged you'), $sender['xchan_name']); + $preamble = sprintf(t('%1$s tagged you at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( + t('%1$s [zrl=%2$s]tagged you[/zrl].'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $params['link'] + ); + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + } + + if ($params['type'] == NOTIFY_POKE) { + $subject = sprintf(t('[$Projectname:Notify] %1$s poked you'), $sender['xchan_name']); + $preamble = sprintf(t('%1$s poked you at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( + t('%1$s [zrl=%2$s]poked you[/zrl].'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $params['link'] + ); + + $subject = str_replace('poked', t($params['activity']), $subject); + $preamble = str_replace('poked', t($params['activity']), $preamble); + $epreamble = str_replace('poked', t($params['activity']), $epreamble); + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + } + + if ($params['type'] == NOTIFY_TAGSHARE) { + $subject = sprintf(t('[$Projectname:Notify] %s tagged your post'), $sender['xchan_name']); + $preamble = sprintf(t('%1$s tagged your post at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( + t('%1$s tagged [zrl=%2$s]your post[/zrl]'), + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $itemlink + ); + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + } + + if ($params['type'] == NOTIFY_INTRO) { + $subject = sprintf(t('[$Projectname:Notify] Introduction received')); + $preamble = sprintf(t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( + t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'), + $siteurl . '/connections/ifpending', + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]' + ); + $body = sprintf(t('You may visit their profile at %s'), $sender['xchan_url']); + + $sitelink = t('Please visit %s to approve or reject the connection request.'); + $tsitelink = sprintf($sitelink, $siteurl . '/connections/ifpending'); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + } + + if ($params['type'] == NOTIFY_SUGGEST) { + $subject = sprintf(t('[$Projectname:Notify] Friend suggestion received')); + $preamble = sprintf(t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( + t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'), + $itemlink, + '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]', + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]' + ); + + $body = t('Name:') . ' ' . $params['item']['name'] . "\n"; + $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n"; + $body .= sprintf(t('You may visit their profile at %s'), $params['item']['url']); + + $sitelink = t('Please visit %s to approve or reject the suggestion.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + } + + if ($params['type'] == NOTIFY_CONFIRM) { + // ? + } + + if ($params['type'] == NOTIFY_SYSTEM) { + // ? + } + + $h = array( + 'params' => $params, + 'subject' => $subject, + 'preamble' => $preamble, + 'epreamble' => $epreamble, + 'body' => $body, + 'sitelink' => $sitelink, + 'sitename' => $sitename, + 'tsitelink' => $tsitelink, + 'hsitelink' => $hsitelink, + 'itemlink' => $itemlink, + 'sender' => $sender, + 'recipient' => $recip + ); + + call_hooks('enotify', $h); + + $subject = $h['subject']; + $preamble = $h['preamble']; + $epreamble = $h['epreamble']; + $body = $h['body']; + $sitelink = $h['sitelink']; + $tsitelink = $h['tsitelink']; + $hsitelink = $h['hsitelink']; + $itemlink = $h['itemlink']; + + + require_once('include/html2bbcode.php'); + + do { + $dups = false; + $hash = random_string(); + $r = q( + "SELECT id FROM notify WHERE hash = '%s' LIMIT 1", + dbesc($hash) + ); + if ($r) { + $dups = true; + } + } while ($dups === true); + + + $datarray = []; + $datarray['hash'] = $hash; + $datarray['sender_hash'] = $sender['xchan_hash']; + $datarray['xname'] = $sender['xchan_name']; + $datarray['url'] = $sender['xchan_url']; + $datarray['photo'] = $sender['xchan_photo_s']; + $datarray['created'] = datetime_convert(); + $datarray['aid'] = $recip['channel_account_id']; + $datarray['uid'] = $recip['channel_id']; + $datarray['link'] = $itemlink; + $datarray['parent'] = $parent_mid; + $datarray['parent_item'] = $parent_item; + $datarray['ntype'] = $params['type']; + $datarray['verb'] = $params['verb']; + $datarray['otype'] = $params['otype']; + $datarray['abort'] = false; + + $datarray['item'] = $params['item']; + + if (LibBlock::fetch_by_entity($datarray['uid'], $datarray['sender_hash'])) { + pop_lang(); + return; + } + + if (is_array($datarray['parent_item'])) { + if (LibBlock::fetch_by_entity($datarray['uid'], $datarray['parent_item']['author_xchan']) || LibBlock::fetch_by_entity($datarray['uid'], $datarray['parent_item']['owner_xchan'])) { + pop_lang(); + return; + } + } + + call_hooks('enotify_store', $datarray); + + if ($datarray['abort']) { + pop_lang(); + return; + } + + + // create notification entry in DB + $seen = 0; + + // Mark some notifications as seen right away + // Note! The notification have to be created, because they are used to send emails + // So easiest solution to hide them from Notices is to mark them as seen right away. + // Another option would be to not add them to the DB, and change how emails are handled + // (probably would be better that way) + + if (!$always_show_in_notices) { + if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_INTRO)) { + $seen = 1; + } + // set back to unseen for moderated wall posts + if ($params['type'] == NOTIFY_WALL && $params['item']['item_blocked'] == ITEM_MODERATED) { + $seen = 0; + } + } + + $e = q( + "select * from notify where otype = '%s' and xname = '%s' and verb = '%s' and link = '%s' and ntype = %d limit 1", + dbesc($datarray['otype']), + dbesc($datarray['xname']), + dbesc($datarray['verb']), + dbesc($datarray['link']), + intval($datarray['ntype']) + ); + if ($e) { + logger('duplicated notification'); + pop_lang(); + return; + } + + $r = q( + "insert into notify (hash,xname,url,photo,created,msg,aid,uid,link,parent,seen,ntype,verb,otype) values('%s','%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')", - dbesc($datarray['hash']), - dbesc($datarray['xname']), - dbesc($datarray['url']), - dbesc($datarray['photo']), - dbesc($datarray['created']), - dbesc(''), // will fill this in below after the record is created - intval($datarray['aid']), - intval($datarray['uid']), - dbesc($datarray['link']), - dbesc($datarray['parent']), - intval($seen), - intval($datarray['ntype']), - dbesc($datarray['verb']), - dbesc($datarray['otype']) - ); + dbesc($datarray['hash']), + dbesc($datarray['xname']), + dbesc($datarray['url']), + dbesc($datarray['photo']), + dbesc($datarray['created']), + dbesc(''), // will fill this in below after the record is created + intval($datarray['aid']), + intval($datarray['uid']), + dbesc($datarray['link']), + dbesc($datarray['parent']), + intval($seen), + intval($datarray['ntype']), + dbesc($datarray['verb']), + dbesc($datarray['otype']) + ); - $r = q("select id from notify where hash = '%s' and uid = %d limit 1", - dbesc($hash), - intval($recip['channel_id']) - ); - if ($r) { - $notify_id = $r[0]['id']; - } else { - logger('notification not found.'); - pop_lang(); - return; - } + $r = q( + "select id from notify where hash = '%s' and uid = %d limit 1", + dbesc($hash), + intval($recip['channel_id']) + ); + if ($r) { + $notify_id = $r[0]['id']; + } else { + logger('notification not found.'); + pop_lang(); + return; + } - $itemlink = z_root() . '/notify/view/' . $notify_id; - $msg = str_replace('$itemlink',$itemlink,$epreamble); + $itemlink = z_root() . '/notify/view/' . $notify_id; + $msg = str_replace('$itemlink', $itemlink, $epreamble); - // wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation + // wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation - if ((App::$language === 'en' || (! App::$language)) && strpos($msg,', ')) - $msg = substr($msg,strpos($msg,', ') + 1); + if ((App::$language === 'en' || (! App::$language)) && strpos($msg, ', ')) { + $msg = substr($msg, strpos($msg, ', ') + 1); + } - $r = q("update notify set msg = '%s' where id = %d and uid = %d", - dbesc($msg), - intval($notify_id), - intval($datarray['uid']) - ); + $r = q( + "update notify set msg = '%s' where id = %d and uid = %d", + dbesc($msg), + intval($notify_id), + intval($datarray['uid']) + ); - // send email notification if notification preferences permit + // send email notification if notification preferences permit - require_once('bbcode.php'); - if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) { + require_once('bbcode.php'); + if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) { + logger('notification: sending notification email'); - logger('notification: sending notification email'); + $hn = get_pconfig($recip['channel_id'], 'system', 'email_notify_host'); + if ($hn && (! stristr(App::get_hostname(), $hn))) { + // this isn't the email notification host + pop_lang(); + return; + } - $hn = get_pconfig($recip['channel_id'],'system','email_notify_host'); - if($hn && (! stristr(App::get_hostname(),$hn))) { - // this isn't the email notification host - pop_lang(); - return; - } + $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))), ENT_QUOTES, 'UTF-8')); - $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8')); - - $htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","
\n"),$body))); + $htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","
\n"), $body))); - // use $_SESSION['zid_override'] to force zid() to use - // the recipient address instead of the current observer + // use $_SESSION['zid_override'] to force zid() to use + // the recipient address instead of the current observer - $_SESSION['zid_override'] = channel_reddress($recip); - $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address']; - - $textversion = zidify_links($textversion); - $htmlversion = zidify_links($htmlversion); + $_SESSION['zid_override'] = channel_reddress($recip); + $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address']; - // unset when done to revert to normal behaviour + $textversion = zidify_links($textversion); + $htmlversion = zidify_links($htmlversion); - unset($_SESSION['zid_override']); - unset($_SESSION['zrl_override']); + // unset when done to revert to normal behaviour - $datarray = []; - $datarray['banner'] = $banner; - $datarray['product'] = $product; - $datarray['preamble'] = $preamble; - $datarray['sitename'] = $sitename; - $datarray['siteurl'] = $siteurl; - $datarray['type'] = $params['type']; - $datarray['parent'] = $params['parent_mid']; - $datarray['source_name'] = $sender['xchan_name']; - $datarray['source_link'] = $sender['xchan_url']; - $datarray['source_photo'] = $sender['xchan_photo_s']; - $datarray['uid'] = $recip['channel_id']; - $datarray['username'] = $recip['channel_name']; - $datarray['hsitelink'] = $hsitelink; - $datarray['tsitelink'] = $tsitelink; - $datarray['hitemlink'] = '' . $itemlink . ''; - $datarray['titemlink'] = $itemlink; - $datarray['thanks'] = $thanks; - $datarray['site_admin'] = $site_admin; - $datarray['opt_out1'] = $opt_out1; - $datarray['opt_out2'] = $opt_out2; - $datarray['hopt_out2'] = $hopt_out2; - $datarray['title'] = stripslashes($title); - $datarray['htmlversion'] = $htmlversion; - $datarray['textversion'] = $textversion; - $datarray['subject'] = $subject; - $datarray['headers'] = $additional_mail_header; - $datarray['email_secure'] = false; + unset($_SESSION['zid_override']); + unset($_SESSION['zrl_override']); - call_hooks('enotify_mail', $datarray); + $datarray = []; + $datarray['banner'] = $banner; + $datarray['product'] = $product; + $datarray['preamble'] = $preamble; + $datarray['sitename'] = $sitename; + $datarray['siteurl'] = $siteurl; + $datarray['type'] = $params['type']; + $datarray['parent'] = $params['parent_mid']; + $datarray['source_name'] = $sender['xchan_name']; + $datarray['source_link'] = $sender['xchan_url']; + $datarray['source_photo'] = $sender['xchan_photo_s']; + $datarray['uid'] = $recip['channel_id']; + $datarray['username'] = $recip['channel_name']; + $datarray['hsitelink'] = $hsitelink; + $datarray['tsitelink'] = $tsitelink; + $datarray['hitemlink'] = '' . $itemlink . ''; + $datarray['titemlink'] = $itemlink; + $datarray['thanks'] = $thanks; + $datarray['site_admin'] = $site_admin; + $datarray['opt_out1'] = $opt_out1; + $datarray['opt_out2'] = $opt_out2; + $datarray['hopt_out2'] = $hopt_out2; + $datarray['title'] = stripslashes($title); + $datarray['htmlversion'] = $htmlversion; + $datarray['textversion'] = $textversion; + $datarray['subject'] = $subject; + $datarray['headers'] = $additional_mail_header; + $datarray['email_secure'] = false; - // Default to private - don't disclose message contents over insecure channels (such as email) - // Might be interesting to use GPG,PGP,S/MIME encryption instead - // but we'll save that for a clever plugin developer to implement + call_hooks('enotify_mail', $datarray); - $private_activity = false; + // Default to private - don't disclose message contents over insecure channels (such as email) + // Might be interesting to use GPG,PGP,S/MIME encryption instead + // but we'll save that for a clever plugin developer to implement - if (! $datarray['email_secure']) { - switch ($params['type']) { - case NOTIFY_WALL: - case NOTIFY_TAGSELF: - case NOTIFY_POKE: - case NOTIFY_RESHARE: - case NOTIFY_COMMENT: - if (! $private) - break; - $private_activity = true; - case NOTIFY_MAIL: - $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = ''; - $datarray['subject'] = preg_replace('/' . preg_quote(t('[$Projectname:Notify]'), '/') . '/','$0*',$datarray['subject']); - break; - default: - break; - } - } + $private_activity = false; - if ($private_activity - && intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) { + if (! $datarray['email_secure']) { + switch ($params['type']) { + case NOTIFY_WALL: + case NOTIFY_TAGSELF: + case NOTIFY_POKE: + case NOTIFY_RESHARE: + case NOTIFY_COMMENT: + if (! $private) { + break; + } + $private_activity = true; + case NOTIFY_MAIL: + $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = ''; + $datarray['subject'] = preg_replace('/' . preg_quote(t('[$Projectname:Notify]'), '/') . '/', '$0*', $datarray['subject']); + break; + default: + break; + } + } - pop_lang(); - return; - } + if ( + $private_activity + && intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications')) + ) { + pop_lang(); + return; + } - // load the template for private message notifications - $tpl = get_markup_template('email_notify_html.tpl'); - $email_html_body = replace_macros($tpl,array( - '$banner' => $datarray['banner'], - '$notify_icon' => System::get_site_icon(), - '$product' => $datarray['product'], - '$preamble' => $salutation . '

' . $datarray['preamble'], - '$sitename' => $datarray['sitename'], - '$siteurl' => $datarray['siteurl'], - '$source_name' => $datarray['source_name'], - '$source_link' => $datarray['source_link'], - '$source_photo' => $datarray['source_photo'], - '$username' => $datarray['to_name'], - '$hsitelink' => $datarray['hsitelink'], - '$hitemlink' => $datarray['hitemlink'], - '$thanks' => $datarray['thanks'], - '$site_admin' => $datarray['site_admin'], - '$opt_out1' => $datarray['opt_out1'], - '$opt_out2' => $datarray['hopt_out2'], - '$title' => $datarray['title'], - '$htmlversion' => $datarray['htmlversion'], - )); + // load the template for private message notifications + $tpl = get_markup_template('email_notify_html.tpl'); + $email_html_body = replace_macros($tpl, array( + '$banner' => $datarray['banner'], + '$notify_icon' => System::get_site_icon(), + '$product' => $datarray['product'], + '$preamble' => $salutation . '

' . $datarray['preamble'], + '$sitename' => $datarray['sitename'], + '$siteurl' => $datarray['siteurl'], + '$source_name' => $datarray['source_name'], + '$source_link' => $datarray['source_link'], + '$source_photo' => $datarray['source_photo'], + '$username' => $datarray['to_name'], + '$hsitelink' => $datarray['hsitelink'], + '$hitemlink' => $datarray['hitemlink'], + '$thanks' => $datarray['thanks'], + '$site_admin' => $datarray['site_admin'], + '$opt_out1' => $datarray['opt_out1'], + '$opt_out2' => $datarray['hopt_out2'], + '$title' => $datarray['title'], + '$htmlversion' => $datarray['htmlversion'], + )); - // load the template for private message notifications - $tpl = get_markup_template('email_notify_text.tpl'); - $email_text_body = replace_macros($tpl, array( - '$banner' => $datarray['banner'], - '$product' => $datarray['product'], - '$preamble' => $salutation . "\n\n" . $datarray['preamble'], - '$sitename' => $datarray['sitename'], - '$siteurl' => $datarray['siteurl'], - '$source_name' => $datarray['source_name'], - '$source_link' => $datarray['source_link'], - '$source_photo' => $datarray['source_photo'], - '$username' => $datarray['to_name'], - '$tsitelink' => $datarray['tsitelink'], - '$titemlink' => $datarray['titemlink'], - '$thanks' => $datarray['thanks'], - '$site_admin' => $datarray['site_admin'], - '$opt_out1' => $datarray['opt_out1'], - '$opt_out2' => $datarray['opt_out2'], - '$title' => $datarray['title'], - '$textversion' => $datarray['textversion'], - )); + // load the template for private message notifications + $tpl = get_markup_template('email_notify_text.tpl'); + $email_text_body = replace_macros($tpl, array( + '$banner' => $datarray['banner'], + '$product' => $datarray['product'], + '$preamble' => $salutation . "\n\n" . $datarray['preamble'], + '$sitename' => $datarray['sitename'], + '$siteurl' => $datarray['siteurl'], + '$source_name' => $datarray['source_name'], + '$source_link' => $datarray['source_link'], + '$source_photo' => $datarray['source_photo'], + '$username' => $datarray['to_name'], + '$tsitelink' => $datarray['tsitelink'], + '$titemlink' => $datarray['titemlink'], + '$thanks' => $datarray['thanks'], + '$site_admin' => $datarray['site_admin'], + '$opt_out1' => $datarray['opt_out1'], + '$opt_out2' => $datarray['opt_out2'], + '$title' => $datarray['title'], + '$textversion' => $datarray['textversion'], + )); -// logger('text: ' . $email_text_body); + // logger('text: ' . $email_text_body); - // use the EmailNotification library to send the message + // use the EmailNotification library to send the message - $to_email = $recip['account_email']; + $to_email = $recip['account_email']; - $e = get_pconfig($recip['channel_id'],'system','notification_email', false); - if ($e) { - $to_email = $e; - } + $e = get_pconfig($recip['channel_id'], 'system', 'notification_email', false); + if ($e) { + $to_email = $e; + } - $addrs = explode(',', $to_email); + $addrs = explode(',', $to_email); - foreach($addrs as $addr) { + foreach ($addrs as $addr) { + self::send(array( + 'fromName' => $sender_name, + 'fromEmail' => $sender_email, + 'replyTo' => $reply_email, + 'toEmail' => $addr, + 'messageSubject' => $datarray['subject'], + 'htmlVersion' => $email_html_body, + 'textVersion' => $email_text_body, + 'additionalMailHeader' => $datarray['headers'], + )); + } + } - self::send(array( - 'fromName' => $sender_name, - 'fromEmail' => $sender_email, - 'replyTo' => $reply_email, - 'toEmail' => $addr, - 'messageSubject' => $datarray['subject'], - 'htmlVersion' => $email_html_body, - 'textVersion' => $email_text_body, - 'additionalMailHeader' => $datarray['headers'], - )); - } - } + pop_lang(); + } - pop_lang(); - -} - - - /** - * @brief Send a multipart/alternative message with Text and HTML versions. - * - * @param array $params an assoziative array with: - * * \e string \b fromName name of the sender - * * \e string \b fromEmail email of the sender - * * \e string \b replyTo replyTo address to direct responses - * * \e string \b toEmail destination email address - * * \e string \b messageSubject subject of the message - * * \e string \b htmlVersion html version of the message - * * \e string \b textVersion text only version of the message - * * \e string \b additionalMailHeader additions to the smtp mail header - */ - public static function send($params) { - - $params['sent'] = false; - $params['result'] = false; - - call_hooks('email_send', $params); - - if($params['sent']) { - logger("notification: enotify::send (addon) returns " . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG); - return $params['result']; - } - - $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8'); - $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8'); - - // generate a mime boundary - $mimeBoundary = rand(0, 9) . "-" - .rand(100000000, 999999999) . "-" - .rand(100000000, 999999999) . "=:" - .rand(10000, 99999); - - // generate a multipart/alternative message header - $messageHeader = - $params['additionalMailHeader'] . - "From: $fromName <{$params['fromEmail']}>" . PHP_EOL . - "Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL . - "MIME-Version: 1.0" . PHP_EOL . - "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\""; - - // assemble the final multipart message body with the text and html types included - $textBody = chunk_split(base64_encode($params['textVersion'])); - $htmlBody = chunk_split(base64_encode($params['htmlVersion'])); - - $multipartMessageBody = - "--" . $mimeBoundary . PHP_EOL . // plain text section - "Content-Type: text/plain; charset=UTF-8" . PHP_EOL . - "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL . - $textBody . PHP_EOL . - "--" . $mimeBoundary . PHP_EOL . // text/html section - "Content-Type: text/html; charset=UTF-8" . PHP_EOL . - "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL . - $htmlBody . PHP_EOL . - "--" . $mimeBoundary . "--" . PHP_EOL; // message ending - - // send the message - $res = mail( - $params['toEmail'], // send to address - $messageSubject, // subject - $multipartMessageBody, // message body - $messageHeader // message headers - ); - logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG); - return $res; - } - - public static function format($item) { - - $ret = ''; - - $expire = intval(get_config('system','default_expire_days')); - $expire_date = (($expire) ? datetime_convert('UTC','UTC','now - ' . $expire . ' days') : NULL_DATE); - - require_once('include/conversation.php'); - - // Call localize_item to get a one line status for activities. - // This should set $item['localize'] to indicate we have a brief summary. - // and perhaps $item['shortlocalize'] for an even briefer summary - - localize_item($item); - - if($item['shortlocalize']) { - $itemem_text = $item['shortlocalize']; - } - elseif($item['localize']) { - $itemem_text = $item['localize']; - } - else { - $itemem_text = (($item['item_thread_top']) - ? t('created a new post') - : sprintf( t('reacted to %s\'s conversation'), $item['owner']['xchan_name'])); - if($item['verb'] === 'Announce') { - $itemem_text = sprintf( t('shared %s\'s post'), $item['owner']['xchan_name']); - } - } - if ($item['item_private'] == 2) { - $itemem_text = t('sent a direct message'); - } - - $edit = false; - - if($item['edited'] > $item['created']) { - if($item['item_thread_top']) { - $itemem_text = sprintf( t('edited a post dated %s'), relative_date($item['created'])); - $edit = true; - } - else { - $itemem_text = sprintf( t('edited a comment dated %s'), relative_date($item['created'])); - $edit = true; - } - } - - if (LibBlock::fetch_by_entity(local_channel(),$item['author']['xchan_hash'])) { - return []; - } - - // convert this logic into a json array just like the system notifications - - $x = array( - 'notify_link' => $item['llink'], - 'name' => $item['author']['xchan_name'], - 'addr' => $item['author']['xchan_addr'], - 'url' => $item['author']['xchan_url'], - 'photo' => $item['author']['xchan_photo_s'], - 'when' => relative_date(($edit)? $item['edited'] : $item['created']), - 'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'), - 'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])), - 'notify_id' => 'undefined', - 'thread_top' => (($item['item_thread_top']) ? true : false), - 'message' => strip_tags(bbcode($itemem_text)), - // these are for the superblock addon - 'hash' => $item['author']['xchan_hash'], - 'uid' => local_channel(), - 'display' => true - ); - - $post_date = (($edit)? $item['edited'] : $item['created']); - if($post_date && $post_date < $expire_date) { - return []; - } - - call_hooks('enotify_format',$x); - if(! $x['display']) { - return []; - } - - return $x; - } + /** + * @brief Send a multipart/alternative message with Text and HTML versions. + * + * @param array $params an assoziative array with: + * * \e string \b fromName name of the sender + * * \e string \b fromEmail email of the sender + * * \e string \b replyTo replyTo address to direct responses + * * \e string \b toEmail destination email address + * * \e string \b messageSubject subject of the message + * * \e string \b htmlVersion html version of the message + * * \e string \b textVersion text only version of the message + * * \e string \b additionalMailHeader additions to the smtp mail header + */ + public static function send($params) + { + + $params['sent'] = false; + $params['result'] = false; + + call_hooks('email_send', $params); + + if ($params['sent']) { + logger("notification: enotify::send (addon) returns " . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG); + return $params['result']; + } + + $fromName = email_header_encode(html_entity_decode($params['fromName'], ENT_QUOTES, 'UTF-8'), 'UTF-8'); + $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'], ENT_QUOTES, 'UTF-8'), 'UTF-8'); + + // generate a mime boundary + $mimeBoundary = rand(0, 9) . "-" + . rand(100000000, 999999999) . "-" + . rand(100000000, 999999999) . "=:" + . rand(10000, 99999); + + // generate a multipart/alternative message header + $messageHeader = + $params['additionalMailHeader'] . + "From: $fromName <{$params['fromEmail']}>" . PHP_EOL . + "Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL . + "MIME-Version: 1.0" . PHP_EOL . + "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\""; + + // assemble the final multipart message body with the text and html types included + $textBody = chunk_split(base64_encode($params['textVersion'])); + $htmlBody = chunk_split(base64_encode($params['htmlVersion'])); + + $multipartMessageBody = + "--" . $mimeBoundary . PHP_EOL . // plain text section + "Content-Type: text/plain; charset=UTF-8" . PHP_EOL . + "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL . + $textBody . PHP_EOL . + "--" . $mimeBoundary . PHP_EOL . // text/html section + "Content-Type: text/html; charset=UTF-8" . PHP_EOL . + "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL . + $htmlBody . PHP_EOL . + "--" . $mimeBoundary . "--" . PHP_EOL; // message ending + + // send the message + $res = mail( + $params['toEmail'], // send to address + $messageSubject, // subject + $multipartMessageBody, // message body + $messageHeader // message headers + ); + logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG); + return $res; + } + + public static function format($item) + { + + $ret = ''; + + $expire = intval(get_config('system', 'default_expire_days')); + $expire_date = (($expire) ? datetime_convert('UTC', 'UTC', 'now - ' . $expire . ' days') : NULL_DATE); + + require_once('include/conversation.php'); + + // Call localize_item to get a one line status for activities. + // This should set $item['localize'] to indicate we have a brief summary. + // and perhaps $item['shortlocalize'] for an even briefer summary + + localize_item($item); + + if ($item['shortlocalize']) { + $itemem_text = $item['shortlocalize']; + } elseif ($item['localize']) { + $itemem_text = $item['localize']; + } else { + $itemem_text = (($item['item_thread_top']) + ? t('created a new post') + : sprintf(t('reacted to %s\'s conversation'), $item['owner']['xchan_name'])); + if ($item['verb'] === 'Announce') { + $itemem_text = sprintf(t('shared %s\'s post'), $item['owner']['xchan_name']); + } + } + if ($item['item_private'] == 2) { + $itemem_text = t('sent a direct message'); + } + + $edit = false; + + if ($item['edited'] > $item['created']) { + if ($item['item_thread_top']) { + $itemem_text = sprintf(t('edited a post dated %s'), relative_date($item['created'])); + $edit = true; + } else { + $itemem_text = sprintf(t('edited a comment dated %s'), relative_date($item['created'])); + $edit = true; + } + } + + if (LibBlock::fetch_by_entity(local_channel(), $item['author']['xchan_hash'])) { + return []; + } + + // convert this logic into a json array just like the system notifications + + $x = array( + 'notify_link' => $item['llink'], + 'name' => $item['author']['xchan_name'], + 'addr' => $item['author']['xchan_addr'], + 'url' => $item['author']['xchan_url'], + 'photo' => $item['author']['xchan_photo_s'], + 'when' => relative_date(($edit) ? $item['edited'] : $item['created']), + 'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'), + 'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])), + 'notify_id' => 'undefined', + 'thread_top' => (($item['item_thread_top']) ? true : false), + 'message' => strip_tags(bbcode($itemem_text)), + // these are for the superblock addon + 'hash' => $item['author']['xchan_hash'], + 'uid' => local_channel(), + 'display' => true + ); + + $post_date = (($edit) ? $item['edited'] : $item['created']); + if ($post_date && $post_date < $expire_date) { + return []; + } + + call_hooks('enotify_format', $x); + if (! $x['display']) { + return []; + } + + return $x; + } } diff --git a/Zotlabs/Lib/ExtendedZip.php b/Zotlabs/Lib/ExtendedZip.php index 5bc6db6c8..3b1bea668 100644 --- a/Zotlabs/Lib/ExtendedZip.php +++ b/Zotlabs/Lib/ExtendedZip.php @@ -15,45 +15,49 @@ use ZipArchive; * * @author andrew */ -class ExtendedZip extends ZipArchive { - - // Member function to add a whole file system subtree to the archive - public function addTree($dirname, $localname = '') { - if ($localname) - $this->addEmptyDir($localname); - $this->_addTree($dirname, $localname); - } +class ExtendedZip extends ZipArchive +{ - // Internal function, to recurse - protected function _addTree($dirname, $localname) { - $dir = opendir($dirname); - while ($filename = readdir($dir)) { - // Discard . and .. - if ($filename == '.' || $filename == '..') - continue; + // Member function to add a whole file system subtree to the archive + public function addTree($dirname, $localname = '') + { + if ($localname) { + $this->addEmptyDir($localname); + } + $this->_addTree($dirname, $localname); + } - // Proceed according to type - $path = $dirname . '/' . $filename; - $localpath = $localname ? ($localname . '/' . $filename) : $filename; - if (is_dir($path)) { - // Directory: add & recurse - $this->addEmptyDir($localpath); - $this->_addTree($path, $localpath); - } - else if (is_file($path)) { - // File: just add - $this->addFile($path, $localpath); - } - } - closedir($dir); - } + // Internal function, to recurse + protected function _addTree($dirname, $localname) + { + $dir = opendir($dirname); + while ($filename = readdir($dir)) { + // Discard . and .. + if ($filename == '.' || $filename == '..') { + continue; + } - // Helper function - public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') { - $zip = new self(); - $zip->open($zipFilename, $flags); - $zip->addTree($dirname, $localname); - $zip->close(); - } - + // Proceed according to type + $path = $dirname . '/' . $filename; + $localpath = $localname ? ($localname . '/' . $filename) : $filename; + if (is_dir($path)) { + // Directory: add & recurse + $this->addEmptyDir($localpath); + $this->_addTree($path, $localpath); + } elseif (is_file($path)) { + // File: just add + $this->addFile($path, $localpath); + } + } + closedir($dir); + } + + // Helper function + public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') + { + $zip = new self(); + $zip->open($zipFilename, $flags); + $zip->addTree($dirname, $localname); + $zip->close(); + } } diff --git a/Zotlabs/Lib/Hashpath.php b/Zotlabs/Lib/Hashpath.php index 1e8c9502f..1f8745b64 100644 --- a/Zotlabs/Lib/Hashpath.php +++ b/Zotlabs/Lib/Hashpath.php @@ -1,6 +1,6 @@ $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing); - if ((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) { - $item['iconfig'] = []; - } + if (is_null($idx)) { + $item['iconfig'][] = $entry; + } else { + $item['iconfig'][$idx] = $entry; + } + return $value; + } - if (array_key_exists('item_id',$item)) { - $iid = $item['item_id']; - } - else { - $iid = ((isset($item['id'])) ? $item['id'] : 0); - } - - if (array_key_exists('iconfig',$item) && is_array($item['iconfig'])) { - foreach ($item['iconfig'] as $c) { - if ($c['cat'] == $family && $c['k'] == $key) { - return $c['v']; - } - } - } - } - elseif (intval($item)) { - $iid = $item; - } + if (intval($item)) { + $iid = intval($item); + } - if (! $iid) { - return $default; - } + if (! $iid) { + return false; + } - $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1", - intval($iid), - dbesc($family), - dbesc($key) - ); - if ($r) { - $r[0]['v'] = unserialise($r[0]['v']); - if ($is_item) { - $item['iconfig'][] = $r[0]; - } - return $r[0]['v']; - } - return $default; - } + if (self::Get($item, $family, $key) === false) { + $r = q( + "insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ", + intval($iid), + dbesc($family), + dbesc($key), + dbesc($dbvalue), + intval($sharing) + ); + } else { + $r = q( + "update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ", + dbesc($dbvalue), + intval($sharing), + intval($iid), + dbesc($family), + dbesc($key) + ); + } - /** - * IConfig::Set(&$item, $family, $key, $value, $sharing = false); - * - * $item - item array or item id. If passed an array the iconfig meta information is - * added to the item structure (which will need to be saved with item_store eventually). - * If passed an id, the DB is updated, but may not be federated and/or cloned. - * $family - namespace of meta variable - * $key - key of meta variable - * $value - value of meta variable - * $sharing - boolean (default false); if true the meta information is propagated with the item - * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered. - * If the meta information is added after delivery and you wish it to be shared, it may be necessary to - * alter the item edited timestamp and invoke the delivery process on the updated item. The edited - * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end. - */ - + if (! $r) { + return false; + } - public static function Set(&$item, $family, $key, $value, $sharing = false) { - - $dbvalue = ((is_array($value)) ? serialise($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - - $is_item = false; - $idx = null; - - if(is_array($item)) { - $is_item = true; - if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) - $item['iconfig'] = []; - elseif($item['iconfig']) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - $idx = $x; - } - } - } - $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing); - - if(is_null($idx)) - $item['iconfig'][] = $entry; - else - $item['iconfig'][$idx] = $entry; - return $value; - } - - if(intval($item)) - $iid = intval($item); - - if(! $iid) - return false; - - if(self::Get($item, $family, $key) === false) { - $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ", - intval($iid), - dbesc($family), - dbesc($key), - dbesc($dbvalue), - intval($sharing) - ); - } - else { - $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ", - dbesc($dbvalue), - intval($sharing), - intval($iid), - dbesc($family), - dbesc($key) - ); - } - - if(! $r) - return false; - - return $value; - } + return $value; + } - public static function Delete(&$item, $family, $key) { + public static function Delete(&$item, $family, $key) + { - $is_item = false; - $idx = null; + $is_item = false; + $idx = null; - if(is_array($item)) { - $is_item = true; - if(is_array($item['iconfig'])) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - unset($item['iconfig'][$x]); - } - } - // re-order the array index - $item['iconfig'] = array_values($item['iconfig']); - } - return true; - } + if (is_array($item)) { + $is_item = true; + if (is_array($item['iconfig'])) { + for ($x = 0; $x < count($item['iconfig']); $x++) { + if ($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { + unset($item['iconfig'][$x]); + } + } + // re-order the array index + $item['iconfig'] = array_values($item['iconfig']); + } + return true; + } - if(intval($item)) - $iid = intval($item); + if (intval($item)) { + $iid = intval($item); + } - if(! $iid) - return false; + if (! $iid) { + return false; + } - return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ", - intval($iid), - dbesc($family), - dbesc($key) - ); - - } - -} \ No newline at end of file + return q( + "delete from iconfig where iid = %d and cat = '%s' and k = '%s' ", + intval($iid), + dbesc($family), + dbesc($key) + ); + } +} diff --git a/Zotlabs/Lib/Img_cache.php b/Zotlabs/Lib/Img_cache.php index fe58c6eab..1682d07b2 100644 --- a/Zotlabs/Lib/Img_cache.php +++ b/Zotlabs/Lib/Img_cache.php @@ -1,4 +1,5 @@ base64url_encode($key_id, true) ] ]); - } public static function verify($x) @@ -64,13 +63,10 @@ class JSalmon } return $ret; - } public static function unpack($data) { return json_decode(base64url_decode($data), true); } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Keyutils.php b/Zotlabs/Lib/Keyutils.php index 616ecfcf6..67c6f85fc 100644 --- a/Zotlabs/Lib/Keyutils.php +++ b/Zotlabs/Lib/Keyutils.php @@ -9,91 +9,94 @@ use phpseclib\Math\BigInteger; * Keyutils * Convert RSA keys between various formats */ -class Keyutils { +class Keyutils +{ - /** - * @param string $m modulo - * @param string $e exponent - * @return string - */ - public static function meToPem($m, $e) { + /** + * @param string $m modulo + * @param string $e exponent + * @return string + */ + public static function meToPem($m, $e) + { - $rsa = new RSA(); - $rsa->loadKey([ - 'e' => new BigInteger($e, 256), - 'n' => new BigInteger($m, 256) - ]); - return $rsa->getPublicKey(); + $rsa = new RSA(); + $rsa->loadKey([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + return $rsa->getPublicKey(); + } - } + /** + * @param string key + * @return string + */ + public static function rsaToPem($key) + { - /** - * @param string key - * @return string - */ - public static function rsaToPem($key) { + $rsa = new RSA(); + $rsa->setPublicKey($key); - $rsa = new RSA(); - $rsa->setPublicKey($key); + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); + } - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); + /** + * @param string key + * @return string + */ + public static function pemToRsa($key) + { - } + $rsa = new RSA(); + $rsa->setPublicKey($key); - /** - * @param string key - * @return string - */ - public static function pemToRsa($key) { + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + } - $rsa = new RSA(); - $rsa->setPublicKey($key); + /** + * @param string $key key + * @param string $m reference modulo + * @param string $e reference exponent + */ + public static function pemToMe($key, &$m, &$e) + { - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + $rsa = new RSA(); + $rsa->loadKey($key); + $rsa->setPublicKey(); - } + $m = $rsa->modulus->toBytes(); + $e = $rsa->exponent->toBytes(); + } - /** - * @param string $key key - * @param string $m reference modulo - * @param string $e reference exponent - */ - public static function pemToMe($key, &$m, &$e) { + /** + * @param string $pubkey + * @return string + */ + public static function salmonKey($pubkey) + { + self::pemToMe($pubkey, $m, $e); + return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true); + } - $rsa = new RSA(); - $rsa->loadKey($key); - $rsa->setPublicKey(); + /** + * @param string $key + * @return string + */ + public static function convertSalmonKey($key) + { + if (strstr($key, ',')) { + $rawkey = substr($key, strpos($key, ',') + 1); + } else { + $rawkey = substr($key, 5); + } - $m = $rsa->modulus->toBytes(); - $e = $rsa->exponent->toBytes(); + $key_info = explode('.', $rawkey); - } + $m = base64url_decode($key_info[1]); + $e = base64url_decode($key_info[2]); - /** - * @param string $pubkey - * @return string - */ - public static function salmonKey($pubkey) { - self::pemToMe($pubkey, $m, $e); - return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true); - } - - /** - * @param string $key - * @return string - */ - public static function convertSalmonKey($key) { - if (strstr($key, ',')) - $rawkey = substr($key, strpos($key, ',') + 1); - else - $rawkey = substr($key, 5); - - $key_info = explode('.', $rawkey); - - $m = base64url_decode($key_info[1]); - $e = base64url_decode($key_info[2]); - - return self::meToPem($m, $e); - } - -} \ No newline at end of file + return self::meToPem($m, $e); + } +} diff --git a/Zotlabs/Lib/LDSignatures.php b/Zotlabs/Lib/LDSignatures.php index 737b2b199..ae88db9cd 100644 --- a/Zotlabs/Lib/LDSignatures.php +++ b/Zotlabs/Lib/LDSignatures.php @@ -26,7 +26,7 @@ class LDSignatures public static function dopplesign(&$data, $channel) { // remove for the time being - performance issues - // $data['magicEnv'] = self::salmon_sign($data,$channel); + // $data['magicEnv'] = self::salmon_sign($data,$channel); return self::sign($data, $channel); } @@ -89,8 +89,9 @@ class LDSignatures $data = json_decode($data); } - if (!is_object($data)) + if (!is_object($data)) { return ''; + } jsonld_set_document_loader('jsonld_document_loader'); @@ -133,8 +134,5 @@ class LDSignatures 'meCreator' => channel_url($channel), 'meSignatureValue' => $signature ]); - } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/LibBlock.php b/Zotlabs/Lib/LibBlock.php index 25948ddb8..0e79ea627 100644 --- a/Zotlabs/Lib/LibBlock.php +++ b/Zotlabs/Lib/LibBlock.php @@ -2,12 +2,11 @@ namespace Zotlabs\Lib; - class LibBlock { - static public $cache = []; - static public $empty = []; + public static $cache = []; + public static $empty = []; // This limits the number of DB queries for fetch_by_entity to once per page load. @@ -46,7 +45,8 @@ class LibBlock $arr['block_comment'] = ((array_key_exists('block_comment', $arr)) ? escape_tags(trim($arr['block_comment'])) : EMPTY_STR); if (!intval($arr['block_id'])) { - $r = q("select * from block where block_channel_id = %d and block_entity = '%s' and block_type = %d limit 1", + $r = q( + "select * from block where block_channel_id = %d and block_entity = '%s' and block_type = %d limit 1", intval($arr['block_channel_id']), dbesc($arr['block_entity']), intval($arr['block_type']) @@ -57,7 +57,8 @@ class LibBlock } if (intval($arr['block_id'])) { - return q("UPDATE block set block_channel_id = %d, block_entity = '%s', block_type = %d, block_comment = '%s' where block_id = %d", + return q( + "UPDATE block set block_channel_id = %d, block_entity = '%s', block_type = %d, block_comment = '%s' where block_id = %d", intval($arr['block_channel_id']), dbesc($arr['block_entity']), intval($arr['block_type']), @@ -71,7 +72,8 @@ class LibBlock public static function remove($channel_id, $entity) { - return q("delete from block where block_channel_id = %d and block_entity = '%s'", + return q( + "delete from block where block_channel_id = %d and block_entity = '%s'", intval($channel_id), dbesc($entity) ); @@ -82,7 +84,8 @@ class LibBlock if (!intval($channel_id)) { return false; } - $r = q("select * from block where block_channel_id = %d and block_id = %d ", + $r = q( + "select * from block where block_channel_id = %d and block_id = %d ", intval($channel_id) ); return (($r) ? array_shift($r) : $r); @@ -96,7 +99,6 @@ class LibBlock } return self::fetch_from_cache($channel_id, $entity); - } public static function fetch($channel_id, $type = false) @@ -107,10 +109,10 @@ class LibBlock $sql_extra = (($type === false) ? EMPTY_STR : " and block_type = " . intval($type)); - $r = q("select * from block where block_channel_id = %d $sql_extra", + $r = q( + "select * from block where block_channel_id = %d $sql_extra", intval($channel_id) ); return $r; } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Libprofile.php b/Zotlabs/Lib/Libprofile.php index 27611f13c..2ce56d17d 100644 --- a/Zotlabs/Lib/Libprofile.php +++ b/Zotlabs/Lib/Libprofile.php @@ -27,7 +27,7 @@ class Libprofile public static function load($nickname, $profile = '') { - // logger('Libprofile::load: ' . $nickname . (($profile) ? ' profile: ' . $profile : '')); + // logger('Libprofile::load: ' . $nickname . (($profile) ? ' profile: ' . $profile : '')); $channel = channelx_by_nick($nickname); @@ -50,25 +50,29 @@ class Libprofile } if (!$profile) { - $r = q("SELECT abook_profile FROM abook WHERE abook_xchan = '%s' and abook_channel = '%d' limit 1", + $r = q( + "SELECT abook_profile FROM abook WHERE abook_xchan = '%s' and abook_channel = '%d' limit 1", dbesc(($observer) ? $observer['xchan_hash'] : ''), intval($channel['channel_id']) ); - if ($r) + if ($r) { $profile = $r[0]['abook_profile']; + } } $p = null; if ($profile) { - $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + $p = q( + "SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile LEFT JOIN channel ON profile.uid = channel.channel_id WHERE channel.channel_address = '%s' AND profile.profile_guid = '%s' LIMIT 1", dbesc($nickname), dbesc($profile) ); if (!$p) { - $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + $p = q( + "SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile LEFT JOIN channel ON profile.uid = channel.channel_id WHERE channel.channel_address = '%s' AND profile.id = %d LIMIT 1", dbesc($nickname), @@ -78,7 +82,8 @@ class Libprofile } if (!$p) { - $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + $p = q( + "SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile LEFT JOIN channel ON profile.uid = channel.channel_id WHERE channel.channel_address = '%s' and channel_removed = 0 AND profile.is_default = 1 LIMIT 1", @@ -93,22 +98,23 @@ class Libprofile return; } - $q = q("select * from profext where hash = '%s' and channel_id = %d", + $q = q( + "select * from profext where hash = '%s' and channel_id = %d", dbesc($p[0]['profile_guid']), intval($p[0]['profile_uid']) ); if ($q) { - $extra_fields = []; $profile_fields_basic = get_profile_fields_basic(); $profile_fields_advanced = get_profile_fields_advanced(); $advanced = ((feature_enabled(local_channel(), 'advanced_profiles')) ? true : false); - if ($advanced) + if ($advanced) { $fields = $profile_fields_advanced; - else + } else { $fields = $profile_fields_basic; + } foreach ($q as $qq) { foreach ($fields as $k => $f) { @@ -123,7 +129,8 @@ class Libprofile $p[0]['extra_fields'] = ((isset($extra_fields)) ? $extra_fields : []); - $z = q("select xchan_photo_date, xchan_addr from xchan where xchan_hash = '%s' limit 1", + $z = q( + "select xchan_photo_date, xchan_addr from xchan where xchan_hash = '%s' limit 1", dbesc($p[0]['channel_hash']) ); if ($z) { @@ -134,11 +141,13 @@ class Libprofile // fetch user tags if this isn't the default profile if (!$p[0]['is_default']) { - $x = q("select keywords from profile where uid = %d and is_default = 1 limit 1", + $x = q( + "select keywords from profile where uid = %d and is_default = 1 limit 1", intval($p[0]['profile_uid']) ); - if ($x && $can_view_profile) + if ($x && $can_view_profile) { $p[0]['keywords'] = $x[0]['keywords']; + } } if ($p[0]['keywords']) { @@ -171,8 +180,7 @@ class Libprofile * load/reload current theme info */ - // $_SESSION['theme'] = $p[0]['channel_theme']; - + // $_SESSION['theme'] = $p[0]['channel_theme']; } public static function edit_menu($uid) @@ -198,14 +206,16 @@ class Libprofile $ret['edit'] = [z_root() . '/profiles/' . $uid, t('Edit Profile'), '', t('Edit')]; } - $r = q("SELECT * FROM profile WHERE uid = %d", + $r = q( + "SELECT * FROM profile WHERE uid = %d", local_channel() ); if ($r) { foreach ($r as $rr) { - if (!($multi_profiles || $rr['is_default'])) + if (!($multi_profiles || $rr['is_default'])) { continue; + } $ret['menu']['entries'][] = [ 'photo' => $rr['thumb'], @@ -252,13 +262,15 @@ class Libprofile $block = true; } - if ((!is_array($profile)) && (!count($profile))) + if ((!is_array($profile)) && (!count($profile))) { return $o; + } head_set_icon($profile['thumb']); - if (is_sys_channel($profile['uid'])) + if (is_sys_channel($profile['uid'])) { $show_connect = false; + } $profile['picdate'] = urlencode($profile['picdate']); @@ -269,42 +281,46 @@ class Libprofile call_hooks('profile_sidebar_enter', $profile); if ($show_connect) { - // This will return an empty string if we're already connected. $connect_url = rconnect_url($profile['uid'], get_observer_hash()); $connect = (($connect_url) ? t('Connect') : ''); - if ($connect_url) + if ($connect_url) { $connect_url = sprintf($connect_url, urlencode(channel_reddress($profile))); + } // premium channel - over-ride - if ($profile['channel_pageflags'] & PAGE_PREMIUM) + if ($profile['channel_pageflags'] & PAGE_PREMIUM) { $connect_url = z_root() . '/connect/' . $profile['channel_address']; + } } - if ((x($profile, 'address') == 1) + if ( + (x($profile, 'address') == 1) || (x($profile, 'locality') == 1) || (x($profile, 'region') == 1) || (x($profile, 'postal_code') == 1) - || (x($profile, 'country_name') == 1)) + || (x($profile, 'country_name') == 1) + ) { $location = t('Location:'); + } $profile['homepage'] = linkify($profile['homepage'], true); - $gender = ((x($profile, 'gender') == 1) ? t('Gender:') : False); - $marital = ((x($profile, 'marital') == 1) ? t('Status:') : False); - $homepage = ((x($profile, 'homepage') == 1) ? t('Homepage:') : False); - $pronouns = ((x($profile, 'pronouns') == 1) ? t('Pronouns:') : False); + $gender = ((x($profile, 'gender') == 1) ? t('Gender:') : false); + $marital = ((x($profile, 'marital') == 1) ? t('Status:') : false); + $homepage = ((x($profile, 'homepage') == 1) ? t('Homepage:') : false); + $pronouns = ((x($profile, 'pronouns') == 1) ? t('Pronouns:') : false); // zap/osada do not have a realtime chat system at this time so don't show online state - // $profile['online'] = (($profile['online_status'] === 'online') ? t('Online Now') : False); - // logger('online: ' . $profile['online']); + // $profile['online'] = (($profile['online_status'] === 'online') ? t('Online Now') : False); + // logger('online: ' . $profile['online']); $profile['online'] = false; if (($profile['hidewall'] && (!local_channel()) && (!remote_channel())) || $block) { - $location = $reddress = $pdesc = $gender = $marital = $homepage = False; + $location = $reddress = $pdesc = $gender = $marital = $homepage = false; } if ($profile['gender']) { @@ -327,8 +343,9 @@ class Libprofile if ($menu && !$block) { require_once('include/menu.php'); $m = menu_fetch($menu, $profile['uid'], $observer['xchan_hash']); - if ($m) + if ($m) { $channel_menu = menu_render($m); + } } $menublock = get_pconfig($profile['uid'], 'system', 'channel_menublock'); if ($menublock && (!$block)) { @@ -336,10 +353,11 @@ class Libprofile $channel_menu .= $comanche->block($menublock); } - if ($zcard) + if ($zcard) { $tpl = get_markup_template('profile_vcard_short.tpl'); - else + } else { $tpl = get_markup_template('profile_vcard.tpl'); + } $o .= replace_macros($tpl, array( '$zcard' => $zcard, @@ -383,23 +401,29 @@ class Libprofile public static function gender_icon($gender) { - // logger('gender: ' . $gender); + // logger('gender: ' . $gender); // This can easily get throw off if the observer language is different // than the channel owner language. - if (strpos(strtolower($gender), strtolower(t('Female'))) !== false) + if (strpos(strtolower($gender), strtolower(t('Female'))) !== false) { return 'venus'; - if (strpos(strtolower($gender), strtolower(t('Male'))) !== false) + } + if (strpos(strtolower($gender), strtolower(t('Male'))) !== false) { return 'mars'; - if (strpos(strtolower($gender), strtolower(t('Trans'))) !== false) + } + if (strpos(strtolower($gender), strtolower(t('Trans'))) !== false) { return 'transgender'; - if (strpos(strtolower($gender), strtolower(t('Inter'))) !== false) + } + if (strpos(strtolower($gender), strtolower(t('Inter'))) !== false) { return 'transgender'; - if (strpos(strtolower($gender), strtolower(t('Neuter'))) !== false) + } + if (strpos(strtolower($gender), strtolower(t('Neuter'))) !== false) { return 'neuter'; - if (strpos(strtolower($gender), strtolower(t('Non-specific'))) !== false) + } + if (strpos(strtolower($gender), strtolower(t('Non-specific'))) !== false) { return 'genderless'; + } return ''; } @@ -411,12 +435,15 @@ class Libprofile // This can easily get throw off if the observer language is different // than the channel owner language. - if (strpos(strtolower($pronouns), strtolower(t('She'))) !== false) + if (strpos(strtolower($pronouns), strtolower(t('She'))) !== false) { return 'venus'; - if (strpos(strtolower($pronouns), strtolower(t('Him'))) !== false) + } + if (strpos(strtolower($pronouns), strtolower(t('Him'))) !== false) { return 'mars'; - if (strpos(strtolower($pronouns), strtolower(t('Them'))) !== false) + } + if (strpos(strtolower($pronouns), strtolower(t('Them'))) !== false) { return 'users'; + } return ''; } @@ -425,19 +452,20 @@ class Libprofile public static function advanced() { - if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_profile')) + if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_profile')) { return ''; + } if (App::$profile['fullname']) { - $profile_fields_basic = get_profile_fields_basic(); $profile_fields_advanced = get_profile_fields_advanced(); $advanced = ((feature_enabled(App::$profile['profile_uid'], 'advanced_profiles')) ? true : false); - if ($advanced) + if ($advanced) { $fields = $profile_fields_advanced; - else + } else { $fields = $profile_fields_basic; + } $clean_fields = []; if ($fields) { @@ -453,38 +481,40 @@ class Libprofile $profile['fullname'] = array(t('Full Name:'), App::$profile['fullname']); - if (App::$profile['gender']) $profile['gender'] = array(t('Gender:'), App::$profile['gender']); + if (App::$profile['gender']) { + $profile['gender'] = array(t('Gender:'), App::$profile['gender']); + } $ob_hash = get_observer_hash(); // this may not work at all any more, but definitely won't work correctly if the liked profile belongs to a group // comment out until we are able to look at it much closer -// if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) { -// $profile['canlike'] = true; -// $profile['likethis'] = t('Like this channel'); -// $profile['profile_guid'] = App::$profile['profile_guid']; -// } +// if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) { +// $profile['canlike'] = true; +// $profile['likethis'] = t('Like this channel'); +// $profile['profile_guid'] = App::$profile['profile_guid']; +// } -// $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", -// intval(App::$profile['profile_uid']), -// dbesc(ACTIVITY_OBJ_PROFILE), -// dbesc(ACTIVITY_LIKE) -// ); -// $profile['likers'] = []; -// $profile['like_count'] = count($likers); -// $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); +// $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", +// intval(App::$profile['profile_uid']), +// dbesc(ACTIVITY_OBJ_PROFILE), +// dbesc(ACTIVITY_LIKE) +// ); +// $profile['likers'] = []; +// $profile['like_count'] = count($likers); +// $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); -// if($likers) { -// foreach($likers as $l) -// $profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url'])); -// } +// if($likers) { +// foreach($likers as $l) +// $profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url'])); +// } if ((App::$profile['dob']) && (App::$profile['dob'] != '0000-00-00')) { - $val = ''; - if ((substr(App::$profile['dob'], 5, 2) === '00') || (substr(App::$profile['dob'], 8, 2) === '00')) + if ((substr(App::$profile['dob'], 5, 2) === '00') || (substr(App::$profile['dob'], 8, 2) === '00')) { $val = substr(App::$profile['dob'], 0, 4); + } $year_bd_format = t('j F, Y'); $short_bd_format = t('j F'); @@ -497,14 +527,17 @@ class Libprofile $profile['birthday'] = array(t('Birthday:'), $val); } - if ($age = age(App::$profile['dob'], App::$profile['timezone'], '')) + if ($age = age(App::$profile['dob'], App::$profile['timezone'], '')) { $profile['age'] = array(t('Age:'), $age); + } - if (App::$profile['marital']) + if (App::$profile['marital']) { $profile['marital'] = array(t('Status:'), App::$profile['marital']); + } - if (App::$profile['partner']) + if (App::$profile['partner']) { $profile['marital']['partner'] = zidify_links(bbcode(App::$profile['partner'])); + } if (strlen(App::$profile['howlong']) && App::$profile['howlong'] > NULL_DATE) { $profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s')); @@ -523,51 +556,91 @@ class Libprofile } - if (App::$profile['sexual']) $profile['sexual'] = array(t('Sexual Preference:'), App::$profile['sexual']); + if (App::$profile['sexual']) { + $profile['sexual'] = array(t('Sexual Preference:'), App::$profile['sexual']); + } - if (App::$profile['pronouns']) $profile['pronouns'] = array(t('Pronouns:'), App::$profile['pronouns']); + if (App::$profile['pronouns']) { + $profile['pronouns'] = array(t('Pronouns:'), App::$profile['pronouns']); + } - if (App::$profile['homepage']) $profile['homepage'] = array(t('Homepage:'), linkify(App::$profile['homepage'])); + if (App::$profile['homepage']) { + $profile['homepage'] = array(t('Homepage:'), linkify(App::$profile['homepage'])); + } - if (App::$profile['hometown']) $profile['hometown'] = array(t('Hometown:'), linkify(App::$profile['hometown'])); + if (App::$profile['hometown']) { + $profile['hometown'] = array(t('Hometown:'), linkify(App::$profile['hometown'])); + } - if (App::$profile['politic']) $profile['politic'] = array(t('Political Views:'), App::$profile['politic']); + if (App::$profile['politic']) { + $profile['politic'] = array(t('Political Views:'), App::$profile['politic']); + } - if (App::$profile['religion']) $profile['religion'] = array(t('Religion:'), App::$profile['religion']); + if (App::$profile['religion']) { + $profile['religion'] = array(t('Religion:'), App::$profile['religion']); + } - if ($txt = prepare_text(App::$profile['about'])) $profile['about'] = array(t('About:'), $txt); + if ($txt = prepare_text(App::$profile['about'])) { + $profile['about'] = array(t('About:'), $txt); + } - if ($txt = prepare_text(App::$profile['interest'])) $profile['interest'] = array(t('Hobbies/Interests:'), $txt); + if ($txt = prepare_text(App::$profile['interest'])) { + $profile['interest'] = array(t('Hobbies/Interests:'), $txt); + } - if ($txt = prepare_text(App::$profile['likes'])) $profile['likes'] = array(t('Likes:'), $txt); + if ($txt = prepare_text(App::$profile['likes'])) { + $profile['likes'] = array(t('Likes:'), $txt); + } - if ($txt = prepare_text(App::$profile['dislikes'])) $profile['dislikes'] = array(t('Dislikes:'), $txt); + if ($txt = prepare_text(App::$profile['dislikes'])) { + $profile['dislikes'] = array(t('Dislikes:'), $txt); + } - if ($txt = prepare_text(App::$profile['contact'])) $profile['contact'] = array(t('Contact information and Social Networks:'), $txt); + if ($txt = prepare_text(App::$profile['contact'])) { + $profile['contact'] = array(t('Contact information and Social Networks:'), $txt); + } - if ($txt = prepare_text(App::$profile['channels'])) $profile['channels'] = array(t('My other channels:'), $txt); + if ($txt = prepare_text(App::$profile['channels'])) { + $profile['channels'] = array(t('My other channels:'), $txt); + } - if ($txt = prepare_text(App::$profile['music'])) $profile['music'] = array(t('Musical interests:'), $txt); + if ($txt = prepare_text(App::$profile['music'])) { + $profile['music'] = array(t('Musical interests:'), $txt); + } - if ($txt = prepare_text(App::$profile['book'])) $profile['book'] = array(t('Books, literature:'), $txt); + if ($txt = prepare_text(App::$profile['book'])) { + $profile['book'] = array(t('Books, literature:'), $txt); + } - if ($txt = prepare_text(App::$profile['tv'])) $profile['tv'] = array(t('Television:'), $txt); + if ($txt = prepare_text(App::$profile['tv'])) { + $profile['tv'] = array(t('Television:'), $txt); + } - if ($txt = prepare_text(App::$profile['film'])) $profile['film'] = array(t('Film/dance/culture/entertainment:'), $txt); + if ($txt = prepare_text(App::$profile['film'])) { + $profile['film'] = array(t('Film/dance/culture/entertainment:'), $txt); + } - if ($txt = prepare_text(App::$profile['romance'])) $profile['romance'] = array(t('Love/Romance:'), $txt); + if ($txt = prepare_text(App::$profile['romance'])) { + $profile['romance'] = array(t('Love/Romance:'), $txt); + } - if ($txt = prepare_text(App::$profile['employment'])) $profile['employment'] = array(t('Work/employment:'), $txt); + if ($txt = prepare_text(App::$profile['employment'])) { + $profile['employment'] = array(t('Work/employment:'), $txt); + } - if ($txt = prepare_text(App::$profile['education'])) $profile['education'] = array(t('School/education:'), $txt); + if ($txt = prepare_text(App::$profile['education'])) { + $profile['education'] = array(t('School/education:'), $txt); + } if (App::$profile['extra_fields']) { foreach (App::$profile['extra_fields'] as $f) { - $x = q("select * from profdef where field_name = '%s' limit 1", + $x = q( + "select * from profdef where field_name = '%s' limit 1", dbesc($f) ); - if ($x && $txt = prepare_text(App::$profile[$f])) + if ($x && $txt = prepare_text(App::$profile[$f])) { $profile[$f] = array($x[0]['field_desc'] . ':', $txt); + } } $profile['extra_fields'] = App::$profile['extra_fields']; } @@ -575,9 +648,9 @@ class Libprofile $things = get_things(App::$profile['profile_guid'], App::$profile['profile_uid']); - // logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA); + // logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA); - // $exportlink = ((App::$profile['profile_vcard']) ? zid(z_root() . '/profile/' . App::$profile['channel_address'] . '/vcard') : ''); + // $exportlink = ((App::$profile['profile_vcard']) ? zid(z_root() . '/profile/' . App::$profile['channel_address'] . '/vcard') : ''); return replace_macros($tpl, array( '$title' => t('Profile'), @@ -594,6 +667,4 @@ class Libprofile return ''; } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index 5a1efe312..2611364f4 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -56,7 +56,8 @@ class Libsync unset($channel['channel_password']); unset($channel['channel_salt']); - $h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url + $h = q( + "select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_network = 'zot6' and hubloc_deleted = 0", dbesc(($keychange) ? $packet['keychange']['old_hash'] : $channel['channel_hash']) ); @@ -72,7 +73,8 @@ class Libsync continue; } - $y = q("select site_dead from site where site_url = '%s' limit 1", + $y = q( + "select site_dead from site where site_url = '%s' limit 1", dbesc($x['hubloc_url']) ); @@ -106,7 +108,6 @@ class Libsync if ($channel) { $info['channel'] = []; foreach ($channel as $k => $v) { - // filter out any joined tables like xchan if (strpos($k, 'channel_') !== 0) { @@ -132,14 +133,16 @@ class Libsync } if ($groups_changed) { - $r = q("select hash as collection, visible, deleted, rule, gname as name from pgrp where uid = %d ", + $r = q( + "select hash as collection, visible, deleted, rule, gname as name from pgrp where uid = %d ", intval($uid) ); if ($r) { $info['collections'] = $r; } - $r = q("select pgrp.hash as collection, pgrp_member.xchan as member from pgrp left join pgrp_member on pgrp.id = pgrp_member.gid + $r = q( + "select pgrp.hash as collection, pgrp_member.xchan as member from pgrp left join pgrp_member on pgrp.id = pgrp_member.gid where pgrp_member.uid = %d ", intval($uid) ); @@ -203,7 +206,8 @@ class Libsync return; } - $l = q("select link from linkid where ident = '%s' and sigtype = 2", + $l = q( + "select link from linkid where ident = '%s' and sigtype = 2", dbesc($channel['channel_hash']) ); @@ -227,7 +231,8 @@ class Libsync continue; } - $y = q("select site_dead from site where site_url = '%s' limit 1", + $y = q( + "select site_dead from site where site_url = '%s' limit 1", dbesc($x['hubloc_url']) ); @@ -296,19 +301,22 @@ class Libsync foreach ($deliveries as $d) { $linked_channel = false; - $r = q("select * from channel where channel_hash = '%s' limit 1", + $r = q( + "select * from channel where channel_hash = '%s' limit 1", dbesc($sender) ); $DR = new DReport(z_root(), $sender, $d, 'sync'); if (!$r) { - $l = q("select ident from linkid where link = '%s' and sigtype = 2 limit 1", + $l = q( + "select ident from linkid where link = '%s' and sigtype = 2 limit 1", dbesc($sender) ); if ($l) { $linked_channel = true; - $r = q("select * from channel where channel_hash = '%s' limit 1", + $r = q( + "select * from channel where channel_hash = '%s' limit 1", dbesc($l[0]['ident']) ); } @@ -342,7 +350,8 @@ class Libsync // if the clone is active, so are we if (substr($channel['channel_active'], 0, 10) !== substr(datetime_convert(), 0, 10)) { - q("UPDATE channel set channel_active = '%s' where channel_id = %d", + q( + "UPDATE channel set channel_active = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($channel['channel_id']) ); @@ -421,19 +430,16 @@ class Libsync } if (array_key_exists('channel', $arr) && is_array($arr['channel']) && count($arr['channel'])) { - $remote_channel = $arr['channel']; $remote_channel['channel_id'] = $channel['channel_id']; if (array_key_exists('channel_pageflags', $arr['channel']) && intval($arr['channel']['channel_pageflags'])) { - // Several pageflags are site-specific and cannot be sync'd. // Only allow those bits which are shareable from the remote and then // logically OR with the local flags $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN | PAGE_AUTOCONNECT | PAGE_APPLICATION | PAGE_PREMIUM | PAGE_ADULT); $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] | $channel['channel_pageflags']; - } $columns = db_columns('channel'); @@ -461,11 +467,11 @@ class Libsync } if (array_key_exists('abook', $arr) && is_array($arr['abook']) && count($arr['abook'])) { - $total_friends = 0; $total_feeds = 0; - $r = q("select abook_id, abook_feed from abook where abook_channel = %d", + $r = q( + "select abook_id, abook_feed from abook where abook_channel = %d", intval($channel['channel_id']) ); if ($r) { @@ -484,7 +490,6 @@ class Libsync $fields = db_columns('abook'); foreach ($arr['abook'] as $abook) { - // this is here for debugging so we can find the issue source if (!is_array($abook)) { @@ -503,7 +508,8 @@ class Libsync if ($abook['abook_xchan'] && $abook['entry_deleted']) { logger('Removing abook entry for ' . $abook['abook_xchan']); - $r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", + $r = q( + "select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($abook['abook_xchan']), intval($channel['channel_id']) ); @@ -546,7 +552,8 @@ class Libsync $xc[$k] = $v; } } - $r = q("select * from xchan where xchan_hash = '%s'", + $r = q( + "select * from xchan where xchan_hash = '%s'", dbesc($xc['xchan_hash']) ); if (!$r) { @@ -584,7 +591,8 @@ class Libsync } } - $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + $r = q( + "select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($clean['abook_xchan']), intval($channel['channel_id']) ); @@ -621,7 +629,6 @@ class Libsync $r = dbq("UPDATE abook set " . dbesc($k) . " = '" . dbesc($v) . "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id'])); - } } @@ -646,7 +653,8 @@ class Libsync // sync collections (privacy groups) oh joy... if (array_key_exists('collections', $arr) && is_array($arr['collections']) && count($arr['collections'])) { - $x = q("select * from pgrp where uid = %d ", + $x = q( + "select * from pgrp where uid = %d ", intval($channel['channel_id']) ); foreach ($arr['collections'] as $cl) { @@ -659,10 +667,13 @@ class Libsync } } if ($found) { - if (($y['gname'] != $cl['name']) + if ( + ($y['gname'] != $cl['name']) || ($y['visible'] != $cl['visible']) - || ($y['deleted'] != $cl['deleted'])) { - q("update pgrp set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", + || ($y['deleted'] != $cl['deleted']) + ) { + q( + "update pgrp set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", dbesc($cl['name']), intval($cl['visible']), intval($cl['deleted']), @@ -671,14 +682,16 @@ class Libsync ); } if (intval($cl['deleted']) && (!intval($y['deleted']))) { - q("delete from pgrp_member where gid = %d", + q( + "delete from pgrp_member where gid = %d", intval($y['id']) ); } } } if (!$found) { - $r = q("INSERT INTO pgrp ( hash, uid, visible, deleted, gname, rule ) + $r = q( + "INSERT INTO pgrp ( hash, uid, visible, deleted, gname, rule ) VALUES( '%s', %d, %d, %d, '%s', '%s' ) ", dbesc($cl['collection']), intval($channel['channel_id']), @@ -703,10 +716,12 @@ class Libsync } } if (!$found_local) { - q("delete from pgrp_member where gid = %d", + q( + "delete from pgrp_member where gid = %d", intval($y['id']) ); - q("update pgrp set deleted = 1 where id = %d and uid = %d", + q( + "update pgrp set deleted = 1 where id = %d and uid = %d", intval($y['id']), intval($channel['channel_id']) ); @@ -716,16 +731,18 @@ class Libsync } // reload the group list with any updates - $x = q("select * from pgrp where uid = %d", + $x = q( + "select * from pgrp where uid = %d", intval($channel['channel_id']) ); // now sync the members - if (array_key_exists('collection_members', $arr) + if ( + array_key_exists('collection_members', $arr) && is_array($arr['collection_members']) - && count($arr['collection_members'])) { - + && count($arr['collection_members']) + ) { // first sort into groups keyed by the group hash $members = []; foreach ($arr['collection_members'] as $cm) { @@ -739,12 +756,12 @@ class Libsync // our group list is already synchronised if ($x) { foreach ($x as $y) { - // for each group, loop on members list we just received if (isset($y['hash']) && isset($members[$y['hash']])) { foreach ($members[$y['hash']] as $member) { $found = false; - $z = q("select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1", + $z = q( + "select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1", intval($y['id']), intval($channel['channel_id']), dbesc($member) @@ -756,7 +773,8 @@ class Libsync // if somebody is in the group that wasn't before - add them if (!$found) { - q("INSERT INTO pgrp_member (uid, gid, xchan) + q( + "INSERT INTO pgrp_member (uid, gid, xchan) VALUES( %d, %d, '%s' ) ", intval($channel['channel_id']), intval($y['id']), @@ -767,7 +785,8 @@ class Libsync } // now retrieve a list of members we have on this site - $m = q("select xchan from pgrp_member where gid = %d and uid = %d", + $m = q( + "select xchan from pgrp_member where gid = %d and uid = %d", intval($y['id']), intval($channel['channel_id']) ); @@ -775,7 +794,8 @@ class Libsync foreach ($m as $mm) { // if the local existing member isn't in the list we just received - remove them if (!in_array($mm['xchan'], $members[$y['hash']])) { - q("delete from pgrp_member where xchan = '%s' and gid = %d and uid = %d", + q( + "delete from pgrp_member where xchan = '%s' and gid = %d and uid = %d", dbesc($mm['xchan']), intval($y['id']), intval($channel['channel_id']) @@ -789,12 +809,11 @@ class Libsync } if (array_key_exists('profile', $arr) && is_array($arr['profile']) && count($arr['profile'])) { - $disallowed = array('id', 'aid', 'uid', 'guid'); foreach ($arr['profile'] as $profile) { - - $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", + $x = q( + "select * from profile where profile_guid = '%s' and uid = %d limit 1", dbesc($profile['profile_guid']), intval($channel['channel_id']) ); @@ -807,7 +826,8 @@ class Libsync ] ); - $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", + $x = q( + "select * from profile where profile_guid = '%s' and uid = %d limit 1", dbesc($profile['profile_guid']), intval($channel['channel_id']) ); @@ -897,7 +917,8 @@ class Libsync // If a sender reports that the channel has been deleted, delete its hubloc if (isset($arr['deleted_locally']) && intval($arr['deleted_locally'])) { - q("UPDATE hubloc SET hubloc_deleted = 1, hubloc_updated = '%s' WHERE hubloc_hash = '%s' AND hubloc_url = '%s'", + q( + "UPDATE hubloc SET hubloc_deleted = 1, hubloc_updated = '%s' WHERE hubloc_hash = '%s' AND hubloc_url = '%s'", dbesc(datetime_convert()), dbesc($sender['hash']), dbesc($sender['site']['url']) @@ -905,8 +926,8 @@ class Libsync } if ($arr['locations']) { - - $x = q("select * from xchan where xchan_hash = '%s'", + $x = q( + "select * from xchan where xchan_hash = '%s'", dbesc($sender['hash']) ); if ($x) { @@ -917,7 +938,8 @@ class Libsync Libzot::check_location_move($sender['hash'], $arr['locations']); } - $xisting = q("select * from hubloc where hubloc_hash = '%s'", + $xisting = q( + "select * from hubloc where hubloc_hash = '%s'", dbesc($sender['hash']) ); @@ -937,8 +959,9 @@ class Libsync // Ensure that they have one primary hub - if (!$has_primary) + if (!$has_primary) { $arr['locations'][0]['primary'] = true; + } foreach ($arr['locations'] as $location) { if (!Libzot::verify($location['url'], $location['url_sig'], $sender['public_key'])) { @@ -948,8 +971,10 @@ class Libsync } for ($x = 0; $x < count($xisting); $x++) { - if (($xisting[$x]['hubloc_url'] === $location['url']) - && ($xisting[$x]['hubloc_sitekey'] === $location['sitekey'])) { + if ( + ($xisting[$x]['hubloc_url'] === $location['url']) + && ($xisting[$x]['hubloc_sitekey'] === $location['sitekey']) + ) { $xisting[$x]['updated'] = true; } } @@ -961,7 +986,8 @@ class Libsync // match as many fields as possible in case anything at all changed. - $r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_id_url = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' ", + $r = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_id_url = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' ", dbesc($sender['hash']), dbesc($sender['id']), dbesc($sender['id_sig']), @@ -979,7 +1005,8 @@ class Libsync // generate a new hubloc_site_id if it's wrong due to historical bugs 2021-11-30 if ($r[0]['hubloc_site_id'] !== $location['site_id']) { - q("update hubloc set hubloc_site_id = '%s' where hubloc_id = %d", + q( + "update hubloc set hubloc_site_id = '%s' where hubloc_id = %d", dbesc(Libzot::make_xchan_hash($location['url'], $location['sitekey'])), intval($r[0]['hubloc_id']) ); @@ -993,7 +1020,8 @@ class Libsync $t = datetime_convert('UTC', 'UTC', 'now - 15 minutes'); if (array_key_exists('site', $arr) && $location['url'] == $arr['site']['url']) { - q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_updated < '%s'", + q( + "update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_updated < '%s'", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($r[0]['hubloc_id']), @@ -1003,15 +1031,18 @@ class Libsync } if ($current_site && (intval($r[0]['hubloc_error']) || intval($r[0]['hubloc_deleted']))) { - q("update hubloc set hubloc_error = 0, hubloc_deleted = 0 where hubloc_id = %d", + q( + "update hubloc set hubloc_error = 0, hubloc_deleted = 0 where hubloc_id = %d", intval($r[0]['hubloc_id']) ); if (intval($r[0]['hubloc_orphancheck'])) { - q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d", + q( + "update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d", intval($r[0]['hubloc_id']) ); } - q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", + q( + "update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", dbesc($sender['hash']) ); } @@ -1019,7 +1050,8 @@ class Libsync // Remove pure duplicates if (count($r) > 1) { for ($h = 1; $h < count($r); $h++) { - q("delete from hubloc where hubloc_id = %d", + q( + "delete from hubloc where hubloc_id = %d", intval($r[$h]['hubloc_id']) ); $what .= 'duplicate_hubloc_removed '; @@ -1028,7 +1060,8 @@ class Libsync } if (intval($r[0]['hubloc_primary']) && (!$location['primary'])) { - $m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id = %d", + $m = q( + "update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); @@ -1037,7 +1070,8 @@ class Libsync $what .= 'primary_hub '; $changed = true; } elseif ((!intval($r[0]['hubloc_primary'])) && ($location['primary'])) { - $m = q("update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d", + $m = q( + "update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); @@ -1062,7 +1096,8 @@ class Libsync } if (intval($r[0]['hubloc_deleted']) && (!intval($location['deleted']))) { - $n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d", + $n = q( + "update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); @@ -1070,7 +1105,8 @@ class Libsync $changed = true; } elseif ((!intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) { logger('deleting hubloc: ' . $r[0]['hubloc_addr']); - $n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d", + $n = q( + "update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); @@ -1084,7 +1120,8 @@ class Libsync // New hub claiming to be primary. Make it so by removing any existing primaries. if (intval($location['primary'])) { - $r = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1", + $r = q( + "update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1", dbesc(datetime_convert()), dbesc($sender['hash']) ); @@ -1116,12 +1153,14 @@ class Libsync $changed = true; if ($location['primary']) { - $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s' limit 1", + $r = q( + "select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s' limit 1", dbesc($location['address']), dbesc($location['sitekey']) ); - if ($r) + if ($r) { hubloc_change_primary($r[0]); + } } } @@ -1131,7 +1170,8 @@ class Libsync foreach ($xisting as $x) { if (!array_key_exists('updated', $x)) { logger('Deleting unreferenced hub location ' . $x['hubloc_addr']); - $r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d", + $r = q( + "update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($x['hubloc_id']) ); @@ -1164,7 +1204,8 @@ class Libsync $hash = Libzot::make_xchan_hash($channel['channel_guid'], $arr['channel']['channel_pubkey']); - $r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', + $r = q( + "update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', channel_hash = '%s' where channel_id = %d", dbesc($arr['channel']['channel_prvkey']), dbesc($arr['channel']['channel_pubkey']), @@ -1177,7 +1218,8 @@ class Libsync return; } - $r = q("select * from channel where channel_id = %d", + $r = q( + "select * from channel where channel_id = %d", intval($channel['channel_id']) ); @@ -1188,7 +1230,8 @@ class Libsync $channel = $r[0]; - $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", + $h = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", dbesc($arr['keychange']['old_hash']), dbesc(z_root()) ); @@ -1202,11 +1245,13 @@ class Libsync } } - $x = q("select * from xchan where xchan_hash = '%s' ", + $x = q( + "select * from xchan where xchan_hash = '%s' ", dbesc($arr['keychange']['old_hash']) ); - $check = q("select * from xchan where xchan_hash = '%s'", + $check = q( + "select * from xchan where xchan_hash = '%s'", dbesc($hash) ); @@ -1222,19 +1267,19 @@ class Libsync } } - $a = q("select * from abook where abook_xchan = '%s' and abook_self = 1", + $a = q( + "select * from abook where abook_xchan = '%s' and abook_self = 1", dbesc($arr['keychange']['old_hash']) ); if ($a) { - q("update abook set abook_xchan = '%s' where abook_id = %d", + q( + "update abook set abook_xchan = '%s' where abook_id = %d", dbesc($hash), intval($a[0]['abook_id']) ); } xchan_change_key($oldxchan, $newxchan, $arr['keychange']); - } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 630fd82a4..5d225bd59 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -82,7 +82,8 @@ class Libzot /* Only search for active hublocs - e.g. those that haven't been marked deleted */ - $ret = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0 order by hubloc_url ", + $ret = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0 order by hubloc_url ", dbesc($hash) ); @@ -234,8 +235,14 @@ class Libzot '(request-target)' => 'post ' . get_request_string($url) ]; - $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false, 'sha512', - (($crypto) ? ['key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto'])] : false)); + $h = HTTPSig::create_sig( + $headers, + $channel['channel_prvkey'], + channel_url($channel), + false, + 'sha512', + (($crypto) ? ['key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto'])] : false) + ); } else { $h = []; } @@ -299,7 +306,8 @@ class Libzot // We are looking for the most recently created primary hub, and the most recently created if for some reason we do not have a primary. // hubloc_id_url is set to the channel home, which corresponds to an ActivityStreams actor id. - $r = q("select hubloc_id_url, hubloc_primary from hubloc where hubloc_hash = '%s' and hubloc_network = 'zot6' order by hubloc_id desc", + $r = q( + "select hubloc_id_url, hubloc_primary from hubloc where hubloc_hash = '%s' and hubloc_network = 'zot6' order by hubloc_id desc", dbesc($them['xchan_hash']) ); @@ -325,7 +333,8 @@ class Libzot $site_url = unparse_url(['scheme' => $m['scheme'], 'host' => $m['host']]); - $s = q("select site_dead from site where site_url = '%s' limit 1", + $s = q( + "select site_dead from site where site_url = '%s' limit 1", dbesc($site_url) ); @@ -377,23 +386,25 @@ class Libzot // Keep original perms to check if we need to notify them $previous_perms = get_all_perms($channel['channel_id'], $x['hash']); - $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", + $r = q( + "select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($x['hash']), intval($channel['channel_id']) ); if ($r) { - // connection exists // if the dob is the same as what we have stored (disregarding the year), keep the one // we have as we may have updated the year after sending a notification; and resetting // to the one we just received would cause us to create duplicated events. - if (substr($r[0]['abook_dob'], 5) == substr($next_birthday, 5)) + if (substr($r[0]['abook_dob'], 5) == substr($next_birthday, 5)) { $next_birthday = $r[0]['abook_dob']; + } - $y = q("update abook set abook_dob = '%s' + $y = q( + "update abook set abook_dob = '%s' where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 ", dbescdate($next_birthday), @@ -405,15 +416,16 @@ class Libzot logger('abook update failed'); } else { // if we were just granted read stream permission and didn't have it before, try to pull in some posts - if ((!$old_read_stream_perm) && (intval($permissions['view_stream']))) + if ((!$old_read_stream_perm) && (intval($permissions['view_stream']))) { Run::Summon(['Onepoll', $r[0]['abook_id']]); + } } } else { - // limit the ability to do connection spamming, this limit is per channel $lim = intval(get_config('system', 'max_connections_per_day', 50)); if ($lim) { - $n = q("select count(abook_id) as total from abook where abook_channel = %d and abook_created > '%s'", + $n = q( + "select count(abook_id) as total from abook where abook_channel = %d and abook_created > '%s'", intval($channel['channel_id']), dbesc(datetime_convert('UTC', 'UTC', 'now - 24 hours')) ); @@ -456,7 +468,8 @@ class Libzot $is_collection = false; - $cl = q("select channel_id from channel where channel_hash = '%s' and channel_parent = '%s' and channel_account_id = %d limit 1", + $cl = q( + "select channel_id from channel where channel_hash = '%s' and channel_parent = '%s' and channel_account_id = %d limit 1", dbesc($x['hash']), dbesc($channel['channel_hash']), intval($channel['channel_account_id']) @@ -487,7 +500,8 @@ class Libzot // Send a clone sync packet and a permissions update if permissions have changed - $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1", + $new_connection = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1", dbesc($x['hash']), intval($channel['channel_id']) ); @@ -509,9 +523,12 @@ class Libzot } if (intval($permissions['view_stream'])) { - if (intval(get_pconfig($channel['channel_id'], 'perm_limits', 'send_stream') & PERMS_PENDING) - || (!intval($new_connection[0]['abook_pending']))) + if ( + intval(get_pconfig($channel['channel_id'], 'perm_limits', 'send_stream') & PERMS_PENDING) + || (!intval($new_connection[0]['abook_pending'])) + ) { Run::Summon(['Onepoll', $new_connection[0]['abook_id']]); + } } @@ -538,7 +555,6 @@ class Libzot Libsync::build_sync_packet($channel['channel_id'], ['abook' => $new_connection]); } } - } return true; } else { @@ -560,7 +576,7 @@ class Libzot * * \e string \b id_sig => id signed with conversant's private key * * \e string \b location => URL of the origination hub of this communication * * \e string \b location_sig => URL signed with conversant's private key - * @param boolean $multiple (optional) default false + * @param bool $multiple (optional) default false * * @return array|null * * null if site is denied or not found @@ -571,7 +587,6 @@ class Libzot { if ($arr['id'] && $arr['id_sig'] && $arr['location'] && $arr['location_sig']) { - if (!check_siteallowed($arr['location'])) { logger('denied site: ' . $arr['location']); return null; @@ -579,7 +594,8 @@ class Libzot $limit = (($multiple) ? '' : ' limit 1 '); - $r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url + $r = q( + "select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_site_id = '%s' and hubloc_network = 'zot6' @@ -604,7 +620,8 @@ class Libzot public static function valid_hub($sender, $site_id) { - $r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_site_id = '%s' limit 1", + $r = q( + "select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_site_id = '%s' limit 1", dbesc($sender), dbesc($site_id) ); @@ -747,7 +764,8 @@ class Libzot logger('import_xchan: ' . $xchan_hash, LOGGER_DEBUG); - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($xchan_hash) ); @@ -829,15 +847,18 @@ class Libzot } - if (($r[0]['xchan_name_date'] != $arr['name_updated']) + if ( + ($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['primary_location']['connections_url']) || ($r[0]['xchan_addr'] != $arr['primary_location']['address']) || ($r[0]['xchan_follow'] != $arr['primary_location']['follow_url']) || ($r[0]['xchan_connpage'] != $arr['connect_url']) || ($r[0]['xchan_url'] != $arr['primary_location']['url']) || ($r[0]['xchan_updated'] < datetime_convert('UTC', 'UTC', 'now - 7 days')) - || $hidden_changed || $adult_changed || $deleted_changed || $type_changed) { - $rup = q("update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s', + || $hidden_changed || $adult_changed || $deleted_changed || $type_changed + ) { + $rup = q( + "update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s', xchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_type = %d, xchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), @@ -863,9 +884,11 @@ class Libzot } else { $import_photos = true; - if ((($arr['site']['directory_mode'] === 'standalone') + if ( + (($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) - && ($arr['site']['url'] != z_root())) { + && ($arr['site']['url'] != z_root()) + ) { $arr['searchable'] = false; } @@ -916,12 +939,12 @@ class Libzot } if ($import_photos) { - require_once('include/photo_factory.php'); // see if this is a channel clone that's hosted locally - which we treat different from other xchans/connections - $local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1", + $local = q( + "select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1", dbesc($xchan_hash) ); if ($local) { @@ -936,7 +959,8 @@ class Libzot // unless proven otherwise $is_default_profile = 1; - $profile = q("select is_default from profile where aid = %d and uid = %d limit 1", + $profile = q( + "select is_default from profile where aid = %d and uid = %d limit 1", intval($local[0]['channel_account_id']), intval($local[0]['channel_id']) ); @@ -948,7 +972,8 @@ class Libzot // If setting for the default profile, unset the profile photo flag from any other photos I own if ($is_default_profile) { - q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", + q( + "UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), dbesc($hash), @@ -974,7 +999,8 @@ class Libzot if ($photos[4]) { // importing the photo failed somehow. Leave the photo_date alone so we can try again at a later date. // This often happens when somebody joins the matrix with a bad cert. - $r = q("update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), @@ -984,7 +1010,8 @@ class Libzot dbesc($xchan_hash) ); } else { - $r = q("update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc(datetime_convert('UTC', 'UTC', ((isset($arr['photo_updated'])) ? $arr['photo_updated'] : 'now'))), @@ -1027,14 +1054,14 @@ class Libzot $other_realm = false; -// $realm = get_directory_realm(); -// if (array_key_exists('site',$arr) -// && array_key_exists('realm',$arr['site']) -// && (strpos($arr['site']['realm'],$realm) === false)) -// $other_realm = true; +// $realm = get_directory_realm(); +// if (array_key_exists('site',$arr) +// && array_key_exists('realm',$arr['site']) +// && (strpos($arr['site']['realm'],$realm) === false)) +// $other_realm = true; -// if ($dirmode != DIRECTORY_MODE_NORMAL) { +// if ($dirmode != DIRECTORY_MODE_NORMAL) { // We're some kind of directory server. However we can only add directory information // if the entry is in the same realm (or is a sub-realm). Sub-realms are denoted by @@ -1050,14 +1077,16 @@ class Libzot } else { logger('Profile not available - hiding'); // they may have made it private - $r = q("delete from xprof where xprof_hash = '%s'", + $r = q( + "delete from xprof where xprof_hash = '%s'", dbesc($xchan_hash) ); - $r = q("delete from xtag where xtag_hash = '%s' and xtag_flags = 0", + $r = q( + "delete from xtag where xtag_hash = '%s' and xtag_flags = 0", dbesc($xchan_hash) ); } -// } +// } if (array_key_exists('site', $arr) && is_array($arr['site'])) { $profile_changed = self::import_site($arr['site']); @@ -1073,7 +1102,8 @@ class Libzot logger('Changed: ' . $what, LOGGER_DEBUG); } elseif (!$ud_flags) { // nothing changed but we still need to update the updates record - q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) > 0 ", + q( + "update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) > 0 ", intval(UPDATE_FLAGS_UPDATED), dbesc($address), intval(UPDATE_FLAGS_UPDATED) @@ -1128,10 +1158,10 @@ class Libzot if ($x) { if (!$x['success']) { - // handle remote validation issues - $b = q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", + $b = q( + "update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", dbesc(($x['message']) ? $x['message'] : 'unknown delivery error'), dbesc(datetime_convert()), dbesc($outq['outq_hash']) @@ -1142,7 +1172,8 @@ class Libzot foreach ($x['delivery_report'] as $xx) { call_hooks('dreport_process', $xx); if (is_array($xx) && array_key_exists('message_id', $xx) && DReport::is_storable($xx)) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_log ) values ( '%s', '%s', '%s','%s','%s','%s','%s','%s' ) ", + q( + "insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_log ) values ( '%s', '%s', '%s','%s','%s','%s','%s','%s' ) ", dbesc($xx['message_id']), dbesc($xx['location']), dbesc($xx['recipient']), @@ -1157,14 +1188,16 @@ class Libzot // we have a more descriptive delivery report, so discard the per hub 'queue' report. - q("delete from dreport where dreport_queue = '%s' ", + q( + "delete from dreport where dreport_queue = '%s' ", dbesc($outq['outq_hash']) ); } } // update the timestamp for this site - q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'", + q( + "update site set site_dead = 0, site_update = '%s' where site_url = '%s'", dbesc(datetime_convert()), dbesc(dirname($hub)) ); @@ -1207,7 +1240,6 @@ class Libzot logger('zot_fetch: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); return self::import($arr, $hub); - } /** @@ -1256,10 +1288,11 @@ class Libzot $AS = null; if ($env['encoding'] === 'activitystreams') { - $AS = new ActivityStreams($data); - if ($AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) - && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) { + if ( + $AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) + && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj) + ) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); @@ -1305,7 +1338,6 @@ class Libzot logger('activity rejected: create actor'); return; } - } $deliveries = null; @@ -1341,7 +1373,6 @@ class Libzot // We found somebody on this site that's in the recipient list. } else { - logger('public post'); @@ -1360,15 +1391,14 @@ class Libzot } if ($has_data) { - if (in_array($env['type'], ['activity', 'response'])) { - if (!(is_array($AS->actor) && isset($AS->actor['id']))) { logger('No author!'); return; } - $r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s'", + $r = q( + "select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s'", dbesc($AS->actor['id']) ); @@ -1382,7 +1412,8 @@ class Libzot return; } - $s = q("select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $s = q( + "select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($env['sender']) ); @@ -1422,7 +1453,8 @@ class Libzot if (!array_key_exists('comment_policy', $arr)) { // set comment policy depending on source hub. Unknown or osada is ActivityPub. // Anything else we'll say is zot - which could have a range of project names - $s = q("select site_project from site where site_url = '%s' limit 1", + $s = q( + "select site_project from site where site_url = '%s' limit 1", dbesc($r[0]['hubloc_url']) ); @@ -1448,7 +1480,6 @@ class Libzot $result = self::process_delivery($env['sender'], $AS, $arr, $deliveries, $relay, false, $message_request); } elseif ($env['type'] === 'sync') { - $arr = json_decode($data, true); logger('Channel sync received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); @@ -1544,7 +1575,6 @@ class Libzot if ($c) { foreach ($c as $cc) { - // top level activity sent to ourself: ignore. Clones will get a sync activity // which is a true clone of the original item. Everything else is a duplicate. @@ -1568,7 +1598,8 @@ class Libzot // add channels that are following tags // these will be enumerated and validated in tgroup_check() - $ft = q("select channel_hash as hash from channel left join pconfig on pconfig.uid = channel_id where cat = 'system' and k = 'followed_tags' and channel_hash != '%s' and channel_removed = 0", + $ft = q( + "select channel_hash as hash from channel left join pconfig on pconfig.uid = channel_id where cat = 'system' and k = 'followed_tags' and channel_hash != '%s' and channel_removed = 0", dbesc($msg['sender']) ); if ($ft) { @@ -1588,7 +1619,8 @@ class Libzot if ($tag['type'] === 'Mention' && (strpos($tag['href'], z_root()) !== false)) { $address = basename($tag['href']); if ($address) { - $z = q("select channel_hash as hash from channel where channel_address = '%s' + $z = q( + "select channel_hash as hash from channel where channel_address = '%s' and channel_hash != '%s' and channel_removed = 0 limit 1", dbesc($address), dbesc($msg['sender']) @@ -1601,7 +1633,8 @@ class Libzot if ($tag['type'] === 'topicalCollection' && strpos($tag['name'], App::get_hostname())) { $address = substr($tag['name'], 0, strpos($tag['name'], '@')); if ($address) { - $z = q("select channel_hash as hash from channel where channel_address = '%s' + $z = q( + "select channel_hash as hash from channel where channel_address = '%s' and channel_hash != '%s' and channel_removed = 0 limit 1", dbesc($address), dbesc($msg['sender']) @@ -1622,7 +1655,8 @@ class Libzot $thread_parent = self::find_parent($msg, $act); if ($thread_parent) { - $z = q("select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ", + $z = q( + "select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ", dbesc($thread_parent), dbesc($thread_parent) ); @@ -1652,9 +1686,9 @@ class Libzot * @param ActivityStreams object $act * @param array $msg_arr * @param array $deliveries - * @param boolean $relay - * @param boolean $public (optional) default false - * @param boolean $request (optional) default false + * @param bool $relay + * @param bool $public (optional) default false + * @param bool $request (optional) default false * @return array */ @@ -1686,16 +1720,15 @@ class Libzot } foreach ($deliveries as $d) { - $local_public = $public; // if any further changes are to be made, change a copy and not the original $arr = $msg_arr; -// if (! $msg_arr['mid']) { -// logger('no mid2: ' . print_r($msg_arr,true)); -// logger('recip: ' . $d); -// } +// if (! $msg_arr['mid']) { +// logger('no mid2: ' . print_r($msg_arr,true)); +// logger('recip: ' . $d); +// } $DR = new DReport(z_root(), $sender, $d, $arr['mid']); @@ -1710,27 +1743,26 @@ class Libzot $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); -// if ($act->type === 'Tombstone') { -// $r = q("select * from item where mid in ( '%s', '%s' ) and uid = %d", -// dbesc($act->id), -// dbesc(str_replace('/activity/','/item/',$act->id)) -// intval($channel['channel_id']) -// ); -// if ($r) { -// if (($r[0]['author_xchan'] === $sender) || ($r[0]['owner_xchan'] === $sender)) { -// drop_item($r[0]['id'],false); -// } -// $DR->update('item deleted'); -// $result[] = $DR->get(); -// continue; -// } -// $DR->update('deleted item not found'); -// $result[] = $DR->get(); -// continue; -// } +// if ($act->type === 'Tombstone') { +// $r = q("select * from item where mid in ( '%s', '%s' ) and uid = %d", +// dbesc($act->id), +// dbesc(str_replace('/activity/','/item/',$act->id)) +// intval($channel['channel_id']) +// ); +// if ($r) { +// if (($r[0]['author_xchan'] === $sender) || ($r[0]['owner_xchan'] === $sender)) { +// drop_item($r[0]['id'],false); +// } +// $DR->update('item deleted'); +// $result[] = $DR->get(); +// continue; +// } +// $DR->update('deleted item not found'); +// $result[] = $DR->get(); +// continue; +// } if (($act) && ($act->obj) && (!is_array($act->obj))) { - // The initial object fetch failed using the sys channel credentials. // Try again using the delivery channel credentials. // We will also need to re-parse the $item array, @@ -1777,7 +1809,8 @@ class Libzot // don't allow pubstream posts if the sender even has a clone on a pubstream denied site $siteallowed = true; - $h = q("select hubloc_url from hubloc where hubloc_hash = '%s'", + $h = q( + "select hubloc_url from hubloc where hubloc_hash = '%s'", dbesc($sender) ); if ($h) { @@ -1793,7 +1826,8 @@ class Libzot continue; } - $r = q("select xchan_selfcensored from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select xchan_selfcensored from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); // don't import sys channel posts from selfcensored authors @@ -1812,8 +1846,9 @@ class Libzot $tag_delivery = tgroup_check($channel['channel_id'], $arr); $perm = 'send_stream'; - if (($arr['mid'] !== $arr['parent_mid']) && ($relay)) + if (($arr['mid'] !== $arr['parent_mid']) && ($relay)) { $perm = 'post_comments'; + } // This is our own post, possibly coming from a channel clone @@ -1830,7 +1865,8 @@ class Libzot $blocked = LibBlock::fetch($channel['channel_id'], BLOCKTYPE_SERVER); if ($blocked) { - $h = q("select hubloc_url from hubloc where hubloc_hash = '%s'", + $h = q( + "select hubloc_url from hubloc where hubloc_hash = '%s'", dbesc($sender) ); if ($h) { @@ -1848,7 +1884,8 @@ class Libzot if (!$allowed) { if ($perm === 'post_comments') { - $parent = q("select * from item where mid = '%s' and uid = %d limit 1", + $parent = q( + "select * from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) ); @@ -1865,13 +1902,11 @@ class Libzot if ($parent && absolutely_no_comments($parent[0])) { $allowed = false; } - } elseif ($permit_mentions) { $allowed = true; } } if ($request) { - // Conversation fetches (e.g. $request == true) take place for // a) new comments on expired posts // b) hyperdrive (friend-of-friend) conversations @@ -1916,7 +1951,6 @@ class Libzot } if ($arr['mid'] !== $arr['parent_mid']) { - if (perm_is_allowed($channel['channel_id'], $sender, 'moderated') && $relay) { $arr['item_blocked'] = ITEM_MODERATED; } @@ -1931,12 +1965,14 @@ class Libzot $prnt = ((strpos($arr['parent_mid'], 'token=') !== false) ? substr($arr['parent_mid'], 0, strpos($arr['parent_mid'], '?')) : ''); - $r = q("select route, id, parent_mid, mid, owner_xchan, item_private, obj_type from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select route, id, parent_mid, mid, owner_xchan, item_private, obj_type from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) ); if (!$r) { - $r = q("select route, id, parent_mid, mid, owner_xchan, item_private, obj_type from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select route, id, parent_mid, mid, owner_xchan, item_private, obj_type from item where mid = '%s' and uid = %d limit 1", dbesc($prnt), intval($channel['channel_id']) ); @@ -1948,7 +1984,8 @@ class Libzot $arr['thr_parent'] = $arr['parent_mid']; $arr['parent_mid'] = $r[0]['parent_mid']; if ($act->replyto) { - q("update item set replyto = '%s' where id = %d", + q( + "update item set replyto = '%s' where id = %d", dbesc($act->replyto), intval($r[0]['id']) ); @@ -1964,7 +2001,6 @@ class Libzot } } } else { - // We don't seem to have a copy of this conversation or at least the parent // - so request a copy of the entire conversation to date. // Don't do this if it's a relay post as we're the ones who are supposed to @@ -1976,8 +2012,10 @@ class Libzot // the top level post is unlikely to be imported and // this is just an exercise in futility. - if ((!$relay) && (!$request) && (!$local_public) - && perm_is_allowed($channel['channel_id'], $sender, 'send_stream')) { + if ( + (!$relay) && (!$request) && (!$local_public) + && perm_is_allowed($channel['channel_id'], $sender, 'send_stream') + ) { $reports = self::fetch_conversation($channel, $arr['mid']); // extract our delivery report from the fetched conversation @@ -2018,7 +2056,6 @@ class Libzot $arr['route'] = $r[0]['route']; $arr['owner_xchan'] = $r[0]['owner_xchan']; } else { - // going downstream check that we have the same upstream provider that // sent it to us originally. Ignore it if it came from another source // (with potentially different permissions). @@ -2058,14 +2095,14 @@ class Libzot // This is used to fetch allow/deny rules if either the sender // or owner is a connection. post_is_importable() evaluates all of them - $abook = q("select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )", + $abook = q( + "select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )", intval($channel['channel_id']), dbesc($arr['owner_xchan']), dbesc($arr['author_xchan']) ); if (isset($arr['item_deleted']) && intval($arr['item_deleted'])) { - // set these just in case we need to store a fresh copy of the deleted post. // This could happen if the delete got here before the original post did. @@ -2088,7 +2125,8 @@ class Libzot // reactions such as like and dislike could have an mid with /activity/ in it. // Check for both forms in order to prevent duplicates. - $r = q("select * from item where mid in ('%s','%s') and uid = %d limit 1", + $r = q( + "select * from item where mid in ('%s','%s') and uid = %d limit 1", dbesc($arr['mid']), dbesc(str_replace(z_root() . '/activity/', z_root() . '/item/', $arr['mid'])), intval($channel['channel_id']) @@ -2163,7 +2201,6 @@ class Libzot } if (post_is_importable($arr['uid'], $arr, $abook)) { - // Strip old-style hubzilla bookmarks if (strpos($arr['body'], "#^[") !== false) { $arr['body'] = str_replace("#^[", "[", $arr['body']); @@ -2203,8 +2240,10 @@ class Libzot // preserve conversations with which you are involved from expiration $stored = (($item_result && $item_result['item']) ? $item_result['item'] : false); - if ((is_array($stored)) && ($stored['id'] != $stored['parent']) - && ($stored['author_xchan'] === $channel['channel_hash'])) { + if ( + (is_array($stored)) && ($stored['id'] != $stored['parent']) + && ($stored['author_xchan'] === $channel['channel_hash']) + ) { retain_item($stored['item']['parent']); } @@ -2263,16 +2302,18 @@ class Libzot $ret = []; - $signer = q("select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $signer = q( + "select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($a['signature']['signer']) ); foreach ($items as $activity) { - $AS = new ActivityStreams($activity); - if ($AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) - && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) { + if ( + $AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) + && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj) + ) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); @@ -2287,7 +2328,8 @@ class Libzot // logger($AS->debug()); - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", + $r = q( + "select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", dbesc($AS->actor['id']), dbesc($AS->actor['id']) ); @@ -2295,7 +2337,8 @@ class Libzot if (!$r) { $y = import_author_xchan(['url' => $AS->actor['id']]); if ($y) { - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", + $r = q( + "select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s' limit 1", dbesc($AS->actor['id']), dbesc($AS->actor['id']) ); @@ -2361,8 +2404,9 @@ class Libzot public static function remove_community_tag($sender, $arr, $uid) { - if (!(activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM))) + if (!(activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM))) { return; + } logger('remove_community_tag: invoked'); @@ -2371,7 +2415,8 @@ class Libzot return; } - $r = q("select * from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select * from item where mid = '%s' and uid = %d limit 1", dbesc($arr['mid']), intval($uid) ); @@ -2400,7 +2445,8 @@ class Libzot $message_id = $i['target']['id']; - $r = q("select id from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select id from item where mid = '%s' and uid = %d limit 1", dbesc($message_id), intval($uid) ); @@ -2409,7 +2455,8 @@ class Libzot return; } - q("delete from term where uid = %d and oid = %d and otype = %d and ttype in ( %d, %d ) and term = '%s' and url = '%s'", + q( + "delete from term where uid = %d and oid = %d and otype = %d and ttype in ( %d, %d ) and term = '%s' and url = '%s'", intval($uid), intval($r[0]['id']), intval(TERM_OBJ_POST), @@ -2427,7 +2474,7 @@ class Libzot * @param array $item * @param array $orig * @param int $uid - * @param boolean $tag_delivery + * @param bool $tag_delivery * @see item_store_update() * */ @@ -2483,8 +2530,8 @@ class Libzot * * \e string \b hash a xchan_hash * @param array $item * @param int $uid - * @param boolean $relay - * @return boolean|int post_id + * @param bool $relay + * @return bool|int post_id */ public static function delete_imported_item($sender, $act, $item, $uid, $relay) @@ -2506,7 +2553,8 @@ class Libzot // we may have stored either the object id or the activity id if it was a response activity (like, dislike, etc.) - $r = q("select * from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) + $r = q( + "select * from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) and mid in ('%s','%s') and uid = %d limit 1", dbesc($sender), dbesc($sender), @@ -2526,7 +2574,6 @@ class Libzot } else { // this will fail with an ownership issue, so explain the real reason logger('delete received for non-existent item or not owned by sender - ignoring.'); - } if ($ownership_valid === false) { @@ -2535,13 +2582,15 @@ class Libzot } if ($stored['resource_type'] === 'event') { - $i = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $i = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($stored['resource_id']), intval($uid) ); if ($i) { if ($i[0]['event_xchan'] === $sender) { - q("delete from event where event_hash = '%s' and uid = %d", + q( + "delete from event where event_hash = '%s' and uid = %d", dbesc($stored['resource_id']), intval($uid) ); @@ -2566,14 +2615,16 @@ class Libzot // this information from the metadata should have no other discernible impact. if (($stored['id'] != $stored['parent']) && intval($stored['item_origin'])) { - q("update item set item_origin = 0 where id = %d and uid = %d", + q( + "update item set item_origin = 0 where id = %d and uid = %d", intval($stored['id']), intval($stored['uid']) ); } } else { if ($stored['id'] !== $stored['parent']) { - q("update item set commented = '%s', changed = '%s' where id = %d", + q( + "update item set commented = '%s', changed = '%s' where id = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($stored['parent']) @@ -2607,7 +2658,8 @@ class Libzot logger('process_profile_delivery', LOGGER_DEBUG); - $r = q("select xchan_addr from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select xchan_addr from xchan where xchan_hash = '%s' limit 1", dbesc($sender['hash']) ); if ($r) { @@ -2630,7 +2682,8 @@ class Libzot // deliveries is irrelevant logger('process_location_delivery', LOGGER_DEBUG); - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); if ($r) { @@ -2680,7 +2733,8 @@ class Libzot $loc = $locations[0]; - $r = q("select * from channel where channel_hash = '%s' limit 1", + $r = q( + "select * from channel where channel_hash = '%s' limit 1", dbesc($sender_hash) ); @@ -2689,7 +2743,8 @@ class Libzot } if ($loc['url'] !== z_root()) { - $x = q("update channel set channel_moved = '%s' where channel_hash = '%s' limit 1", + $x = q( + "update channel set channel_moved = '%s' where channel_hash = '%s' limit 1", dbesc($loc['url']), dbesc($sender_hash) ); @@ -2729,7 +2784,6 @@ class Libzot if ($x && count($x)) { foreach ($x as $hub) { - // if this is a local channel that has been deleted, the hubloc is no good // - make sure it is marked deleted so that nobody tries to use it. @@ -2761,7 +2815,7 @@ class Libzot * * @param array $arr * @param string $pubkey - * @return boolean true if updated or inserted + * @return bool true if updated or inserted */ public static function import_site($arr) @@ -2779,7 +2833,8 @@ class Libzot $update = false; $exists = false; - $r = q("select * from site where site_url = '%s' limit 1", + $r = q( + "select * from site where site_url = '%s' limit 1", dbesc($arr['url']) ); if ($r) { @@ -2836,8 +2891,9 @@ class Libzot if ($access_policy != ACCESS_PRIVATE) { $x = z_fetch_url($arr['url'] . '/siteinfo.json'); - if (!$x['success']) + if (!$x['success']) { $access_policy = ACCESS_PRIVATE; + } } $site_about = EMPTY_STR; @@ -2875,7 +2931,8 @@ class Libzot } if ($exists) { - if (($siterecord['site_flags'] != $site_flags) + if ( + ($siterecord['site_flags'] != $site_flags) || ($siterecord['site_access'] != $access_policy) || ($siterecord['site_directory'] != $directory_url) || ($siterecord['site_sellpage'] != $sellpage) @@ -2884,14 +2941,15 @@ class Libzot || ($siterecord['site_project'] != $site_project) || ($siterecord['site_realm'] != $site_realm) || ($siterecord['site_crypto'] != $site_crypto) - || ($siterecord['site_version'] != $site_version)) { - + || ($siterecord['site_version'] != $site_version) + ) { $update = true; - // logger('import_site: input: ' . print_r($arr,true)); - // logger('import_site: stored: ' . print_r($siterecord,true)); + // logger('import_site: input: ' . print_r($arr,true)); + // logger('import_site: stored: ' . print_r($siterecord,true)); - $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s', site_version = '%s', site_crypto = '%s' + $r = q( + "update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s', site_version = '%s', site_crypto = '%s' where site_url = '%s'", dbesc($site_location), intval($site_flags), @@ -2912,7 +2970,8 @@ class Libzot } } else { // update the timestamp to indicate we communicated with this site - q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'", + q( + "update site set site_dead = 0, site_update = '%s' where site_url = '%s'", dbesc(datetime_convert()), dbesc($url) ); @@ -2970,7 +3029,7 @@ class Libzot * @brief * * @param array $x - * @return boolean|string return false or a hash + * @return bool|string return false or a hash */ public static function import_author_zot($x) @@ -2990,7 +3049,8 @@ class Libzot $found_primary = false; - $r1 = q("select hubloc_url, hubloc_updated, site_dead from hubloc left join site on + $r1 = q( + "select hubloc_url, hubloc_updated, site_dead from hubloc left join site on hubloc_url = site_url where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1", dbesc($x['id']), dbesc($x['id_sig']) @@ -2999,7 +3059,8 @@ class Libzot $found_primary = true; } - $r2 = q("select xchan_hash from xchan where xchan_guid = '%s' and xchan_guid_sig = '%s' limit 1", + $r2 = q( + "select xchan_hash from xchan where xchan_guid = '%s' and xchan_guid_sig = '%s' limit 1", dbesc($x['id']), dbesc($x['id_sig']) ); @@ -3028,7 +3089,8 @@ class Libzot if ($primary_dead || !$found_primary) { logger('dead or site - ignoring', LOGGER_DEBUG, LOG_INFO); - $r = q("select hubloc_id_url from hubloc left join site on hubloc_url = site_url + $r = q( + "select hubloc_id_url from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and site_dead = 0", dbesc($hash) ); @@ -3065,13 +3127,13 @@ class Libzot $feed = ((x($arr, 'feed')) ? intval($arr['feed']) : 0); if ($ztarget) { - $t = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $t = q( + "select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($ztarget) ); if ($t) { $ztarget_hash = $t[0]['hubloc_hash']; } else { - // should probably perform discovery of the requestor (target) but if they actually had // permissions we would know about them and we only want to know who they are to // enumerate their specific permissions @@ -3083,19 +3145,22 @@ class Libzot $r = null; if (strlen($zhash)) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_hash = '%s' limit 1", dbesc($zhash) ); } elseif (strlen($zguid) && strlen($zguid_sig)) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_guid = '%s' and channel_guid_sig = '%s' limit 1", dbesc($zguid), dbesc($zguid_sig) ); } elseif (strlen($zaddr)) { if (strpos($zaddr, '[system]') === false) { /* normal address lookup */ - $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1", dbesc($zaddr), dbesc($zaddr) @@ -3154,16 +3219,17 @@ class Libzot $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; // This is for birthdays and keywords, but must check access permissions - $p = q("select * from profile where uid = %d and is_default = 1", + $p = q( + "select * from profile where uid = %d and is_default = 1", intval($e['channel_id']) ); $profile = []; if ($p) { - - if (!intval($p[0]['publish'])) + if (!intval($p[0]['publish'])) { $searchable = false; + } $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; @@ -3272,7 +3338,8 @@ class Libzot if ($ztarget_hash) { $permissions['connected'] = false; - $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + $b = q( + "select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($ztarget_hash), intval($e['channel_id']) ); @@ -3311,7 +3378,6 @@ class Libzot call_hooks('zotinfo', $ret); return ($ret); - } @@ -3353,7 +3419,6 @@ class Libzot // hide detailed site information if you're off the grid if ($dirmode != DIRECTORY_MODE_STANDALONE || $force) { - $register_policy = intval(get_config('system', 'register_policy')); if ($register_policy == REGISTER_CLOSED) { @@ -3406,7 +3471,6 @@ class Libzot } return $ret['site']; - } /** @@ -3422,19 +3486,18 @@ class Libzot { if ($site_id) { - /* - * This hub has now been proven to be valid. - * Any hub with the same URL and a different sitekey cannot be valid. - * Get rid of them (mark them deleted). There's a good chance they were re-installs. - */ + * This hub has now been proven to be valid. + * Any hub with the same URL and a different sitekey cannot be valid. + * Get rid of them (mark them deleted). There's a good chance they were re-installs. + */ - q("update hubloc set hubloc_deleted = 1, hubloc_error = 1 where hubloc_hash = '%s' and hubloc_url = '%s' and hubloc_site_id != '%s' ", + q( + "update hubloc set hubloc_deleted = 1, hubloc_error = 1 where hubloc_hash = '%s' and hubloc_url = '%s' and hubloc_site_id != '%s' ", dbesc($hub['hubloc_hash']), dbesc($hub['hubloc_url']), dbesc($site_id) ); - } else { $site_id = $hub['hubloc_site_id']; } @@ -3448,7 +3511,8 @@ class Libzot $t = datetime_convert('UTC', 'UTC', 'now - 15 minutes'); - $r = q("update hubloc set hubloc_connected = '%s' where hubloc_id = %d and hubloc_site_id = '%s' and hubloc_connected < '%s' ", + $r = q( + "update hubloc set hubloc_connected = '%s' where hubloc_id = %d and hubloc_site_id = '%s' and hubloc_connected < '%s' ", dbesc(datetime_convert()), intval($hub['hubloc_id']), dbesc($site_id), @@ -3458,23 +3522,27 @@ class Libzot // a dead hub came back to life - reset any tombstones we might have if (intval($hub['hubloc_error']) || intval($hub['hubloc_deleted'])) { - q("update hubloc set hubloc_error = 0, hubloc_deleted = 0 where hubloc_id = %d and hubloc_site_id = '%s' ", + q( + "update hubloc set hubloc_error = 0, hubloc_deleted = 0 where hubloc_id = %d and hubloc_site_id = '%s' ", intval($hub['hubloc_id']), dbesc($site_id) ); if (intval($hub['hubloc_orphancheck'])) { - q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d and hubloc_site_id = '%s' ", + q( + "update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d and hubloc_site_id = '%s' ", intval($hub['hubloc_id']), dbesc($site_id) ); } - q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", + q( + "update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", dbesc($hub['hubloc_hash']) ); } // this site obviously isn't dead because they are trying to communicate with us. - q("update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", + q( + "update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", dbesc($hub['hubloc_url']) ); @@ -3546,5 +3614,4 @@ class Libzot } self::refresh(['hubloc_id_url' => $hubloc['hubloc_id_url']]); } - } diff --git a/Zotlabs/Lib/Libzotdir.php b/Zotlabs/Lib/Libzotdir.php index e9d9eff8a..7414ee4d5 100644 --- a/Zotlabs/Lib/Libzotdir.php +++ b/Zotlabs/Lib/Libzotdir.php @@ -39,8 +39,9 @@ class Libzotdir } } - if (!$isadir) + if (!$isadir) { set_config('system', 'directory_server', ''); + } } @@ -48,10 +49,11 @@ class Libzotdir { - if ($observer) + if ($observer) { $ret = get_xconfig($observer, 'directory', $setting); - else + } else { $ret = ((array_key_exists($setting, $_SESSION)) ? intval($_SESSION[$setting]) : false); + } if ($ret === false) { $ret = get_config('directory', $setting); @@ -60,8 +62,9 @@ class Libzotdir } } - if ($setting === 'globaldir' && intval(get_config('system', 'localdir_hide'))) + if ($setting === 'globaldir' && intval(get_config('system', 'localdir_hide'))) { $ret = 1; + } return $ret; } @@ -116,7 +119,7 @@ class Libzotdir '$forumsurl' => $forumsurl, '$safemode' => array('safemode', t('Safe Mode'), $safe_mode, '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''), '$pubforums' => array('pubforums', t('Groups Only'), (($pubforums == 1) ? true : false), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 1 : 0)\''), -// '$collections' => array('collections', t('Collections Only'),(($pubforums == 2) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 2 : 0)\''), +// '$collections' => array('collections', t('Collections Only'),(($pubforums == 2) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 2 : 0)\''), '$hide_local' => $hide_local, '$globaldir' => array('globaldir', t('This Website Only'), 1 - intval($globaldir), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''), '$activedir' => array('activedir', t('Recently Updated'), intval($activedir), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&active="+(this.checked ? 1 : 0)\''), @@ -153,7 +156,8 @@ class Libzotdir if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) { $xc = Libzot::import_xchan($zf['data'], 0, $ud); } else { - q("update updates set ud_last = '%s' where ud_addr = '%s'", + q( + "update updates set ud_last = '%s' where ud_addr = '%s'", dbesc(datetime_convert()), dbesc($ud['ud_addr']) ); @@ -178,7 +182,8 @@ class Libzotdir logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG); - $p = q("select channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1", + $p = q( + "select channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1", intval($uid) ); @@ -190,8 +195,9 @@ class Libzotdir $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; - if ($age = age($p[0]['dob'], $p[0]['channel_timezone'], '')) + if ($age = age($p[0]['dob'], $p[0]['channel_timezone'], '')) { $profile['age'] = $age; + } $profile['gender'] = $p[0]['gender']; $profile['marital'] = $p[0]['marital']; @@ -207,25 +213,31 @@ class Libzotdir if ($p[0]['keywords']) { $tags = []; $k = explode(' ', $p[0]['keywords']); - if ($k) - foreach ($k as $kk) - if (trim($kk)) + if ($k) { + foreach ($k as $kk) { + if (trim($kk)) { $tags[] = trim($kk); + } + } + } - if ($tags) + if ($tags) { $profile['keywords'] = $tags; + } } $hidden = (1 - intval($p[0]['publish'])); // logger('hidden: ' . $hidden); - $r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select xchan_hidden from xchan where xchan_hash = '%s' limit 1", dbesc($p[0]['channel_hash']) ); if (intval($r[0]['xchan_hidden']) != $hidden) { - $r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'", + $r = q( + "update xchan set xchan_hidden = %d where xchan_hash = '%s'", intval($hidden), dbesc($p[0]['channel_hash']) ); @@ -240,14 +252,15 @@ class Libzotdir self::import_directory_profile($hash, $arr['profile'], $address, 0); } else { // they may have made it private - $r = q("delete from xprof where xprof_hash = '%s'", + $r = q( + "delete from xprof where xprof_hash = '%s'", dbesc($hash) ); - $r = q("delete from xtag where xtag_hash = '%s'", + $r = q( + "delete from xtag where xtag_hash = '%s'", dbesc($hash) ); } - } $ud_hash = random_string() . '@' . App::get_hostname(); @@ -270,8 +283,9 @@ class Libzotdir { logger('import_directory_profile', LOGGER_DEBUG); - if (!$hash) + if (!$hash) { return false; + } $maxlen = get_max_import_size(); @@ -315,19 +329,23 @@ class Libzotdir if (in_arrayi('nsfw', $clean) || in_arrayi('adult', $clean)) { - q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'", + q( + "update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'", dbesc($hash) ); } - $r = q("select * from xprof where xprof_hash = '%s' limit 1", + $r = q( + "select * from xprof where xprof_hash = '%s' limit 1", dbesc($hash) ); - if ($arr['xprof_age'] > 150) + if ($arr['xprof_age'] > 150) { $arr['xprof_age'] = 150; - if ($arr['xprof_age'] < 0) + } + if ($arr['xprof_age'] < 0) { $arr['xprof_age'] = 0; + } if ($r) { $update = false; @@ -339,7 +357,8 @@ class Libzotdir } } if ($update) { - q("update xprof set + q( + "update xprof set xprof_desc = '%s', xprof_dob = '%s', xprof_age = %d, @@ -377,7 +396,8 @@ class Libzotdir } else { $update = true; logger('New profile'); - q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_about, xprof_homepage, xprof_hometown, xprof_keywords, xprof_pronouns) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", + q( + "insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_about, xprof_homepage, xprof_hometown, xprof_keywords, xprof_pronouns) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($arr['xprof_hash']), dbesc($arr['xprof_desc']), dbesc($arr['xprof_dob']), @@ -417,7 +437,8 @@ class Libzotdir self::update_modtime($arr['xprof_hash'], new_uuid(), $addr, $ud_flags); } - q("update xchan set xchan_updated = '%s' where xchan_hash = '%s'", + q( + "update xchan set xchan_updated = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($arr['xprof_hash']) ); @@ -436,13 +457,15 @@ class Libzotdir { $existing = []; - $r = q("select * from xtag where xtag_hash = '%s' and xtag_flags = 0", + $r = q( + "select * from xtag where xtag_hash = '%s' and xtag_flags = 0", dbesc($hash) ); if ($r) { - foreach ($r as $rr) + foreach ($r as $rr) { $existing[] = $rr['xtag_term']; + } } $clean = []; @@ -453,15 +476,18 @@ class Libzotdir } foreach ($existing as $x) { - if (!in_array($x, $clean)) - $r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0", + if (!in_array($x, $clean)) { + $r = q( + "delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0", dbesc($hash), dbesc($x) ); + } } foreach ($clean as $x) { if (!in_array($x, $existing)) { - $r = q("insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )", + $r = q( + "insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )", dbesc($hash), dbesc($x) ); @@ -484,11 +510,13 @@ class Libzotdir $dirmode = intval(get_config('system', 'directory_mode')); - if ($dirmode == DIRECTORY_MODE_NORMAL) + if ($dirmode == DIRECTORY_MODE_NORMAL) { return; + } if ($flags) { - q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )", + q( + "insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )", dbesc($hash), dbesc($guid), dbesc(datetime_convert()), @@ -496,13 +524,12 @@ class Libzotdir dbesc($addr) ); } else { - q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and (ud_flags & %d) = 0 ", + q( + "update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and (ud_flags & %d) = 0 ", intval(UPDATE_FLAGS_UPDATED), dbesc($addr), intval(UPDATE_FLAGS_UPDATED) ); } } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Markdown.php b/Zotlabs/Lib/Markdown.php index 6aae98a66..59ae117a5 100644 --- a/Zotlabs/Lib/Markdown.php +++ b/Zotlabs/Lib/Markdown.php @@ -1,4 +1,5 @@ getTagName()) { - case 'tr': - $line = []; - $i = 1; - foreach ($element->getChildren() as $td) { - $i++; - $v = $td->getValue(); - $v = trim($v); - if ($i % 2 === 0 || $v !== '') { - $line[] = $v; - } - } - return '| ' . implode(' | ', $line) . " |\n"; - case 'td': - case 'th': - return trim($element->getValue()); - case 'tbody': - return trim($element->getValue()); - case 'thead': - $headerLine = reset($element->getChildren())->getValue(); - $headers = explode(' | ', trim(trim($headerLine, "\n"), '|')); - $hr = []; - foreach ($headers as $td) { - $length = strlen(trim($td)) + 2; - $hr[] = str_repeat('-', $length > 3 ? $length : 3); - } - $hr = '|' . implode('|', $hr) . '|'; - return $headerLine . $hr . "\n"; - case 'table': - $inner = $element->getValue(); - if (strpos($inner, '-----') === false) { - $inner = explode("\n", $inner); - $single = explode(' | ', trim($inner[0], '|')); - $hr = []; - foreach ($single as $td) { - $length = strlen(trim($td)) + 2; - $hr[] = str_repeat('-', $length > 3 ? $length : 3); - } - $hr = '|' . implode('|', $hr) . '|'; - array_splice($inner, 1, 0, $hr); - $inner = implode("\n", $inner); - } - return trim($inner) . "\n\n"; - } - return $element->getValue(); - } - /** - * @return string[] - */ - public function getSupportedTags() - { - return array('table', 'tr', 'thead', 'td', 'tbody'); - } + /** + * @param ElementInterface $element + * + * @return string + */ + public function convert(ElementInterface $element) + { + switch ($element->getTagName()) { + case 'tr': + $line = []; + $i = 1; + foreach ($element->getChildren() as $td) { + $i++; + $v = $td->getValue(); + $v = trim($v); + if ($i % 2 === 0 || $v !== '') { + $line[] = $v; + } + } + return '| ' . implode(' | ', $line) . " |\n"; + case 'td': + case 'th': + return trim($element->getValue()); + case 'tbody': + return trim($element->getValue()); + case 'thead': + $headerLine = reset($element->getChildren())->getValue(); + $headers = explode(' | ', trim(trim($headerLine, "\n"), '|')); + $hr = []; + foreach ($headers as $td) { + $length = strlen(trim($td)) + 2; + $hr[] = str_repeat('-', $length > 3 ? $length : 3); + } + $hr = '|' . implode('|', $hr) . '|'; + return $headerLine . $hr . "\n"; + case 'table': + $inner = $element->getValue(); + if (strpos($inner, '-----') === false) { + $inner = explode("\n", $inner); + $single = explode(' | ', trim($inner[0], '|')); + $hr = []; + foreach ($single as $td) { + $length = strlen(trim($td)) + 2; + $hr[] = str_repeat('-', $length > 3 ? $length : 3); + } + $hr = '|' . implode('|', $hr) . '|'; + array_splice($inner, 1, 0, $hr); + $inner = implode("\n", $inner); + } + return trim($inner) . "\n\n"; + } + return $element->getValue(); + } + /** + * @return string[] + */ + public function getSupportedTags() + { + return array('table', 'tr', 'thead', 'td', 'tbody'); + } } diff --git a/Zotlabs/Lib/MarkdownSoap.php b/Zotlabs/Lib/MarkdownSoap.php index a08ad6073..304f0cd02 100644 --- a/Zotlabs/Lib/MarkdownSoap.php +++ b/Zotlabs/Lib/MarkdownSoap.php @@ -67,7 +67,8 @@ class MarkdownSoap public function extract_code($s) { - $text = preg_replace_callback('{ + $text = preg_replace_callback( + '{ (?:\n\n|\A\n?) ( # $1 = the code block -- one or more lines, starting with a space/tab (?> @@ -77,7 +78,9 @@ class MarkdownSoap ) ((?=^[ ]{0,' . '4' . '}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }xm', - [$this, 'encode_code'], $s); + [$this, 'encode_code'], + $s + ); return $text; } diff --git a/Zotlabs/Lib/MastAPI.php b/Zotlabs/Lib/MastAPI.php index 724325169..99c5dfddc 100644 --- a/Zotlabs/Lib/MastAPI.php +++ b/Zotlabs/Lib/MastAPI.php @@ -5,27 +5,30 @@ namespace Zotlabs\Lib; use App; use Zotlabs\Lib\PConfig; - class MastAPI { public static function format_channel($channel) { - $p = q("select * from profile where uid = %d and is_default = 1", + $p = q( + "select * from profile where uid = %d and is_default = 1", intval($channel['channel_id']) ); - $a = q("select * from account where account_id = %d", + $a = q( + "select * from account where account_id = %d", intval($channel['channel_account_id']) ); - $followers = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 ", + $followers = q( + "select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 ", intval($channel['channel_id']), intval($channel['channel_id']), dbesc($channel['channel_hash']) ); - $following = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'my_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0", + $following = q( + "select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'my_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0", intval($channel['channel_id']), intval($channel['channel_id']), dbesc($channel['channel_hash']) @@ -36,7 +39,8 @@ class MastAPI $item_normal = item_normal(); // count posts/comments - $statuses = q("SELECT COUNT(id) as total FROM item + $statuses = q( + "SELECT COUNT(id) as total FROM item WHERE uid = %d AND author_xchan = '%s' $item_normal ", intval($channel['channel_id']), @@ -100,7 +104,5 @@ class MastAPI $ret['contact_account'] = self::format_channel($adminsx); return $ret; - } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/MessageFilter.php b/Zotlabs/Lib/MessageFilter.php index f6c6c6c30..b7f267b1d 100644 --- a/Zotlabs/Lib/MessageFilter.php +++ b/Zotlabs/Lib/MessageFilter.php @@ -2,89 +2,94 @@ namespace Zotlabs\Lib; +class MessageFilter +{ -class MessageFilter { + public static function evaluate($item, $incl, $excl) + { + require_once('include/html2plain.php'); - public static function evaluate($item, $incl, $excl) { + $text = prepare_text($item['body'], ((isset($item['mimetype'])) ? $item['mimetype'] : 'text/bbcode')); + $text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text); - require_once('include/html2plain.php'); + $lang = null; - $text = prepare_text($item['body'],((isset($item['mimetype'])) ? $item['mimetype'] : 'text/bbcode')); - $text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text); + if ((strpos($incl, 'lang=') !== false) || (strpos($excl, 'lang=') !== false) || (strpos($incl, 'lang!=') !== false) || (strpos($excl, 'lang!=') !== false)) { + $lang = detect_language($text); + } - $lang = null; + $tags = ((isset($item['term']) && is_array($item['term']) && count($item['term'])) ? $item['term'] : false); - if((strpos($incl,'lang=') !== false) || (strpos($excl,'lang=') !== false) || (strpos($incl,'lang!=') !== false) || (strpos($excl,'lang!=') !== false)) { - $lang = detect_language($text); - } + // exclude always has priority - $tags = ((isset($item['term']) && is_array($item['term']) && count($item['term'])) ? $item['term'] : false); + $exclude = (($excl) ? explode("\n", $excl) : null); - // exclude always has priority + if ($exclude) { + foreach ($exclude as $word) { + $word = trim($word); + if (! $word) { + continue; + } + if (substr($word, 0, 1) === '#' && $tags) { + foreach ($tags as $t) { + if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) { + return false; + } + } + } elseif (substr($word, 0, 1) === '$' && $tags) { + foreach ($tags as $t) { + if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) { + return false; + } + } + } elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) { + return false; + } elseif ((strpos($word, 'lang=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 5))) == 0)) { + return false; + } elseif ((strpos($word, 'lang!=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 6))) != 0)) { + return false; + } elseif (stristr($text, $word) !== false) { + return false; + } + } + } - $exclude = (($excl) ? explode("\n",$excl) : null); - - if($exclude) { - foreach($exclude as $word) { - $word = trim($word); - if(! $word) - continue; - if(substr($word,0,1) === '#' && $tags) { - foreach($tags as $t) - if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) - return false; - } - elseif(substr($word,0,1) === '$' && $tags) { - foreach($tags as $t) - if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) - return false; - } - elseif((strpos($word,'/') === 0) && preg_match($word,$text)) - return false; - elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0)) - return false; - elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0)) - return false; - elseif(stristr($text,$word) !== false) - return false; - } - } - - $include = (($incl) ? explode("\n",$incl) : null); - - if($include) { - foreach($include as $word) { - $word = trim($word); - if(! $word) - continue; - if(substr($word,0,1) === '#' && $tags) { - foreach($tags as $t) - if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) - return true; - } - elseif(substr($word,0,1) === '$' && $tags) { - foreach($tags as $t) - if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) - return true; - } - elseif((strpos($word,'/') === 0) && preg_match($word,$text)) - return true; - elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0)) - return true; - elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0)) - return true; - elseif(stristr($text,$word) !== false) - return true; - } - } - else { - return true; - } - - return false; - } + $include = (($incl) ? explode("\n", $incl) : null); + if ($include) { + foreach ($include as $word) { + $word = trim($word); + if (! $word) { + continue; + } + if (substr($word, 0, 1) === '#' && $tags) { + foreach ($tags as $t) { + if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) { + return true; + } + } + } elseif (substr($word, 0, 1) === '$' && $tags) { + foreach ($tags as $t) { + if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) { + return true; + } + } + } elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) { + return true; + } elseif ((strpos($word, 'lang=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 5))) == 0)) { + return true; + } elseif ((strpos($word, 'lang!=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 6))) != 0)) { + return true; + } elseif (stristr($text, $word) !== false) { + return true; + } + } + } else { + return true; + } + return false; + } } diff --git a/Zotlabs/Lib/Nodeinfo.php b/Zotlabs/Lib/Nodeinfo.php index 128bb5261..65d5c78a5 100644 --- a/Zotlabs/Lib/Nodeinfo.php +++ b/Zotlabs/Lib/Nodeinfo.php @@ -2,43 +2,40 @@ namespace Zotlabs\Lib; +class Nodeinfo +{ - -class Nodeinfo { - - public static function fetch($url) { - $href = EMPTY_STR; - $m = parse_url($url); - if ($m['scheme'] && $m['host']) { - $s = $m['scheme'] . '://' . $m['host'] . '/.well-known/nodeinfo'; - $n = z_fetch_url($s); - if ($n['success']) { - $j = json_decode($n['body'], true); - if ($j && $j['links']) { - // lemmy just sends one result - if (isset($j['links']['rel'])) { - if ($j['links']['rel'] === 'http://nodeinfo.diaspora.software/ns/schema/2.0' && isset($j['links']['href'])) { - $href = $j['links']['href']; - } - } - else { - foreach ($j['links'] as $l) { - if (isset($l['rel']) && $l['rel'] === 'http://nodeinfo.diaspora.software/ns/schema/2.0' && isset($l['href'])) { - $href = $l['href']; - } - } - } - } - } - } - if ($href) { - $n = z_fetch_url($href); - if ($n['success']) { - return json_decode($n['body'],true); - } - } - return []; - - } - -} \ No newline at end of file + public static function fetch($url) + { + $href = EMPTY_STR; + $m = parse_url($url); + if ($m['scheme'] && $m['host']) { + $s = $m['scheme'] . '://' . $m['host'] . '/.well-known/nodeinfo'; + $n = z_fetch_url($s); + if ($n['success']) { + $j = json_decode($n['body'], true); + if ($j && $j['links']) { + // lemmy just sends one result + if (isset($j['links']['rel'])) { + if ($j['links']['rel'] === 'http://nodeinfo.diaspora.software/ns/schema/2.0' && isset($j['links']['href'])) { + $href = $j['links']['href']; + } + } else { + foreach ($j['links'] as $l) { + if (isset($l['rel']) && $l['rel'] === 'http://nodeinfo.diaspora.software/ns/schema/2.0' && isset($l['href'])) { + $href = $l['href']; + } + } + } + } + } + } + if ($href) { + $n = z_fetch_url($href); + if ($n['success']) { + return json_decode($n['body'], true); + } + } + return []; + } +} diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php index 0745080b0..b456be5ca 100644 --- a/Zotlabs/Lib/PConfig.php +++ b/Zotlabs/Lib/PConfig.php @@ -18,193 +18,212 @@ use App; * The old (deprecated?) way to access a PConfig value is: * @code{.php}$var = get_pconfig(local_channel(), 'category', 'key');@endcode */ -class PConfig { +class PConfig +{ - /** - * @brief Loads all configuration values of a channel into a cached storage. - * - * All configuration values of the given channel are stored in global cache - * which is available under the global variable App::$config[$uid]. - * - * @param string $uid - * The channel_id - * @return void|false Nothing or false if $uid is null or false - */ - public static function Load($uid) { - if(is_null($uid) || $uid === false) - return false; + /** + * @brief Loads all configuration values of a channel into a cached storage. + * + * All configuration values of the given channel are stored in global cache + * which is available under the global variable App::$config[$uid]. + * + * @param string $uid + * The channel_id + * @return void|false Nothing or false if $uid is null or false + */ + public static function Load($uid) + { + if (is_null($uid) || $uid === false) { + return false; + } - if(! is_array(App::$config)) { - btlogger('App::$config not an array'); - } + if (! is_array(App::$config)) { + btlogger('App::$config not an array'); + } - if(! array_key_exists($uid, App::$config)) { - App::$config[$uid] = []; - } + if (! array_key_exists($uid, App::$config)) { + App::$config[$uid] = []; + } - if(! is_array(App::$config[$uid])) { - btlogger('App::$config[$uid] not an array: ' . $uid); - } + if (! is_array(App::$config[$uid])) { + btlogger('App::$config[$uid] not an array: ' . $uid); + } - $r = q("SELECT * FROM pconfig WHERE uid = %d", - intval($uid) - ); + $r = q( + "SELECT * FROM pconfig WHERE uid = %d", + intval($uid) + ); - if($r) { - foreach($r as $rr) { - $k = $rr['k']; - $c = $rr['cat']; - if(! array_key_exists($c, App::$config[$uid])) { - App::$config[$uid][$c] = []; - App::$config[$uid][$c]['config_loaded'] = true; - } - App::$config[$uid][$c][$k] = $rr['v']; - } - } - } + if ($r) { + foreach ($r as $rr) { + $k = $rr['k']; + $c = $rr['cat']; + if (! array_key_exists($c, App::$config[$uid])) { + App::$config[$uid][$c] = []; + App::$config[$uid][$c]['config_loaded'] = true; + } + App::$config[$uid][$c][$k] = $rr['v']; + } + } + } - /** - * @brief Get a particular channel's config variable given the category name - * ($family) and a key. - * - * Get a particular channel's config value from the given category ($family) - * and the $key from a cached storage in App::$config[$uid]. - * - * Returns false if not set. - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @param mixed $default (optional, default false) - * Default value to return if key does not exist - * @return mixed Stored value or false if it does not exist - */ - public static function Get($uid, $family, $key, $default = false) { + /** + * @brief Get a particular channel's config variable given the category name + * ($family) and a key. + * + * Get a particular channel's config value from the given category ($family) + * and the $key from a cached storage in App::$config[$uid]. + * + * Returns false if not set. + * + * @param string $uid + * The channel_id + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to query + * @param mixed $default (optional, default false) + * Default value to return if key does not exist + * @return mixed Stored value or false if it does not exist + */ + public static function Get($uid, $family, $key, $default = false) + { - if(is_null($uid) || $uid === false) - return $default; + if (is_null($uid) || $uid === false) { + return $default; + } - if(! array_key_exists($uid, App::$config)) - self::Load($uid); + if (! array_key_exists($uid, App::$config)) { + self::Load($uid); + } - if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family]))) - return $default; + if ((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family]))) { + return $default; + } - return unserialise(App::$config[$uid][$family][$key]); - } + return unserialise(App::$config[$uid][$family][$key]); + } - /** - * @brief Sets a configuration value for a channel. - * - * Stores a config value ($value) in the category ($family) under the key ($key) - * for the channel_id $uid. - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to set - * @param string $value - * The value to store - * @return mixed Stored $value or false - */ - public static function Set($uid, $family, $key, $value) { + /** + * @brief Sets a configuration value for a channel. + * + * Stores a config value ($value) in the category ($family) under the key ($key) + * for the channel_id $uid. + * + * @param string $uid + * The channel_id + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to set + * @param string $value + * The value to store + * @return mixed Stored $value or false + */ + public static function Set($uid, $family, $key, $value) + { - // this catches subtle errors where this function has been called - // with local_channel() when not logged in (which returns false) - // and throws an error in array_key_exists below. - // we provide a function backtrace in the logs so that we can find - // and fix the calling function. + // this catches subtle errors where this function has been called + // with local_channel() when not logged in (which returns false) + // and throws an error in array_key_exists below. + // we provide a function backtrace in the logs so that we can find + // and fix the calling function. - if(is_null($uid) || $uid === false) { - btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR); - return; - } + if (is_null($uid) || $uid === false) { + btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR); + return; + } - // manage array value - $dbvalue = ((is_array($value)) ? serialise($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + // manage array value + $dbvalue = ((is_array($value)) ? serialise($value) : $value); + $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - if(self::Get($uid, $family, $key) === false) { - if(! array_key_exists($uid, App::$config)) - App::$config[$uid] = []; - if(! array_key_exists($family, App::$config[$uid])) - App::$config[$uid][$family] = []; + if (self::Get($uid, $family, $key) === false) { + if (! array_key_exists($uid, App::$config)) { + App::$config[$uid] = []; + } + if (! array_key_exists($family, App::$config[$uid])) { + App::$config[$uid][$family] = []; + } - $ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", - intval($uid), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - } - else { + $ret = q( + "INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", + intval($uid), + dbesc($family), + dbesc($key), + dbesc($dbvalue) + ); + } else { + $ret = q( + "UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", + dbesc($dbvalue), + intval($uid), + dbesc($family), + dbesc($key) + ); + } - $ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", - dbesc($dbvalue), - intval($uid), - dbesc($family), - dbesc($key) - ); - } + // keep a separate copy for all variables which were + // set in the life of this page. We need this to + // synchronise channel clones. - // keep a separate copy for all variables which were - // set in the life of this page. We need this to - // synchronise channel clones. + if (! array_key_exists('transient', App::$config[$uid])) { + App::$config[$uid]['transient'] = []; + } + if (! array_key_exists($family, App::$config[$uid]['transient'])) { + App::$config[$uid]['transient'][$family] = []; + } - if(! array_key_exists('transient', App::$config[$uid])) - App::$config[$uid]['transient'] = []; - if(! array_key_exists($family, App::$config[$uid]['transient'])) - App::$config[$uid]['transient'][$family] = []; + App::$config[$uid][$family][$key] = $value; + App::$config[$uid]['transient'][$family][$key] = $value; - App::$config[$uid][$family][$key] = $value; - App::$config[$uid]['transient'][$family][$key] = $value; + if ($ret) { + return $value; + } - if($ret) - return $value; - - return $ret; - } + return $ret; + } - /** - * @brief Deletes the given key from the channel's configuration. - * - * Removes the configured value from the stored cache in App::$config[$uid] - * and removes it from the database. - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to delete - * @return mixed - */ - public static function Delete($uid, $family, $key) { + /** + * @brief Deletes the given key from the channel's configuration. + * + * Removes the configured value from the stored cache in App::$config[$uid] + * and removes it from the database. + * + * @param string $uid + * The channel_id + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to delete + * @return mixed + */ + public static function Delete($uid, $family, $key) + { - if(is_null($uid) || $uid === false) - return false; + if (is_null($uid) || $uid === false) { + return false; + } - $ret = false; + $ret = false; - if(array_key_exists($uid, App::$config) - && is_array(App::$config['uid']) - && array_key_exists($family, App::$config['uid']) - && array_key_exists($key, App::$config[$uid][$family])) - unset(App::$config[$uid][$family][$key]); + if ( + array_key_exists($uid, App::$config) + && is_array(App::$config['uid']) + && array_key_exists($family, App::$config['uid']) + && array_key_exists($key, App::$config[$uid][$family]) + ) { + unset(App::$config[$uid][$family][$key]); + } - $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", - intval($uid), - dbesc($family), - dbesc($key) - ); - - return $ret; - } + $ret = q( + "DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", + intval($uid), + dbesc($family), + dbesc($key) + ); + return $ret; + } } diff --git a/Zotlabs/Lib/Permcat.php b/Zotlabs/Lib/Permcat.php index e0805c147..c94061586 100644 --- a/Zotlabs/Lib/Permcat.php +++ b/Zotlabs/Lib/Permcat.php @@ -21,157 +21,168 @@ use Zotlabs\Access\Permissions; * These answer the question "Can Joe view *this* album/photo?". */ -class Permcat { +class Permcat +{ - /** - * @var array - */ - private $permcats = []; + /** + * @var array + */ + private $permcats = []; - /** - * @brief Permcat constructor. - * - * @param int $channel_id - */ - public function __construct($channel_id) { + /** + * @brief Permcat constructor. + * + * @param int $channel_id + */ + public function __construct($channel_id) + { - $perms = []; + $perms = []; - // first check role perms for a perms_connect setting + // first check role perms for a perms_connect setting - $role = get_pconfig($channel_id,'system','permissions_role'); - if($role) { - $x = PermissionRoles::role_perms($role); - if($x['perms_connect']) { - $perms = Permissions::FilledPerms($x['perms_connect']); - } - } + $role = get_pconfig($channel_id, 'system', 'permissions_role'); + if ($role) { + $x = PermissionRoles::role_perms($role); + if ($x['perms_connect']) { + $perms = Permissions::FilledPerms($x['perms_connect']); + } + } - // if no role perms it may be a custom role, see if there any autoperms + // if no role perms it may be a custom role, see if there any autoperms - if(! $perms) { - $perms = Permissions::FilledAutoPerms($channel_id); - } + if (! $perms) { + $perms = Permissions::FilledAutoPerms($channel_id); + } - // if no autoperms it may be a custom role with manual perms + // if no autoperms it may be a custom role with manual perms - if(! $perms) { - $c = channelx_by_n($channel_id); - if($c) { - $perms = Permissions::FilledPerms(get_abconfig($channel_id,$c['channel_hash'],'system','my_perms',EMPTY_STR)); - } - } + if (! $perms) { + $c = channelx_by_n($channel_id); + if ($c) { + $perms = Permissions::FilledPerms(get_abconfig($channel_id, $c['channel_hash'], 'system', 'my_perms', EMPTY_STR)); + } + } - // nothing was found - create a filled permission array where all permissions are 0 + // nothing was found - create a filled permission array where all permissions are 0 - if(! $perms) { - $perms = Permissions::FilledPerms([]); - } + if (! $perms) { + $perms = Permissions::FilledPerms([]); + } - $this->permcats[] = [ - 'name' => 'default', - 'localname' => t('default','permcat'), - 'perms' => Permissions::Operms($perms), - 'system' => 1 - ]; + $this->permcats[] = [ + 'name' => 'default', + 'localname' => t('default', 'permcat'), + 'perms' => Permissions::Operms($perms), + 'system' => 1 + ]; - $p = $this->load_permcats($channel_id); - if($p) { - for($x = 0; $x < count($p); $x++) { - $this->permcats[] = [ - 'name' => $p[$x][0], - 'localname' => $p[$x][1], - 'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])), - 'system' => intval($p[$x][3]) - ]; - } - } - } + $p = $this->load_permcats($channel_id); + if ($p) { + for ($x = 0; $x < count($p); $x++) { + $this->permcats[] = [ + 'name' => $p[$x][0], + 'localname' => $p[$x][1], + 'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])), + 'system' => intval($p[$x][3]) + ]; + } + } + } - /** - * @brief Return array with permcats. - * - * @return array - */ - public function listing() { - return $this->permcats; - } + /** + * @brief Return array with permcats. + * + * @return array + */ + public function listing() + { + return $this->permcats; + } - /** - * @brief - * - * @param string $name - * @return array - * * \e array with permcats - * * \e bool \b error if $name not found in permcats true - */ - public function fetch($name) { - if($name && $this->permcats) { - foreach($this->permcats as $permcat) { - if(strcasecmp($permcat['name'], $name) === 0) { - return $permcat; - } - } - } + /** + * @brief + * + * @param string $name + * @return array + * * \e array with permcats + * * \e bool \b error if $name not found in permcats true + */ + public function fetch($name) + { + if ($name && $this->permcats) { + foreach ($this->permcats as $permcat) { + if (strcasecmp($permcat['name'], $name) === 0) { + return $permcat; + } + } + } - return ['error' => true]; - } + return ['error' => true]; + } - public function load_permcats($uid) { + public function load_permcats($uid) + { - $permcats = [ - [ 'follower', t('follower','permcat'), - [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', - 'post_like' ], 1 - ], - [ 'contributor', t('contributor','permcat'), - [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', - 'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1 - ], - [ 'publisher', t('publisher','permcat'), - [ 'view_stream','view_profile','view_contacts','view_storage','view_pages', - 'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver', - 'chat', 'republish' ], 1 - ] - ]; + $permcats = [ + [ 'follower', t('follower', 'permcat'), + [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', + 'post_like' ], 1 + ], + [ 'contributor', t('contributor', 'permcat'), + [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', + 'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1 + ], + [ 'publisher', t('publisher', 'permcat'), + [ 'view_stream','view_profile','view_contacts','view_storage','view_pages', + 'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver', + 'chat', 'republish' ], 1 + ] + ]; - if($uid) { - $x = q("select * from pconfig where uid = %d and cat = 'permcat'", - intval($uid) - ); - if($x) { - foreach($x as $xv) { - $value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']); - $permcats[] = [ $xv['k'], $xv['k'], $value, 0 ]; - } - } - } + if ($uid) { + $x = q( + "select * from pconfig where uid = %d and cat = 'permcat'", + intval($uid) + ); + if ($x) { + foreach ($x as $xv) { + $value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']); + $permcats[] = [ $xv['k'], $xv['k'], $value, 0 ]; + } + } + } - /** - * @hooks permcats - * * \e array - */ - call_hooks('permcats', $permcats); + /** + * @hooks permcats + * * \e array + */ + call_hooks('permcats', $permcats); - return $permcats; - } + return $permcats; + } - public static function find_permcat($arr, $name) { - if((! $arr) || (! $name)) - return false; + public static function find_permcat($arr, $name) + { + if ((! $arr) || (! $name)) { + return false; + } - foreach($arr as $p) - if($p['name'] == $name) - return $p['value']; - } + foreach ($arr as $p) { + if ($p['name'] == $name) { + return $p['value']; + } + } + } - public static function update($channel_id, $name, $permarr) { - PConfig::Set($channel_id, 'permcat', $name, $permarr); - } + public static function update($channel_id, $name, $permarr) + { + PConfig::Set($channel_id, 'permcat', $name, $permarr); + } - public static function delete($channel_id, $name) { - PConfig::Delete($channel_id, 'permcat', $name); - } - -} \ No newline at end of file + public static function delete($channel_id, $name) + { + PConfig::Delete($channel_id, 'permcat', $name); + } +} diff --git a/Zotlabs/Lib/PermissionDescription.php b/Zotlabs/Lib/PermissionDescription.php index 101a22b39..58d2ee7f3 100644 --- a/Zotlabs/Lib/PermissionDescription.php +++ b/Zotlabs/Lib/PermissionDescription.php @@ -16,148 +16,178 @@ require_once("include/text.php"); * permission settings for an item with an empty ACL. * i.e the caption, icon, and tooltip for the no-ACL option in the ACL dialog. */ -class PermissionDescription { +class PermissionDescription +{ - private $global_perm; - private $channel_perm; - private $fallback_description; + private $global_perm; + private $channel_perm; + private $fallback_description; - /** - * Constructor is private. - * Use static methods fromGlobalPermission(), fromStandalonePermission(), - * or fromDescription() to create instances. - * - * @internal - * @param int $global_perm - * @param int $channel_perm - * @param string $description (optional) default empty - */ - private function __construct($global_perm, $channel_perm, $description = '') { - $this->global_perm = $global_perm; - $this->channel_perm = $channel_perm; - $this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description; - } + /** + * Constructor is private. + * Use static methods fromGlobalPermission(), fromStandalonePermission(), + * or fromDescription() to create instances. + * + * @internal + * @param int $global_perm + * @param int $channel_perm + * @param string $description (optional) default empty + */ + private function __construct($global_perm, $channel_perm, $description = '') + { + $this->global_perm = $global_perm; + $this->channel_perm = $channel_perm; + $this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description; + } - /** - * If the interpretation of an empty ACL can't be summarised with a global default permission - * or a specific permission setting then use this method and describe what it means instead. - * Remember to localize the description first. - * - * @param string $description - the localized caption for the no-ACL option in the ACL dialog. - * @return a new instance of PermissionDescription - */ - public static function fromDescription($description) { - return new PermissionDescription('', 0x80000, $description); - } + /** + * If the interpretation of an empty ACL can't be summarised with a global default permission + * or a specific permission setting then use this method and describe what it means instead. + * Remember to localize the description first. + * + * @param string $description - the localized caption for the no-ACL option in the ACL dialog. + * @return a new instance of PermissionDescription + */ + public static function fromDescription($description) + { + return new PermissionDescription('', 0x80000, $description); + } - /** - * Use this method only if the interpretation of an empty ACL doesn't fall back to a global - * default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC, - * PERMS_NETWORK etc. - * - * @param int $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc. - * @return a new instance of PermissionDescription - */ - public static function fromStandalonePermission($perm) { + /** + * Use this method only if the interpretation of an empty ACL doesn't fall back to a global + * default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC, + * PERMS_NETWORK etc. + * + * @param int $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc. + * @return a new instance of PermissionDescription + */ + public static function fromStandalonePermission($perm) + { - $result = new PermissionDescription('', $perm); + $result = new PermissionDescription('', $perm); - $checkPerm = $result->get_permission_description(); - if($checkPerm == $result->fallback_description) { - $result = null; - logger('null PermissionDescription from unknown standalone permission: ' . $perm, LOGGER_DEBUG, LOG_ERR); - } + $checkPerm = $result->get_permission_description(); + if ($checkPerm == $result->fallback_description) { + $result = null; + logger('null PermissionDescription from unknown standalone permission: ' . $perm, LOGGER_DEBUG, LOG_ERR); + } - return $result; - } + return $result; + } - /** - * This is the preferred way to create a PermissionDescription, as it provides the most details. - * Use this method if you know an empty ACL will result in one of the global default permissions - * being used, such as channel_r_stream (for which you would pass 'view_stream'). - * - * @param string $permname - a key for the global perms array from get_perms() in permissions.php, - * e.g. 'view_stream', 'view_profile', etc. - * @return a new instance of PermissionDescription - */ - public static function fromGlobalPermission($permname) { + /** + * This is the preferred way to create a PermissionDescription, as it provides the most details. + * Use this method if you know an empty ACL will result in one of the global default permissions + * being used, such as channel_r_stream (for which you would pass 'view_stream'). + * + * @param string $permname - a key for the global perms array from get_perms() in permissions.php, + * e.g. 'view_stream', 'view_profile', etc. + * @return a new instance of PermissionDescription + */ + public static function fromGlobalPermission($permname) + { - $result = null; + $result = null; - $global_perms = Permissions::Perms(); + $global_perms = Permissions::Perms(); - if(array_key_exists($permname, $global_perms)) { + if (array_key_exists($permname, $global_perms)) { + $channelPerm = PermissionLimits::Get(App::$channel['channel_id'], $permname); - $channelPerm = PermissionLimits::Get(App::$channel['channel_id'], $permname); + $result = new PermissionDescription('', $channelPerm); + } else { + // The acl dialog can handle null arguments, but it shouldn't happen + logger('null PermissionDescription from unknown global permission: ' . $permname, LOGGER_DEBUG, LOG_ERR); + } - $result = new PermissionDescription('', $channelPerm); - } else { - // The acl dialog can handle null arguments, but it shouldn't happen - logger('null PermissionDescription from unknown global permission: ' . $permname, LOGGER_DEBUG, LOG_ERR); - } + return $result; + } - return $result; - } + /** + * Gets a localized description of the permission, or a generic message if the permission + * is unknown. + * + * @return string description + */ + public function get_permission_description() + { - /** - * Gets a localized description of the permission, or a generic message if the permission - * is unknown. - * - * @return string description - */ - public function get_permission_description() { + switch ($this->channel_perm) { + case 0: + return t('Only me'); + case PERMS_PUBLIC: + return t('Public'); + case PERMS_NETWORK: + return t('Anybody in the $Projectname network'); + case PERMS_SITE: + return sprintf(t('Any account on %s'), App::get_hostname()); + case PERMS_CONTACTS: + return t('Any of my connections'); + case PERMS_SPECIFIC: + return t('Only connections I specifically allow'); + case PERMS_AUTHED: + return t('Anybody authenticated (could include visitors from other networks)'); + case PERMS_PENDING: + return t('Any connections including those who haven\'t yet been approved'); + default: + return $this->fallback_description; + } + } - switch($this->channel_perm) { - case 0: return t('Only me'); - case PERMS_PUBLIC: return t('Public'); - case PERMS_NETWORK: return t('Anybody in the $Projectname network'); - case PERMS_SITE: return sprintf(t('Any account on %s'), App::get_hostname()); - case PERMS_CONTACTS: return t('Any of my connections'); - case PERMS_SPECIFIC: return t('Only connections I specifically allow'); - case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)'); - case PERMS_PENDING: return t('Any connections including those who haven\'t yet been approved'); - default: return $this->fallback_description; - } - } + /** + * Returns an icon css class name if an appropriate one is available, e.g. "fa-globe" for Public, + * otherwise returns empty string. + * + * @return string icon css class name (often FontAwesome) + */ + public function get_permission_icon() + { - /** - * Returns an icon css class name if an appropriate one is available, e.g. "fa-globe" for Public, - * otherwise returns empty string. - * - * @return string icon css class name (often FontAwesome) - */ - public function get_permission_icon() { + switch ($this->channel_perm) { + case 0: + return 'fa-eye-slash'; + case PERMS_PUBLIC: + return 'fa-globe'; + case PERMS_NETWORK: + return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use + case PERMS_SITE: + return 'fa-sitemap'; + case PERMS_CONTACTS: + return 'fa-group'; + case PERMS_SPECIFIC: + return 'fa-list'; + case PERMS_AUTHED: + return ''; + case PERMS_PENDING: + return ''; + default: + return ''; + } + } - switch($this->channel_perm) { - case 0:/* only me */ return 'fa-eye-slash'; - case PERMS_PUBLIC: return 'fa-globe'; - case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use - case PERMS_SITE: return 'fa-sitemap'; - case PERMS_CONTACTS: return 'fa-group'; - case PERMS_SPECIFIC: return 'fa-list'; - case PERMS_AUTHED: return ''; - case PERMS_PENDING: return ''; - default: return ''; - } - } - - /** - * Returns a localized description of where the permission came from, if this is known. - * If it's not know, or if the permission is standalone and didn't come from a default - * permission setting, then empty string is returned. - * - * @return string description or empty string - */ - public function get_permission_origin_description() { - - switch($this->global_perm) { - case PERMS_R_STREAM: return t('This is your default setting for the audience of your normal stream, and posts.'); - case PERMS_R_PROFILE: return t('This is your default setting for who can view your default channel profile'); - case PERMS_R_ABOOK: return t('This is your default setting for who can view your connections'); - case PERMS_R_STORAGE: return t('This is your default setting for who can view your file storage and photos'); - case PERMS_R_PAGES: return t('This is your default setting for the audience of your webpages'); - default: return ''; - } - } + /** + * Returns a localized description of where the permission came from, if this is known. + * If it's not know, or if the permission is standalone and didn't come from a default + * permission setting, then empty string is returned. + * + * @return string description or empty string + */ + public function get_permission_origin_description() + { + switch ($this->global_perm) { + case PERMS_R_STREAM: + return t('This is your default setting for the audience of your normal stream, and posts.'); + case PERMS_R_PROFILE: + return t('This is your default setting for who can view your default channel profile'); + case PERMS_R_ABOOK: + return t('This is your default setting for who can view your connections'); + case PERMS_R_STORAGE: + return t('This is your default setting for who can view your file storage and photos'); + case PERMS_R_PAGES: + return t('This is your default setting for the audience of your webpages'); + default: + return ''; + } + } } diff --git a/Zotlabs/Lib/Queue.php b/Zotlabs/Lib/Queue.php index 62ecec61f..c65beb379 100644 --- a/Zotlabs/Lib/Queue.php +++ b/Zotlabs/Lib/Queue.php @@ -1,4 +1,6 @@ - $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate); call_hooks('queue_deliver', $arr); - if ($arr['handled']) + if ($arr['handled']) { return; + } // "post" queue driver - used for diaspora and friendica-over-diaspora communications. @@ -224,12 +237,14 @@ class Queue if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG); if ($base) { - q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", + q( + "update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($base) ); } - q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", + q( + "update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($outq['outq_hash']) @@ -241,7 +256,8 @@ class Queue // immediate delivery otherwise we could get into a queue loop. if (!$immediate) { - $x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", + $x = q( + "select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", dbesc($outq['outq_posturl']) ); @@ -265,7 +281,6 @@ class Queue } if ($outq['outq_driver'] === 'asfetch') { - $channel = channelx_by_n($outq['outq_channel']); if (!$channel) { logger('missing channel: ' . $outq['outq_channel']); @@ -303,7 +318,8 @@ class Queue // immediate delivery otherwise we could get into a queue loop. if (!$immediate) { - $x = q("select outq_hash from outq where outq_driver = 'asfetch' and outq_channel = %d and outq_delivered = 0", + $x = q( + "select outq_hash from outq where outq_driver = 'asfetch' and outq_channel = %d and outq_delivered = 0", dbesc($outq['outq_channel']) ); @@ -325,7 +341,6 @@ class Queue } if ($outq['outq_driver'] === 'activitypub') { - $channel = channelx_by_n($outq['outq_channel']); if (!$channel) { logger('missing channel: ' . $outq['outq_channel']); @@ -356,12 +371,14 @@ class Queue if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG); if ($base) { - q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", + q( + "update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($base) ); } - q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", + q( + "update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($outq['outq_hash']) @@ -373,7 +390,8 @@ class Queue // immediate delivery otherwise we could get into a queue loop. if (!$immediate) { - $x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", + $x = q( + "select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", dbesc($outq['outq_posturl']) ); @@ -389,18 +407,21 @@ class Queue } } else { if ($result['return_code'] >= 300) { - q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", + q( + "update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", dbesc('delivery rejected' . ' ' . $result['return_code']), dbesc(datetime_convert()), dbesc($outq['outq_hash']) ); } else { - $dr = q("select * from dreport where dreport_queue = '%s'", + $dr = q( + "select * from dreport where dreport_queue = '%s'", dbesc($outq['outq_hash']) ); if ($dr) { // update every queue entry going to this site with the most recent communication error - q("update dreport set dreport_log = '%s' where dreport_site = '%s'", + q( + "update dreport set dreport_log = '%s' where dreport_site = '%s'", dbesc(z_curl_error($result)), dbesc($dr[0]['dreport_site']) ); @@ -426,7 +447,8 @@ class Queue Libzot::process_response($outq['outq_posturl'], ['success' => true, 'body' => json_encode($result)], $outq); if (!$immediate) { - $x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", + $x = q( + "select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", dbesc($outq['outq_posturl']) ); @@ -451,7 +473,8 @@ class Queue $host_crypto = null; if ($channel && $base) { - $h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1", + $h = q( + "select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1", dbesc($base) ); if ($h) { @@ -467,12 +490,14 @@ class Queue logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']); Libzot::process_response($outq['outq_posturl'], $result, $outq); } else { - $dr = q("select * from dreport where dreport_queue = '%s'", + $dr = q( + "select * from dreport where dreport_queue = '%s'", dbesc($outq['outq_hash']) ); // update every queue entry going to this site with the most recent communication error - q("update dreport set dreport_log = '%s' where dreport_site = '%s'", + q( + "update dreport set dreport_log = '%s' where dreport_site = '%s'", dbesc(z_curl_error($result)), dbesc($dr[0]['dreport_site']) ); @@ -485,4 +510,3 @@ class Queue return; } } - diff --git a/Zotlabs/Lib/SConfig.php b/Zotlabs/Lib/SConfig.php index 92161fc61..1d4e93a3f 100644 --- a/Zotlabs/Lib/SConfig.php +++ b/Zotlabs/Lib/SConfig.php @@ -7,23 +7,27 @@ namespace Zotlabs\Lib; * * @see XConfig */ - -class SConfig { - public static function Load($server_id) { - return XConfig::Load('s_' . $server_id); - } +class SConfig +{ - public static function Get($server_id, $family, $key, $default = false) { - return XConfig::Get('s_' . $server_id,$family,$key, $default); - } + public static function Load($server_id) + { + return XConfig::Load('s_' . $server_id); + } - public static function Set($server_id, $family, $key, $value) { - return XConfig::Set('s_' . $server_id,$family,$key,$value); - } + public static function Get($server_id, $family, $key, $default = false) + { + return XConfig::Get('s_' . $server_id, $family, $key, $default); + } - public static function Delete($server_id, $family, $key) { - return XConfig::Delete('s_' . $server_id,$family,$key); - } + public static function Set($server_id, $family, $key, $value) + { + return XConfig::Set('s_' . $server_id, $family, $key, $value); + } + public static function Delete($server_id, $family, $key) + { + return XConfig::Delete('s_' . $server_id, $family, $key); + } } diff --git a/Zotlabs/Lib/Share.php b/Zotlabs/Lib/Share.php index 973922566..70c1fe7c8 100644 --- a/Zotlabs/Lib/Share.php +++ b/Zotlabs/Lib/Share.php @@ -6,222 +6,227 @@ use App; use Zotlabs\Daemon\Run; use Zotlabs\Lib\Libsync; -class Share { +class Share +{ - private $item = null; + private $item = null; - public function __construct($post_id) { - - if (! $post_id) { - return; - } - - if (is_array($post_id)) { - $this->item = $post_id; - return; - } - - if (! (local_channel() || remote_channel())) { - return; - } + public function __construct($post_id) + { - $r = q("SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1", - intval($post_id) - ); - if (! $r) { - return; - } + if (! $post_id) { + return; + } - if (($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss')) { - return; - } - - $sql_extra = item_permissions_sql($r[0]['uid']); - - $r = q("select * from item where id = %d $sql_extra", - intval($post_id) - ); - if (! $r) { - return; - } - - if (! in_array($r[0]['mimetype'], [ 'text/bbcode', 'text/x-multicode' ])) { - return; - } - - /** @FIXME eventually we want to post remotely via rpost on your home site */ - // When that works remove this next bit: - - if (! local_channel()) { - return; - } + if (is_array($post_id)) { + $this->item = $post_id; + return; + } - xchan_query($r); - - $this->item = array_shift($r); + if (! (local_channel() || remote_channel())) { + return; + } - $arr = []; + $r = q( + "SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1", + intval($post_id) + ); + if (! $r) { + return; + } - $owner_uid = $this->item['uid']; - $owner_aid = $this->item['aid']; + if (($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss')) { + return; + } - $channel = channelx_by_n($this->item['uid']); - $observer = App::get_observer(); + $sql_extra = item_permissions_sql($r[0]['uid']); - $can_comment = false; - if ((array_key_exists('owner',$this->item)) && intval($this->item['owner']['abook_self'])) { - $can_comment = perm_is_allowed($this->item['uid'],$observer['xchan_hash'],'post_comments'); - } - else { - $can_comment = can_comment_on_post($observer['xchan_hash'],$this->item); - } + $r = q( + "select * from item where id = %d $sql_extra", + intval($post_id) + ); + if (! $r) { + return; + } - if (! $can_comment) { - return; - } + if (! in_array($r[0]['mimetype'], [ 'text/bbcode', 'text/x-multicode' ])) { + return; + } - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($this->item['owner_xchan']) - ); + /** @FIXME eventually we want to post remotely via rpost on your home site */ + // When that works remove this next bit: - if ($r) { - $thread_owner = array_shift($r); - } - else { - return; - } - - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($this->item['author_xchan']) - ); - if ($r) { - $item_author = array_shift($r); - } - else { - return; - } + if (! local_channel()) { + return; + } - if ($item_author['network'] === 'activitypub') { + xchan_query($r); - // for Mastodon compatibility, send back an ActivityPub Announce activity. - // We don't need or want these on our own network as there is no mechanism for providing - // a fair-use defense to copyright claims and frivolous lawsuits. - - $arr['aid'] = $owner_aid; - $arr['uid'] = $owner_uid; + $this->item = array_shift($r); - $arr['item_origin'] = 1; - $arr['item_wall'] = $this->item['item_wall']; - $arr['uuid'] = new_uuid(); - $arr['mid'] = z_root() . '/item/' . $arr['uuid']; - $arr['mid'] = str_replace('/item/','/activity/',$arr['mid']); - $arr['parent_mid'] = $this->item['mid']; + $arr = []; - $mention = '@[zrl=' . $this->item['author']['xchan_url'] . ']' . $this->item['author']['xchan_name'] . '[/zrl]'; - $arr['body'] = sprintf( t('🔁 Repeated %1$s\'s %2$s'), $mention, $this->item['obj_type']); + $owner_uid = $this->item['uid']; + $owner_aid = $this->item['aid']; - $arr['author_xchan'] = $observer['xchan_hash']; - $arr['owner_xchan'] = $this->item['author_xchan']; - $arr['obj'] = $this->item['obj']; - $arr['obj_type'] = $this->item['obj_type']; - $arr['verb'] = 'Announce'; + $channel = channelx_by_n($this->item['uid']); + $observer = App::get_observer(); - $post = item_store($arr); + $can_comment = false; + if ((array_key_exists('owner', $this->item)) && intval($this->item['owner']['abook_self'])) { + $can_comment = perm_is_allowed($this->item['uid'], $observer['xchan_hash'], 'post_comments'); + } else { + $can_comment = can_comment_on_post($observer['xchan_hash'], $this->item); + } - $post_id = $post['item_id']; + if (! $can_comment) { + return; + } - $arr['id'] = $post_id; - - call_hooks('post_local_end', $arr); + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($this->item['owner_xchan']) + ); - $r = q("select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); - } + if ($r) { + $thread_owner = array_shift($r); + } else { + return; + } - Run::Summon([ 'Notifier','like',$post_id ]); - } - - return; + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($this->item['author_xchan']) + ); + if ($r) { + $item_author = array_shift($r); + } else { + return; + } - } + if ($item_author['network'] === 'activitypub') { + // for Mastodon compatibility, send back an ActivityPub Announce activity. + // We don't need or want these on our own network as there is no mechanism for providing + // a fair-use defense to copyright claims and frivolous lawsuits. - public function obj() { - $obj = []; + $arr['aid'] = $owner_aid; + $arr['uid'] = $owner_uid; - if(! $this->item) - return $obj; + $arr['item_origin'] = 1; + $arr['item_wall'] = $this->item['item_wall']; + $arr['uuid'] = new_uuid(); + $arr['mid'] = z_root() . '/item/' . $arr['uuid']; + $arr['mid'] = str_replace('/item/', '/activity/', $arr['mid']); + $arr['parent_mid'] = $this->item['mid']; - $obj['type'] = $this->item['obj_type']; - $obj['id'] = $this->item['mid']; - $obj['content'] = bbcode($this->item['body']); - $obj['source'] = [ - 'mediaType' => $this->item['mimetype'], - 'content' => $this->item['body'] - ]; + $mention = '@[zrl=' . $this->item['author']['xchan_url'] . ']' . $this->item['author']['xchan_name'] . '[/zrl]'; + $arr['body'] = sprintf(t('🔁 Repeated %1$s\'s %2$s'), $mention, $this->item['obj_type']); - $obj['name'] = $this->item['title']; - $obj['published'] = $this->item['created']; - $obj['updated'] = $this->item['edited']; - $obj['attributedTo'] = ((strpos($this->item['author']['xchan_hash'],'http') === 0) - ? $this->item['author']['xchan_hash'] - : $this->item['author']['xchan_url']); + $arr['author_xchan'] = $observer['xchan_hash']; + $arr['owner_xchan'] = $this->item['author_xchan']; + $arr['obj'] = $this->item['obj']; + $arr['obj_type'] = $this->item['obj_type']; + $arr['verb'] = 'Announce'; - return $obj; - } + $post = item_store($arr); - public function bbcode() { - $bb = EMPTY_STR; + $post_id = $post['item_id']; - if (! $this->item) - return $bb; + $arr['id'] = $post_id; - if (! $this->item['author']) { - $author = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($this->item['author_xchan']) - ); - if ($author) { - $this->item['author'] = array_shift($author); - } - } + call_hooks('post_local_end', $arr); - $special_object = (in_array($this->item['obj_type'], [ ACTIVITY_OBJ_PHOTO, 'Event', 'Question' ]) ? true : false); - if($special_object) { - $object = json_decode($this->item['obj'],true); - $special = (($object['source']) ? $object['source']['content'] : $object['body']); - } - - if (strpos($this->item['body'], "[/share]") !== false) { - $pos = strpos($this->item['body'], "[share"); - $bb = substr($this->item['body'], $pos); - } else { - $bb = "[share author='" . urlencode($this->item['author']['xchan_name']). - "' profile='" . $this->item['author']['xchan_url'] . - "' portable_id='" . $this->item['author']['xchan_hash'] . - "' avatar='" . $this->item['author']['xchan_photo_s'] . - "' link='" . $this->item['plink'] . - "' auth='" . (($this->item['author']['network'] === 'zot6') ? 'true' : 'false') . - "' posted='" . $this->item['created'] . - "' message_id='" . $this->item['mid'] . - "']"; - if ($this->item['title']) { - $bb .= '[b]'.$this->item['title'].'[/b]'."\r\n"; - } - if ($this->item['summary']) { - $bb .= $this->item['summary'] . "\r\n"; - } - - $bb .= (($special_object) ? $special . "\r\n" . $this->item['body'] : $this->item['body']); - $bb .= "[/share]"; - } + $r = q( + "select * from item where id = %d", + intval($post_id) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); + } - return $bb; + Run::Summon([ 'Notifier','like',$post_id ]); + } - } + return; + } + public function obj() + { + $obj = []; + + if (! $this->item) { + return $obj; + } + + $obj['type'] = $this->item['obj_type']; + $obj['id'] = $this->item['mid']; + $obj['content'] = bbcode($this->item['body']); + $obj['source'] = [ + 'mediaType' => $this->item['mimetype'], + 'content' => $this->item['body'] + ]; + + $obj['name'] = $this->item['title']; + $obj['published'] = $this->item['created']; + $obj['updated'] = $this->item['edited']; + $obj['attributedTo'] = ((strpos($this->item['author']['xchan_hash'], 'http') === 0) + ? $this->item['author']['xchan_hash'] + : $this->item['author']['xchan_url']); + + return $obj; + } + + public function bbcode() + { + $bb = EMPTY_STR; + + if (! $this->item) { + return $bb; + } + + if (! $this->item['author']) { + $author = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($this->item['author_xchan']) + ); + if ($author) { + $this->item['author'] = array_shift($author); + } + } + + $special_object = (in_array($this->item['obj_type'], [ ACTIVITY_OBJ_PHOTO, 'Event', 'Question' ]) ? true : false); + if ($special_object) { + $object = json_decode($this->item['obj'], true); + $special = (($object['source']) ? $object['source']['content'] : $object['body']); + } + + if (strpos($this->item['body'], "[/share]") !== false) { + $pos = strpos($this->item['body'], "[share"); + $bb = substr($this->item['body'], $pos); + } else { + $bb = "[share author='" . urlencode($this->item['author']['xchan_name']) . + "' profile='" . $this->item['author']['xchan_url'] . + "' portable_id='" . $this->item['author']['xchan_hash'] . + "' avatar='" . $this->item['author']['xchan_photo_s'] . + "' link='" . $this->item['plink'] . + "' auth='" . (($this->item['author']['network'] === 'zot6') ? 'true' : 'false') . + "' posted='" . $this->item['created'] . + "' message_id='" . $this->item['mid'] . + "']"; + if ($this->item['title']) { + $bb .= '[b]' . $this->item['title'] . '[/b]' . "\r\n"; + } + if ($this->item['summary']) { + $bb .= $this->item['summary'] . "\r\n"; + } + + $bb .= (($special_object) ? $special . "\r\n" . $this->item['body'] : $this->item['body']); + $bb .= "[/share]"; + } + + return $bb; + } } diff --git a/Zotlabs/Lib/SvgSanitizer.php b/Zotlabs/Lib/SvgSanitizer.php index 220a7a796..5e21c4f12 100644 --- a/Zotlabs/Lib/SvgSanitizer.php +++ b/Zotlabs/Lib/SvgSanitizer.php @@ -7,9 +7,9 @@ use Zotlabs\Lib\Config; /** * SVGSantiizer - * + * * Allowlist-based PHP SVG sanitizer. - * + * * @link https://github.com/alister-/SVG-Sanitizer} * @author Alister Norris * @copyright Copyright (c) 2013 Alister Norris @@ -108,7 +108,6 @@ class SvgSanitizer $total = $currentNode->attributes->length; for ($x = 0; $x < $total; $x++) { - // get attributes name $attrName = $currentNode->attributes->item($x)->nodeName; @@ -119,8 +118,14 @@ class SvgSanitizer if (!in_array($attrName, $allowlist_attr_arr)) { $this->removedattrs[] = $attrName; } // check for disallowed functions - elseif (preg_match_all('/([a-zA-Z0-9]+)[\s]*\(/', - $currentNode->attributes->item($x)->textContent, $matches, PREG_SET_ORDER)) { + elseif ( + preg_match_all( + '/([a-zA-Z0-9]+)[\s]*\(/', + $currentNode->attributes->item($x)->textContent, + $matches, + PREG_SET_ORDER + ) + ) { if ($attrName === 'text') { continue; } @@ -138,7 +143,6 @@ class SvgSanitizer logger('removed: ' . $attr, LOGGER_DEBUG); } } - } // else remove element else { logger('remove_node: ' . print_r($currentNode, true)); diff --git a/Zotlabs/Lib/System.php b/Zotlabs/Lib/System.php index 968729aef..3e3010bdf 100644 --- a/Zotlabs/Lib/System.php +++ b/Zotlabs/Lib/System.php @@ -4,113 +4,141 @@ namespace Zotlabs\Lib; use App; -class System { +class System +{ - public static function get_platform_name() { - if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('platform_name',App::$config['system'])) - return App::$config['system']['platform_name']; - return PLATFORM_NAME; - } + public static function get_platform_name() + { + if (is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('platform_name', App::$config['system'])) { + return App::$config['system']['platform_name']; + } + return PLATFORM_NAME; + } - public static function get_site_name() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['sitename']) - return App::$config['system']['sitename']; - return ''; - } + public static function get_site_name() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['sitename']) { + return App::$config['system']['sitename']; + } + return ''; + } - public static function get_banner() { + public static function get_banner() + { - if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('banner',App::$config['system']) && App::$config['system']['banner']) { - return App::$config['system']['banner']; - } - return self::get_site_name(); - } + if (is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('banner', App::$config['system']) && App::$config['system']['banner']) { + return App::$config['system']['banner']; + } + return self::get_site_name(); + } - public static function get_project_icon() { - if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('icon',App::$config['system'])) { - return App::$config['system']['icon']; - } - return z_root() . '/images/' . PLATFORM_NAME . '-64.png'; - } + public static function get_project_icon() + { + if (is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('icon', App::$config['system'])) { + return App::$config['system']['icon']; + } + return z_root() . '/images/' . PLATFORM_NAME . '-64.png'; + } - public static function get_project_favicon() { - if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('favicon',App::$config['system'])) { - return App::$config['system']['favicon']; - } - return z_root() . '/images/' . PLATFORM_NAME . '.ico'; - } + public static function get_project_favicon() + { + if (is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('favicon', App::$config['system'])) { + return App::$config['system']['favicon']; + } + return z_root() . '/images/' . PLATFORM_NAME . '.ico'; + } - public static function get_project_version() { - if(array_path_exists('system/hide_version', App::$config) && intval(App::$config['system']['hide_version'])) - return ''; - if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('std_version',App::$config['system'])) - return App::$config['system']['std_version']; + public static function get_project_version() + { + if (array_path_exists('system/hide_version', App::$config) && intval(App::$config['system']['hide_version'])) { + return ''; + } + if (is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('std_version', App::$config['system'])) { + return App::$config['system']['std_version']; + } - return self::get_std_version(); - } + return self::get_std_version(); + } - public static function get_update_version() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['hide_version']) - return EMPTY_STR; - return DB_UPDATE_VERSION; - } + public static function get_update_version() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['hide_version']) { + return EMPTY_STR; + } + return DB_UPDATE_VERSION; + } - public static function get_notify_icon() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['email_notify_icon_url']) - return App::$config['system']['email_notify_icon_url']; - return self::get_project_icon(); - } + public static function get_notify_icon() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['email_notify_icon_url']) { + return App::$config['system']['email_notify_icon_url']; + } + return self::get_project_icon(); + } - public static function get_site_icon() { - if(is_array(App::$config) && is_array(App::$config['system']) && isset(App::$config['system']['site_icon_url']) && App::$config['system']['site_icon_url']) - return App::$config['system']['site_icon_url']; - return self::get_project_icon(); - } + public static function get_site_icon() + { + if (is_array(App::$config) && is_array(App::$config['system']) && isset(App::$config['system']['site_icon_url']) && App::$config['system']['site_icon_url']) { + return App::$config['system']['site_icon_url']; + } + return self::get_project_icon(); + } - public static function get_site_favicon() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['site_favicon_url']) - return App::$config['system']['site_favicon_url']; - return self::get_project_favicon(); - } + public static function get_site_favicon() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['site_favicon_url']) { + return App::$config['system']['site_favicon_url']; + } + return self::get_project_favicon(); + } - public static function get_project_link() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_link']) - return App::$config['system']['project_link']; - return 'https://zotlabs.com/' . PLATFORM_NAME; - } + public static function get_project_link() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_link']) { + return App::$config['system']['project_link']; + } + return 'https://zotlabs.com/' . PLATFORM_NAME; + } - public static function get_project_srclink() { - if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_srclink']) - return App::$config['system']['project_srclink']; - return 'https://codeberg.org/zot/' . PLATFORM_NAME; - } + public static function get_project_srclink() + { + if (is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_srclink']) { + return App::$config['system']['project_srclink']; + } + return 'https://codeberg.org/zot/' . PLATFORM_NAME; + } - public static function ebs() { - if(defined('EBSSTATE')) { - return EBSSTATE; - } - return 'armed'; - } + public static function ebs() + { + if (defined('EBSSTATE')) { + return EBSSTATE; + } + return 'armed'; + } - public static function get_zot_revision() { - $x = [ 'revision' => ZOT_REVISION ]; - call_hooks('zot_revision',$x); - return $x['revision']; - } + public static function get_zot_revision() + { + $x = [ 'revision' => ZOT_REVISION ]; + call_hooks('zot_revision', $x); + return $x['revision']; + } - public static function get_std_version() { - if(defined('STD_VERSION')) - return STD_VERSION; - return '0.0.0'; - } + public static function get_std_version() + { + if (defined('STD_VERSION')) { + return STD_VERSION; + } + return '0.0.0'; + } - public static function compatible_project($p) { + public static function compatible_project($p) + { - if (in_array(strtolower($p),['hubzilla', 'zap', 'red', 'misty', 'mistpark', 'redmatrix', 'osada', 'roadhouse'])) { - return true; - } - return false; - } + if (in_array(strtolower($p), ['hubzilla', 'zap', 'red', 'misty', 'mistpark', 'redmatrix', 'osada', 'roadhouse'])) { + return true; + } + return false; + } } diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 22e614002..6b4e32952 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -1,4 +1,6 @@ -data = $data; - $this->toplevel = ($this->get_id() == $this->get_data_value('parent')); - $this->threaded = get_config('system','thread_allow',true); - - $observer = App::get_observer(); - - // Prepare the children - if($data['children']) { - foreach($data['children'] as $item) { - - /* - * Only add those that will be displayed - */ - - if(! visible_activity($item)) { - continue; - } - - // this is a quick hack to hide ActivityPub DMs that we should not be allowed to see - // but may have been forwarded as part of a conversation - - if(intval($item['item_private']) && (intval($item['item_restrict']) & 1 ) && $item['mid'] !== $item['parent_mid']) { - if(! $observer) { - continue; - } - } - - $child = new ThreadItem($item); - $this->add_child($child); - } - } - - // allow a site to configure the order and content of the reaction emoji list - if($this->toplevel) { - $x = get_config('system','reactions'); - if($x && is_array($x) && count($x)) { - $this->reactions = $x; - } - } - } - - /** - * Get data in a form usable by a conversation template - * - * Returns: - * _ The data requested on success - * _ false on failure - */ - - public function get_template_data($conv_responses, $thread_level = 1) { - - $result = []; - - $item = $this->get_data(); - - $commentww = ''; - $sparkle = ''; - $buttons = ''; - $dropping = false; - $star = false; - $isstarred = "unstarred fa-star-o"; - $is_comment = false; - $is_item = false; - $osparkle = ''; - $total_children = $this->count_descendants(); - $unseen_comments = ((isset($item['real_uid']) && $item['real_uid']) ? 0 : $this->count_unseen_descendants()); - $privacy_warning = false; - - $conv = $this->get_conversation(); - $observer = $conv->get_observer(); - - $lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) - ? t('Private Message') - : false); - - $locktype = $item['item_private']; - - $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && (! intval($item['item_private']))) ? true : false); - - // allow an exemption for sharing stuff from your private feeds - if($item['author']['xchan_network'] === 'rss') - $shareable = true; - - // @fixme - // Have recently added code to properly handle polls in group reshares by redirecting all of the poll responses to the group. - // Sharing a poll using a regular embedded share is harder because the poll will need to fork. This is due to comment permissions. - // The original poll author may not accept responses from strangers. Forking the poll will receive responses from the sharer's - // followers, but there's no elegant way to merge these two sets of results together. For now, we'll disable sharing polls. - - if ($item['obj_type'] === 'Question') { - $shareable = false; - } - - - if ($item['item_restrict'] & 2) { - $privacy_warning = true; - $lock = t('This comment is part of a private conversation, yet was shared with the public. Discretion advised.'); - } - - $mode = $conv->get_mode(); - - $edlink = 'editpost'; - - if(local_channel() && $observer['xchan_hash'] === $item['author_xchan']) - $edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit')); - else - $edpost = false; - - if(local_channel() && $observer['xchan_hash'] === $item['owner_xchan']) - $myconv = true; - else - $myconv = false; - - - if($item['verb'] === 'Announce') { - $edpost = false; - } - - - if ($observer && $observer['xchan_hash'] - && ( $observer['xchan_hash'] == $this->get_data_value('author_xchan') - || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') - || $observer['xchan_hash'] == $this->get_data_value('source_xchan') - || $this->get_data_value('uid') == local_channel())) - $dropping = true; - - - if(array_key_exists('real_uid',$item)) { - $edpost = false; - $dropping = false; - } - - - if($dropping) { - $drop = array( - 'dropping' => $dropping, - 'delete' => t('Delete'), - ); - } - elseif(is_site_admin()) { - $drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ]; - } - - if(isset($observer_is_pageowner) && $observer_is_pageowner) { - $multidrop = array( - 'select' => t('Select'), - ); - } - - $filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t('Save to Folder') : false); - - $profile_avatar = $item['author']['xchan_photo_m']; - $profile_link = chanlink_hash($item['author_xchan']); - $profile_name = $item['author']['xchan_name']; - - $profile_addr = $item['author']['xchan_addr'] ? $item['author']['xchan_addr'] : $item['author']['xchan_url']; - - $location = format_location($item); - $isevent = false; - $attend = null; - $canvote = false; - - // process action responses - e.g. like/dislike/attend/agree/whatever - $response_verbs = [ 'like', 'dislike' ]; - - if($item['obj_type'] === ACTIVITY_OBJ_EVENT) { - $response_verbs[] = 'attendyes'; - $response_verbs[] = 'attendno'; - $response_verbs[] = 'attendmaybe'; - if($this->is_commentable() && $observer) { - $isevent = true; - $attend = array( t('I will attend'), t('I will not attend'), t('I might attend')); - $undo_attend = t('Undo attendance'); - } - } - - $responses = get_responses($conv_responses,$response_verbs,$this,$item); - - $my_responses = []; - foreach($response_verbs as $v) { - $my_responses[$v] = ((isset($conv_responses[$v][$item['mid'] . '-m']) && $conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0); - } - - $like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : ''); - $like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : ''); - if (($like_list) && (count($like_list) > MAX_LIKERS)) { - $like_list_part = array_slice($like_list, 0, MAX_LIKERS); - array_push($like_list_part, '' . t('View all') . ''); - } else { - $like_list_part = ''; - } - if(get_config('system','show_like_counts',true)) { - $like_button_label = tt('Like','Likes',$like_count,'noun'); - } - else { - $like_button_label = t('Likes','noun'); - } - - $dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : ''); - $dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : ''); - if(get_config('system','show_like_counts',true)) { - $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); - } - else { - $dislike_button_label = t('Dislikes','noun'); - } - - if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) { - $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); - array_push($dislike_list_part, '' . t('View all') . ''); - } else { - $dislike_list_part = ''; - } - - - $showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : ''); - $showdislike = ((x($conv_responses['dislike'],$item['mid'])) - ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : ''); - - /* - * We should avoid doing this all the time, but it depends on the conversation mode - * And the conv mode may change when we change the conv, or it changes its mode - * Maybe we should establish a way to be notified about conversation changes - */ - - $this->check_wall_to_wall(); - - if($this->is_toplevel()) { - if(local_channel() && $conv->get_profile_owner() == local_channel() && (! array_key_exists('real_uid',$item))) { - $star = [ - 'toggle' => t('Save'), - 'isstarred' => ((intval($item['item_starred'])) ? true : false), - ]; - } - } - else { - $is_comment = true; - } - - - $verified = (intval($item['item_verified']) ? t('Message signature validated') : ''); - $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : ''); - $unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : ''); - - - if($conv->get_profile_owner() == local_channel()) { - $tagger = array( - 'tagit' => t("Add Tag"), - 'classtagger' => "", - ); - } - - $has_bookmarks = false; - if(isset($item['term']) && is_array($item['term'])) { - foreach($item['term'] as $t) { - if($t['ttype'] == TERM_BOOKMARK) - $has_bookmarks = true; - } - } - - $has_event = false; - if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel()) - $has_event = true; - - if($this->is_commentable() && $observer) { - $like = array( t('I like this'), t('Undo like')); - $dislike = array( t('I don\'t like this'), t('Undo dislike') ); - } - - $share = $embed = EMPTY_STR; - - if ($shareable) { - $share = t('Repeat This'); - $embed = t('Share this'); - } - - $dreport = ''; - - $keep_reports = intval(get_config('system','expire_delivery_reports')); - if($keep_reports === 0) - $keep_reports = 10; - - if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) { - $dreport = t('Delivery Report'); - $dreport_link = gen_link_id($item['mid']); - } - $is_new = false; - - if (strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) { - $is_new = true; - } - - localize_item($item); - - $opts = []; - if ($this->is_wall_to_wall()) { - if ($this->owner_censored) { - $opts['censored'] = true; - } - } - - $body = prepare_body($item,true,$opts); - - // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link - // since we can't depend on llink or plink pointing to the right local location. - - $owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@')); - $viewthread = $item['llink']; - if($conv->get_mode() === 'channel') - $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode(gen_link_id($item['mid'])); - - $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); - $list_unseen_txt = (($unseen_comments) ? sprintf( t('%d unseen'),$unseen_comments) : ''); - - $children = $this->get_children(); - - - $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); - - $dropdown_extras_arr = [ 'item' => $item , 'dropdown_extras' => '' ]; - call_hooks('dropdown_extras',$dropdown_extras_arr); - $dropdown_extras = $dropdown_extras_arr['dropdown_extras']; - - // Pinned item processing - $allowed_type = (in_array($item['item_type'], get_config('system', 'pin_types', [ ITEM_TYPE_POST ])) ? true : false); - $pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []); - $pinned = ((! empty($pinned_items) && in_array($item['mid'], $pinned_items)) ? true : false); - - $tmp_item = array( - 'template' => $this->get_template(), - 'mode' => $mode, - 'item_type' => intval($item['item_type']), - 'comment_order' => $item['comment_order'], - 'parent' => $this->get_data_value('parent'), - 'collapsed' => ((intval($item['comment_order']) > 3) ? true : false), - 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), - 'body' => $body['html'], - 'tags' => $body['tags'], - 'categories' => $body['categories'], - 'mentions' => $body['mentions'], - 'attachments' => $body['attachments'], - 'folders' => $body['folders'], - 'text' => strip_tags($body['html']), - 'id' => $this->get_id(), - 'mid' => $item['mid'], - 'isevent' => $isevent, - 'attend' => $attend, - 'undo_attend' => $undo_attend, - 'consensus' => '', - 'conlabels' => '', - 'canvote' => $canvote, - 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url'])), - 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url'])), - 'llink' => $item['llink'], - 'viewthread' => $viewthread, - 'to' => t('to'), - 'via' => t('via'), - 'wall' => t('Wall-to-Wall'), - 'vwall' => t('via Wall-To-Wall:'), - 'profile_url' => $profile_link, - 'thread_action_menu' => thread_action_menu($item,$conv->get_mode()), - 'thread_author_menu' => thread_author_menu($item,$conv->get_mode()), - 'dreport' => $dreport, - 'dreport_link' => ((isset($dreport_link) && $dreport_link) ? $dreport_link : EMPTY_STR), - 'myconv' => $myconv, - 'name' => $profile_name, - 'thumb' => $profile_avatar, - 'osparkle' => $osparkle, - 'sparkle' => $sparkle, - 'title' => $item['title'], - 'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'), - 'ago' => relative_date($item['created']), - 'app' => $item['app'], - 'str_app' => sprintf( t('from %s'), $item['app']), - 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), - 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), - 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), - 'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''), - 'lock' => $lock, - 'locktype' => $locktype, - 'delayed' => $item['item_delayed'], - 'privacy_warning' => $privacy_warning, - 'verified' => $verified, - 'unverified' => $unverified, - 'forged' => $forged, - 'location' => $location, - 'divider' => get_pconfig($conv->get_profile_owner(),'system','item_divider'), - 'attend_label' => t('Attend'), - 'attend_title' => t('Attendance Options'), - 'vote_label' => t('Vote'), - 'vote_title' => t('Voting Options'), - 'comment_lbl' => (($this->is_commentable() && $observer) ? t('Reply') : ''), - 'is_comment' => $is_comment, - 'is_new' => $is_new, - 'mod_display' => ((argv(0) === 'display') ? true : false), // comments are not collapsed when using mod_display - 'owner_url' => $this->get_owner_url(), - 'owner_photo' => $this->get_owner_photo(), - 'owner_name' => $this->get_owner_name(), - 'photo' => $body['photo'], - 'event' => $body['event'], - 'has_tags' => $has_tags, - 'reactions' => $this->reactions, - - // Item toolbar buttons - - 'emojis' => '', // deprecated - use your operating system or a browser plugin - 'like' => $like, - 'dislike' => $dislike, - 'share' => $share, - 'embed' => $embed, - 'rawmid' => $item['mid'], - 'plink' => get_plink($item), - 'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), - 'star' => $star, - 'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''), - 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''), - 'pinned' => ($pinned ? t('Pinned post') : ''), - 'pinnable' => (($this->is_toplevel() && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0 && $item['item_delayed'] == 0) ? '1' : ''), - 'pinme' => ($pinned ? t('Unpin this post') : t('Pin this post')), - 'isdraft' => boolval($item['item_unpublished']), - 'draft_txt' => t('Saved draft'), - 'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''), - 'addtocal' => (($has_event && ! $item['resource_id']) ? t('Add to Calendar') : ''), - 'drop' => $drop, - 'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''), - 'dropdown_extras' => $dropdown_extras, - - // end toolbar buttons - - 'unseen_comments' => $unseen_comments, - 'comment_count' => $total_children, - 'comment_count_txt' => $comment_count_txt, - 'list_unseen_txt' => $list_unseen_txt, - 'markseen' => t('Mark all seen'), - 'responses' => $responses, - 'my_responses' => $my_responses, - 'like_count' => $like_count, - 'like_list' => $like_list, - 'like_list_part' => $like_list_part, - 'like_button_label' => $like_button_label, - 'like_modal_title' => t('Likes','noun'), - 'dislike_modal_title' => t('Dislikes','noun'), - 'dislike_count' => $dislike_count, - 'dislike_list' => $dislike_list, - 'dislike_list_part' => $dislike_list_part, - 'dislike_button_label' => $dislike_button_label, - 'modal_dismiss' => t('Close'), - 'showlike' => $showlike, - 'showdislike' => $showdislike, - 'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box()), - 'previewing' => ($conv->is_preview() ? true : false ), - 'preview_lbl' => t('This is an unsaved preview'), - 'wait' => t('Please wait'), - 'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])), - 'thread_level' => $thread_level, - 'indentpx' => intval(get_pconfig(local_channel(),'system','thread_indent_px',get_config('system','thread_indent_px',0))), - 'thread_max' => intval(get_config('system','thread_maxlevel',20)) + 1 - ); - - $arr = array('item' => $item, 'output' => $tmp_item); - call_hooks('display_item', $arr); - - $result = $arr['output']; - - $result['children'] = []; - - if (local_channel() && get_pconfig(local_channel(),'system','activitypub',get_config('system','activitypub', ACTIVITYPUB_ENABLED))) { - // place to store all the author addresses (links if not available) in the thread so we can auto-mention them in JS. - $result['authors'] = []; - // fix to add in sub-replies if replying to a comment on your own post from the top level. - if ($observer && ($profile_addr === $observer['xchan_hash'] || $profile_addr === $observer['xchan_addr'])) { - // ignore it - } - else { - $result['authors'][] = $profile_addr; - } - - // Add any mentions from the immediate parent, unless they are mentions of the current viewer or duplicates - if (isset($item['term']) && is_array($item['term'])) { - $additional_mentions = []; - foreach ($item['term'] as $t) { - if ($t['ttype'] == TERM_MENTION) { - $additional_mentions[] = ((($position = strpos($t['url'],'url=')) !== false) ? urldecode(substr($t['url'],$position + 4)) : $t['url']); +class ThreadItem +{ + + public $data = []; + private $template = 'conv_item.tpl'; + private $comment_box_template = 'comment_item.tpl'; + private $commentable = false; + // list of supported reaction emojis - a site can over-ride this via config system.reactions + // Deprecated. Use your operating system or a browser plugin. + private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608']; + private $toplevel = false; + private $children = []; + private $parent = null; + private $conversation = null; + private $redirect_url = null; + private $owner_url = ''; + private $owner_photo = ''; + private $owner_name = ''; + private $owner_censored = false; + private $wall_to_wall = false; + private $threaded = false; + private $visiting = false; + private $channel = null; + private $display_mode = 'normal'; + private $reload = ''; + + + public function __construct($data) + { + + $this->data = $data; + $this->toplevel = ($this->get_id() == $this->get_data_value('parent')); + $this->threaded = get_config('system', 'thread_allow', true); + + $observer = App::get_observer(); + + // Prepare the children + if ($data['children']) { + foreach ($data['children'] as $item) { + /* + * Only add those that will be displayed + */ + + if (! visible_activity($item)) { + continue; + } + + // this is a quick hack to hide ActivityPub DMs that we should not be allowed to see + // but may have been forwarded as part of a conversation + + if (intval($item['item_private']) && (intval($item['item_restrict']) & 1 ) && $item['mid'] !== $item['parent_mid']) { + if (! $observer) { + continue; } - } - if ($additional_mentions) { - $r = q("select hubloc_addr, hubloc_id_url, hubloc_hash from hubloc where hubloc_id_url in (" . protect_sprintf(stringify_array($additional_mentions, true)) . ") "); - if ($r) { - foreach ($r as $rv) { - $ment = (($r[0]['hubloc_addr']) ? $r[0]['hubloc_addr'] : $r[0]['hubloc_id_url']); - if ($ment) { - if ($observer && $observer['xchan_hash'] !== $rv['hubloc_hash'] && ! in_array($ment,$result['authors'])) { - $result['authors'][] = $ment; - } - } - } - } - } - } - } - - $nb_children = count($children); - - $total_children = $this->count_visible_descendants(); - - $visible_comments = get_config('system', 'expanded_comments', 3); - - if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) { - if ($children) { - foreach($children as $child) { - $xz = $child->get_template_data($conv_responses, $thread_level + 1); - $result['children'][] = $xz; - } - } - // Collapse - if($total_children > $visible_comments && $thread_level == 1) { - $result['children'][0]['comment_firstcollapsed'] = true; - $result['children'][0]['num_comments'] = $comment_count_txt; - $result['children'][0]['hide_text'] = sprintf( t('%s show all'), ''); - } - } - - $result['private'] = $item['item_private']; - $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : ''); - - if($this->is_threaded()) { - $result['flatten'] = false; - $result['threaded'] = true; - } - else { - $result['flatten'] = true; - $result['threaded'] = false; - } - - return $result; - } - - public function get_id() { - return $this->get_data_value('id'); - } - - public function get_display_mode() { - return $this->display_mode; - } - - public function set_display_mode($mode) { - $this->display_mode = $mode; - } - - public function is_threaded() { - return $this->threaded; - } - - public function get_author() { - $xchan = $this->get_data_value('author'); - if($xchan['xchan_addr']) { - return $xchan['xchan_addr']; - } - return $xchan['xchan_url']; - } - - public function set_reload($val) { - $this->reload = $val; - } - - public function get_reload() { - return $this->reload; - } - - public function set_commentable($val) { - $this->commentable = $val; - foreach($this->get_children() as $child) - $child->set_commentable($val); - } - - public function is_commentable() { - return $this->commentable; - } - - /** - * Add a child item - */ - public function add_child($item) { - $item_id = $item->get_id(); - if(!$item_id) { - logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG); - return false; - } - if($this->get_child($item->get_id())) { - logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG); - return false; - } - - /* - * Only add what will be displayed - */ - - if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) { - return false; - } - - $item->set_parent($this); - $this->children[] = $item; - return end($this->children); - } - - /** - * Get a child by its ID - */ - - public function get_child($id) { - foreach($this->get_children() as $child) { - if($child->get_id() == $id) - return $child; - } - return null; - } - - /** - * Get all our children - */ - - public function get_children() { - return $this->children; - } - - /** - * Set our parent - */ - protected function set_parent($item) { - $parent = $this->get_parent(); - if($parent) { - $parent->remove_child($this); - } - $this->parent = $item; - $this->set_conversation($item->get_conversation()); - } - - /** - * Remove our parent - */ - - protected function remove_parent() { - $this->parent = null; - $this->conversation = null; - } - - /** - * Remove a child - */ - - public function remove_child($item) { - $id = $item->get_id(); - foreach($this->get_children() as $key => $child) { - if($child->get_id() == $id) { - $child->remove_parent(); - unset($this->children[$key]); - // Reindex the array, in order to make sure there won't be any trouble on loops using count() - $this->children = array_values($this->children); - return true; - } - } - logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG); - return false; - } - - /** - * Get parent item - */ - protected function get_parent() { - return $this->parent; - } - - /** - * set conversation - */ - public function set_conversation($conv) { - $previous_mode = ($this->conversation ? $this->conversation->get_mode() : ''); - - $this->conversation = $conv; - - // Set it on our children too - foreach($this->get_children() as $child) - $child->set_conversation($conv); - } - - /** - * get conversation - */ - public function get_conversation() { - return $this->conversation; - } - - /** - * Get raw data - * - * We shouldn't need this - */ - public function get_data() { - return $this->data; - } - - /** - * Get a data value - * - * Returns: - * _ value on success - * _ false on failure - */ - public function get_data_value($name) { - if(!isset($this->data[$name])) { -// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG); - return false; - } - - return $this->data[$name]; - } - - /** - * Get template - */ - public function get_template() { - return $this->template; - } - - - public function set_template($t) { - $this->template = $t; - } - - /** - * Check if this is a toplevel post - */ - private function is_toplevel() { - return $this->toplevel; - } - - /** - * Count the total of our descendants - */ - private function count_descendants() { - $children = $this->get_children(); - $total = count($children); - if($total > 0) { - foreach($children as $child) { - $total += $child->count_descendants(); - } - } - return $total; - } - - public function count_visible_descendants() { - $total = 0; - $children = $this->get_children(); - if ($children) { - foreach ($children as $child) { - if (! visible_activity($child->data)) { - continue; - } - $total ++; - $total += $child->count_visible_descendants(); - } - } - return $total; - } - - - private function label_descendants($count = 0) { - if(! array_key_exists('sequence',$this->data)) { - if($count) { - $count ++; - } - $this->data['sequence'] = $count; - } - logger('labelled: ' . print_r($this->data,true), LOGGER_DATA); - $children = $this->get_children(); - $total = count($children); - if($total > 0) { - foreach($children as $child) { - if(! visible_activity($child->data)) { - continue; - } - if(! array_key_exists('sequence',$this->data)) { - $count ++; - $child->data['sequence'] = $count; - logger('labelled_child: ' . print_r($child->data,true), LOGGER_DATA); - } - $child->label_descendants($count); - } - } - } - - private function count_unseen_descendants() { - $children = $this->get_children(); - $total = count($children); - if($total > 0) { - $total = 0; - foreach($children as $child) { - if(! visible_activity($child->data)) { - continue; - } - if(intval($child->data['item_unseen'])) - $total ++; - } - } - return $total; - } - - - /** - * Get the template for the comment box - */ - private function get_comment_box_template() { - return $this->comment_box_template; - } - - /** - * Get the comment box - * - * Returns: - * _ The comment box string (empty if no comment box) - * _ false on failure - */ - private function get_comment_box($indent = 0) { - - if(!$this->is_toplevel() && !get_config('system','thread_allow',true)) { - return ''; - } - - $comment_box = ''; - $conv = $this->get_conversation(); - -// logger('Commentable conv: ' . $conv->is_commentable()); - - if(! $this->is_commentable()) - return; - - $template = get_markup_template($this->get_comment_box_template()); - - $observer = $conv->get_observer(); - - $arr = array('comment_buttons' => '','id' => $this->get_id()); - call_hooks('comment_buttons',$arr); - $comment_buttons = $arr['comment_buttons']; - - $feature_auto_save_draft = ((feature_enabled($conv->get_profile_owner(), 'auto_save_draft')) ? "true" : "false"); - $permanent_draft = ((intval($conv->get_profile_owner()) === intval(local_channel()) && Apps::system_app_installed($conv->get_profile_owner(),'Drafts')) ? ('Save draft') : EMPTY_STR); - - - - $comment_box = replace_macros($template,array( - '$return_path' => '', - '$threaded' => $this->is_threaded(), - '$jsreload' => $conv->reload, - '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'), - '$id' => $this->get_id(), - '$parent' => $this->get_id(), - '$comment_buttons' => $comment_buttons, - '$profile_uid' => $conv->get_profile_owner(), - '$mylink' => $observer['xchan_url'], - '$mytitle' => t('This is you'), - '$myphoto' => $observer['xchan_photo_s'], - '$comment' => t('Comment'), - '$submit' => t('Submit'), - '$edat' => EMPTY_STR, - '$edbold' => t('Bold'), - '$editalic' => t('Italic'), - '$eduline' => t('Underline'), - '$edquote' => t('Quote'), - '$edcode' => t('Code'), - '$edimg' => t('Image'), - '$edatt' => t('Attach/Upload file'), - '$edurl' => t('Insert Link'), - '$edvideo' => t('Video'), - '$preview' => t('Preview'), - '$reset' => t('Reset'), - '$indent' => $indent, - '$can_upload' => (perm_is_allowed($conv->get_profile_owner(),get_observer_hash(),'write_storage') && $conv->is_uploadable()), - '$feature_encrypt' => ((Apps::system_app_installed($conv->get_profile_owner(),'Secrets')) ? true : false), - '$feature_markup' => ((Apps::system_app_installed($conv->get_profile_owner(),'Markup')) ? true : false), - '$encrypt' => t('Encrypt text'), - '$cipher' => $conv->get_cipher(), - '$sourceapp' => App::$sourcename, - '$observer' => get_observer_hash(), - '$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false), - '$anonname' => [ 'anonname', t('Your full name (required)') ], - '$anonmail' => [ 'anonmail', t('Your email address (required)') ], - '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ], - '$auto_save_draft' => $feature_auto_save_draft, - '$save' => $permanent_draft, - '$top' => $this->is_toplevel() - )); - - return $comment_box; - } - - private function get_redirect_url() { - return $this->redirect_url; - } - - /** - * Check if we are a wall to wall item and set the relevant properties - */ - protected function check_wall_to_wall() { - $conv = $this->get_conversation(); - $this->wall_to_wall = false; - $this->owner_url = ''; - $this->owner_photo = ''; - $this->owner_name = ''; - $this->owner_censored = false; - - if($conv->get_mode() === 'channel') - return; - - if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) { - $this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']); - $this->owner_photo = $this->data['owner']['xchan_photo_m']; - $this->owner_name = $this->data['owner']['xchan_name']; - $this->wall_to_wall = true; - } - - // present friend-of-friend conversations from hyperdrive as relayed posts from the first friend - // we find among the respondents. - - if ($this->is_toplevel() && (! $this->data['owner']['abook_id'])) { - if ($this->data['children']) { - $friend = $this->find_a_friend($this->data['children']); - if ($friend) { - $this->owner_url = $friend['url']; - $this->owner_photo = $friend['photo']; - $this->owner_name = $friend['name']; - $this->owner_censored = $friend['censored']; - $this->wall_to_wall = true; - } - } - } - } - - private function find_a_friend($items) { - $ret = null; - if ($items) { - foreach ($items as $child) { - if ($child['author']['abook_id'] && (! intval($child['author']['abook_self']))) { - return [ - 'url' => chanlink_hash($child['author']['xchan_hash']), - 'photo' => $child['author']['xchan_photo_m'], - 'name' => $child['author']['xchan_name'], - 'censored' => (($child['author']['xchan_censored'] || $child['author']['abook_censor']) ? true : false) - ]; - if ($child['children']) { - $ret = $this->find_a_friend($child['children']); - if ($ret) { - break; - } - } - } - } - } - return $ret; - } - - - private function is_wall_to_wall() { - return $this->wall_to_wall; - } - - private function get_owner_url() { - return $this->owner_url; - } - - private function get_owner_photo() { - return $this->owner_photo; - } - - private function get_owner_name() { - return $this->owner_name; - } - - private function is_visiting() { - return $this->visiting; - } - - - - + } + + $child = new ThreadItem($item); + $this->add_child($child); + } + } + + // allow a site to configure the order and content of the reaction emoji list + if ($this->toplevel) { + $x = get_config('system', 'reactions'); + if ($x && is_array($x) && count($x)) { + $this->reactions = $x; + } + } + } + + /** + * Get data in a form usable by a conversation template + * + * Returns: + * _ The data requested on success + * _ false on failure + */ + + public function get_template_data($conv_responses, $thread_level = 1) + { + + $result = []; + + $item = $this->get_data(); + + $commentww = ''; + $sparkle = ''; + $buttons = ''; + $dropping = false; + $star = false; + $isstarred = "unstarred fa-star-o"; + $is_comment = false; + $is_item = false; + $osparkle = ''; + $total_children = $this->count_descendants(); + $unseen_comments = ((isset($item['real_uid']) && $item['real_uid']) ? 0 : $this->count_unseen_descendants()); + $privacy_warning = false; + + $conv = $this->get_conversation(); + $observer = $conv->get_observer(); + + $lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) + ? t('Private Message') + : false); + + $locktype = $item['item_private']; + + $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && (! intval($item['item_private']))) ? true : false); + + // allow an exemption for sharing stuff from your private feeds + if ($item['author']['xchan_network'] === 'rss') { + $shareable = true; + } + + // @fixme + // Have recently added code to properly handle polls in group reshares by redirecting all of the poll responses to the group. + // Sharing a poll using a regular embedded share is harder because the poll will need to fork. This is due to comment permissions. + // The original poll author may not accept responses from strangers. Forking the poll will receive responses from the sharer's + // followers, but there's no elegant way to merge these two sets of results together. For now, we'll disable sharing polls. + + if ($item['obj_type'] === 'Question') { + $shareable = false; + } + + + if ($item['item_restrict'] & 2) { + $privacy_warning = true; + $lock = t('This comment is part of a private conversation, yet was shared with the public. Discretion advised.'); + } + + $mode = $conv->get_mode(); + + $edlink = 'editpost'; + + if (local_channel() && $observer['xchan_hash'] === $item['author_xchan']) { + $edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit')); + } else { + $edpost = false; + } + + if (local_channel() && $observer['xchan_hash'] === $item['owner_xchan']) { + $myconv = true; + } else { + $myconv = false; + } + + + if ($item['verb'] === 'Announce') { + $edpost = false; + } + + + if ( + $observer && $observer['xchan_hash'] + && ( $observer['xchan_hash'] == $this->get_data_value('author_xchan') + || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') + || $observer['xchan_hash'] == $this->get_data_value('source_xchan') + || $this->get_data_value('uid') == local_channel()) + ) { + $dropping = true; + } + + + if (array_key_exists('real_uid', $item)) { + $edpost = false; + $dropping = false; + } + + + if ($dropping) { + $drop = array( + 'dropping' => $dropping, + 'delete' => t('Delete'), + ); + } elseif (is_site_admin()) { + $drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ]; + } + + if (isset($observer_is_pageowner) && $observer_is_pageowner) { + $multidrop = array( + 'select' => t('Select'), + ); + } + + $filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid', $item))) ? t('Save to Folder') : false); + + $profile_avatar = $item['author']['xchan_photo_m']; + $profile_link = chanlink_hash($item['author_xchan']); + $profile_name = $item['author']['xchan_name']; + + $profile_addr = $item['author']['xchan_addr'] ? $item['author']['xchan_addr'] : $item['author']['xchan_url']; + + $location = format_location($item); + $isevent = false; + $attend = null; + $canvote = false; + + // process action responses - e.g. like/dislike/attend/agree/whatever + $response_verbs = [ 'like', 'dislike' ]; + + if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) { + $response_verbs[] = 'attendyes'; + $response_verbs[] = 'attendno'; + $response_verbs[] = 'attendmaybe'; + if ($this->is_commentable() && $observer) { + $isevent = true; + $attend = array( t('I will attend'), t('I will not attend'), t('I might attend')); + $undo_attend = t('Undo attendance'); + } + } + + $responses = get_responses($conv_responses, $response_verbs, $this, $item); + + $my_responses = []; + foreach ($response_verbs as $v) { + $my_responses[$v] = ((isset($conv_responses[$v][$item['mid'] . '-m']) && $conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0); + } + + $like_count = ((x($conv_responses['like'], $item['mid'])) ? $conv_responses['like'][$item['mid']] : ''); + $like_list = ((x($conv_responses['like'], $item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : ''); + if (($like_list) && (count($like_list) > MAX_LIKERS)) { + $like_list_part = array_slice($like_list, 0, MAX_LIKERS); + array_push($like_list_part, '' . t('View all') . ''); + } else { + $like_list_part = ''; + } + if (get_config('system', 'show_like_counts', true)) { + $like_button_label = tt('Like', 'Likes', $like_count, 'noun'); + } else { + $like_button_label = t('Likes', 'noun'); + } + + $dislike_count = ((x($conv_responses['dislike'], $item['mid'])) ? $conv_responses['dislike'][$item['mid']] : ''); + $dislike_list = ((x($conv_responses['dislike'], $item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : ''); + if (get_config('system', 'show_like_counts', true)) { + $dislike_button_label = tt('Dislike', 'Dislikes', $dislike_count, 'noun'); + } else { + $dislike_button_label = t('Dislikes', 'noun'); + } + + if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) { + $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); + array_push($dislike_list_part, '' . t('View all') . ''); + } else { + $dislike_list_part = ''; + } + + + $showlike = ((x($conv_responses['like'], $item['mid'])) ? format_like($conv_responses['like'][$item['mid']], $conv_responses['like'][$item['mid'] . '-l'], 'like', $item['mid']) : ''); + $showdislike = ((x($conv_responses['dislike'], $item['mid'])) + ? format_like($conv_responses['dislike'][$item['mid']], $conv_responses['dislike'][$item['mid'] . '-l'], 'dislike', $item['mid']) : ''); + + /* + * We should avoid doing this all the time, but it depends on the conversation mode + * And the conv mode may change when we change the conv, or it changes its mode + * Maybe we should establish a way to be notified about conversation changes + */ + + $this->check_wall_to_wall(); + + if ($this->is_toplevel()) { + if (local_channel() && $conv->get_profile_owner() == local_channel() && (! array_key_exists('real_uid', $item))) { + $star = [ + 'toggle' => t('Save'), + 'isstarred' => ((intval($item['item_starred'])) ? true : false), + ]; + } + } else { + $is_comment = true; + } + + + $verified = (intval($item['item_verified']) ? t('Message signature validated') : ''); + $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : ''); + $unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : ''); + + + if ($conv->get_profile_owner() == local_channel()) { + $tagger = array( + 'tagit' => t("Add Tag"), + 'classtagger' => "", + ); + } + + $has_bookmarks = false; + if (isset($item['term']) && is_array($item['term'])) { + foreach ($item['term'] as $t) { + if ($t['ttype'] == TERM_BOOKMARK) { + $has_bookmarks = true; + } + } + } + + $has_event = false; + if (($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel()) { + $has_event = true; + } + + if ($this->is_commentable() && $observer) { + $like = array( t('I like this'), t('Undo like')); + $dislike = array( t('I don\'t like this'), t('Undo dislike') ); + } + + $share = $embed = EMPTY_STR; + + if ($shareable) { + $share = t('Repeat This'); + $embed = t('Share this'); + } + + $dreport = ''; + + $keep_reports = intval(get_config('system', 'expire_delivery_reports')); + if ($keep_reports === 0) { + $keep_reports = 10; + } + + if ((! get_config('system', 'disable_dreport')) && strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', "now - $keep_reports days")) > 0) { + $dreport = t('Delivery Report'); + $dreport_link = gen_link_id($item['mid']); + } + $is_new = false; + + if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) { + $is_new = true; + } + + localize_item($item); + + $opts = []; + if ($this->is_wall_to_wall()) { + if ($this->owner_censored) { + $opts['censored'] = true; + } + } + + $body = prepare_body($item, true, $opts); + + // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link + // since we can't depend on llink or plink pointing to the right local location. + + $owner_address = substr($item['owner']['xchan_addr'], 0, strpos($item['owner']['xchan_addr'], '@')); + $viewthread = $item['llink']; + if ($conv->get_mode() === 'channel') { + $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode(gen_link_id($item['mid'])); + } + + $comment_count_txt = sprintf(tt('%d comment', '%d comments', $total_children), $total_children); + $list_unseen_txt = (($unseen_comments) ? sprintf(t('%d unseen'), $unseen_comments) : ''); + + $children = $this->get_children(); + + + $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); + + $dropdown_extras_arr = [ 'item' => $item , 'dropdown_extras' => '' ]; + call_hooks('dropdown_extras', $dropdown_extras_arr); + $dropdown_extras = $dropdown_extras_arr['dropdown_extras']; + + // Pinned item processing + $allowed_type = (in_array($item['item_type'], get_config('system', 'pin_types', [ ITEM_TYPE_POST ])) ? true : false); + $pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []); + $pinned = ((! empty($pinned_items) && in_array($item['mid'], $pinned_items)) ? true : false); + + $tmp_item = array( + 'template' => $this->get_template(), + 'mode' => $mode, + 'item_type' => intval($item['item_type']), + 'comment_order' => $item['comment_order'], + 'parent' => $this->get_data_value('parent'), + 'collapsed' => ((intval($item['comment_order']) > 3) ? true : false), + 'type' => implode("", array_slice(explode("/", $item['verb']), -1)), + 'body' => $body['html'], + 'tags' => $body['tags'], + 'categories' => $body['categories'], + 'mentions' => $body['mentions'], + 'attachments' => $body['attachments'], + 'folders' => $body['folders'], + 'text' => strip_tags($body['html']), + 'id' => $this->get_id(), + 'mid' => $item['mid'], + 'isevent' => $isevent, + 'attend' => $attend, + 'undo_attend' => $undo_attend, + 'consensus' => '', + 'conlabels' => '', + 'canvote' => $canvote, + 'linktitle' => sprintf(t('View %s\'s profile - %s'), $profile_name, (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url'])), + 'olinktitle' => sprintf(t('View %s\'s profile - %s'), $this->get_owner_name(), (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url'])), + 'llink' => $item['llink'], + 'viewthread' => $viewthread, + 'to' => t('to'), + 'via' => t('via'), + 'wall' => t('Wall-to-Wall'), + 'vwall' => t('via Wall-To-Wall:'), + 'profile_url' => $profile_link, + 'thread_action_menu' => thread_action_menu($item, $conv->get_mode()), + 'thread_author_menu' => thread_author_menu($item, $conv->get_mode()), + 'dreport' => $dreport, + 'dreport_link' => ((isset($dreport_link) && $dreport_link) ? $dreport_link : EMPTY_STR), + 'myconv' => $myconv, + 'name' => $profile_name, + 'thumb' => $profile_avatar, + 'osparkle' => $osparkle, + 'sparkle' => $sparkle, + 'title' => $item['title'], + 'title_tosource' => get_pconfig($conv->get_profile_owner(), 'system', 'title_tosource'), + 'ago' => relative_date($item['created']), + 'app' => $item['app'], + 'str_app' => sprintf(t('from %s'), $item['app']), + 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), + 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), + 'editedtime' => (($item['edited'] != $item['created']) ? sprintf(t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), + 'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf(t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')) : ''), + 'lock' => $lock, + 'locktype' => $locktype, + 'delayed' => $item['item_delayed'], + 'privacy_warning' => $privacy_warning, + 'verified' => $verified, + 'unverified' => $unverified, + 'forged' => $forged, + 'location' => $location, + 'divider' => get_pconfig($conv->get_profile_owner(), 'system', 'item_divider'), + 'attend_label' => t('Attend'), + 'attend_title' => t('Attendance Options'), + 'vote_label' => t('Vote'), + 'vote_title' => t('Voting Options'), + 'comment_lbl' => (($this->is_commentable() && $observer) ? t('Reply') : ''), + 'is_comment' => $is_comment, + 'is_new' => $is_new, + 'mod_display' => ((argv(0) === 'display') ? true : false), // comments are not collapsed when using mod_display + 'owner_url' => $this->get_owner_url(), + 'owner_photo' => $this->get_owner_photo(), + 'owner_name' => $this->get_owner_name(), + 'photo' => $body['photo'], + 'event' => $body['event'], + 'has_tags' => $has_tags, + 'reactions' => $this->reactions, + + // Item toolbar buttons + + 'emojis' => '', // deprecated - use your operating system or a browser plugin + 'like' => $like, + 'dislike' => $dislike, + 'share' => $share, + 'embed' => $embed, + 'rawmid' => $item['mid'], + 'plink' => get_plink($item), + 'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), + 'star' => $star, + 'tagger' => ((feature_enabled($conv->get_profile_owner(), 'commtag')) ? $tagger : ''), + 'filer' => ((feature_enabled($conv->get_profile_owner(), 'filing')) ? $filer : ''), + 'pinned' => ($pinned ? t('Pinned post') : ''), + 'pinnable' => (($this->is_toplevel() && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0 && $item['item_delayed'] == 0) ? '1' : ''), + 'pinme' => ($pinned ? t('Unpin this post') : t('Pin this post')), + 'isdraft' => boolval($item['item_unpublished']), + 'draft_txt' => t('Saved draft'), + 'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''), + 'addtocal' => (($has_event && ! $item['resource_id']) ? t('Add to Calendar') : ''), + 'drop' => $drop, + 'multidrop' => ((feature_enabled($conv->get_profile_owner(), 'multi_delete')) ? $multidrop : ''), + 'dropdown_extras' => $dropdown_extras, + + // end toolbar buttons + + 'unseen_comments' => $unseen_comments, + 'comment_count' => $total_children, + 'comment_count_txt' => $comment_count_txt, + 'list_unseen_txt' => $list_unseen_txt, + 'markseen' => t('Mark all seen'), + 'responses' => $responses, + 'my_responses' => $my_responses, + 'like_count' => $like_count, + 'like_list' => $like_list, + 'like_list_part' => $like_list_part, + 'like_button_label' => $like_button_label, + 'like_modal_title' => t('Likes', 'noun'), + 'dislike_modal_title' => t('Dislikes', 'noun'), + 'dislike_count' => $dislike_count, + 'dislike_list' => $dislike_list, + 'dislike_list_part' => $dislike_list_part, + 'dislike_button_label' => $dislike_button_label, + 'modal_dismiss' => t('Close'), + 'showlike' => $showlike, + 'showdislike' => $showdislike, + 'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box()), + 'previewing' => ($conv->is_preview() ? true : false ), + 'preview_lbl' => t('This is an unsaved preview'), + 'wait' => t('Please wait'), + 'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])), + 'thread_level' => $thread_level, + 'indentpx' => intval(get_pconfig(local_channel(), 'system', 'thread_indent_px', get_config('system', 'thread_indent_px', 0))), + 'thread_max' => intval(get_config('system', 'thread_maxlevel', 20)) + 1 + ); + + $arr = array('item' => $item, 'output' => $tmp_item); + call_hooks('display_item', $arr); + + $result = $arr['output']; + + $result['children'] = []; + + if (local_channel() && get_pconfig(local_channel(), 'system', 'activitypub', get_config('system', 'activitypub', ACTIVITYPUB_ENABLED))) { + // place to store all the author addresses (links if not available) in the thread so we can auto-mention them in JS. + $result['authors'] = []; + // fix to add in sub-replies if replying to a comment on your own post from the top level. + if ($observer && ($profile_addr === $observer['xchan_hash'] || $profile_addr === $observer['xchan_addr'])) { + // ignore it + } else { + $result['authors'][] = $profile_addr; + } + + // Add any mentions from the immediate parent, unless they are mentions of the current viewer or duplicates + if (isset($item['term']) && is_array($item['term'])) { + $additional_mentions = []; + foreach ($item['term'] as $t) { + if ($t['ttype'] == TERM_MENTION) { + $additional_mentions[] = ((($position = strpos($t['url'], 'url=')) !== false) ? urldecode(substr($t['url'], $position + 4)) : $t['url']); + } + } + if ($additional_mentions) { + $r = q("select hubloc_addr, hubloc_id_url, hubloc_hash from hubloc where hubloc_id_url in (" . protect_sprintf(stringify_array($additional_mentions, true)) . ") "); + if ($r) { + foreach ($r as $rv) { + $ment = (($r[0]['hubloc_addr']) ? $r[0]['hubloc_addr'] : $r[0]['hubloc_id_url']); + if ($ment) { + if ($observer && $observer['xchan_hash'] !== $rv['hubloc_hash'] && ! in_array($ment, $result['authors'])) { + $result['authors'][] = $ment; + } + } + } + } + } + } + } + + $nb_children = count($children); + + $total_children = $this->count_visible_descendants(); + + $visible_comments = get_config('system', 'expanded_comments', 3); + + if (($this->get_display_mode() === 'normal') && ($nb_children > 0)) { + if ($children) { + foreach ($children as $child) { + $xz = $child->get_template_data($conv_responses, $thread_level + 1); + $result['children'][] = $xz; + } + } + // Collapse + if ($total_children > $visible_comments && $thread_level == 1) { + $result['children'][0]['comment_firstcollapsed'] = true; + $result['children'][0]['num_comments'] = $comment_count_txt; + $result['children'][0]['hide_text'] = sprintf(t('%s show all'), ''); + } + } + + $result['private'] = $item['item_private']; + $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : ''); + + if ($this->is_threaded()) { + $result['flatten'] = false; + $result['threaded'] = true; + } else { + $result['flatten'] = true; + $result['threaded'] = false; + } + + return $result; + } + + public function get_id() + { + return $this->get_data_value('id'); + } + + public function get_display_mode() + { + return $this->display_mode; + } + + public function set_display_mode($mode) + { + $this->display_mode = $mode; + } + + public function is_threaded() + { + return $this->threaded; + } + + public function get_author() + { + $xchan = $this->get_data_value('author'); + if ($xchan['xchan_addr']) { + return $xchan['xchan_addr']; + } + return $xchan['xchan_url']; + } + + public function set_reload($val) + { + $this->reload = $val; + } + + public function get_reload() + { + return $this->reload; + } + + public function set_commentable($val) + { + $this->commentable = $val; + foreach ($this->get_children() as $child) { + $child->set_commentable($val); + } + } + + public function is_commentable() + { + return $this->commentable; + } + + /** + * Add a child item + */ + public function add_child($item) + { + $item_id = $item->get_id(); + if (!$item_id) { + logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG); + return false; + } + if ($this->get_child($item->get_id())) { + logger('[WARN] Item::add_child : Item already exists (' . $item->get_id() . ').', LOGGER_DEBUG); + return false; + } + + /* + * Only add what will be displayed + */ + + if (activity_match($item->get_data_value('verb'), ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'), ACTIVITY_DISLIKE)) { + return false; + } + + $item->set_parent($this); + $this->children[] = $item; + return end($this->children); + } + + /** + * Get a child by its ID + */ + + public function get_child($id) + { + foreach ($this->get_children() as $child) { + if ($child->get_id() == $id) { + return $child; + } + } + return null; + } + + /** + * Get all our children + */ + + public function get_children() + { + return $this->children; + } + + /** + * Set our parent + */ + protected function set_parent($item) + { + $parent = $this->get_parent(); + if ($parent) { + $parent->remove_child($this); + } + $this->parent = $item; + $this->set_conversation($item->get_conversation()); + } + + /** + * Remove our parent + */ + + protected function remove_parent() + { + $this->parent = null; + $this->conversation = null; + } + + /** + * Remove a child + */ + + public function remove_child($item) + { + $id = $item->get_id(); + foreach ($this->get_children() as $key => $child) { + if ($child->get_id() == $id) { + $child->remove_parent(); + unset($this->children[$key]); + // Reindex the array, in order to make sure there won't be any trouble on loops using count() + $this->children = array_values($this->children); + return true; + } + } + logger('[WARN] Item::remove_child : Item is not a child (' . $id . ').', LOGGER_DEBUG); + return false; + } + + /** + * Get parent item + */ + protected function get_parent() + { + return $this->parent; + } + + /** + * set conversation + */ + public function set_conversation($conv) + { + $previous_mode = ($this->conversation ? $this->conversation->get_mode() : ''); + + $this->conversation = $conv; + + // Set it on our children too + foreach ($this->get_children() as $child) { + $child->set_conversation($conv); + } + } + + /** + * get conversation + */ + public function get_conversation() + { + return $this->conversation; + } + + /** + * Get raw data + * + * We shouldn't need this + */ + public function get_data() + { + return $this->data; + } + + /** + * Get a data value + * + * Returns: + * _ value on success + * _ false on failure + */ + public function get_data_value($name) + { + if (!isset($this->data[$name])) { +// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG); + return false; + } + + return $this->data[$name]; + } + + /** + * Get template + */ + public function get_template() + { + return $this->template; + } + + + public function set_template($t) + { + $this->template = $t; + } + + /** + * Check if this is a toplevel post + */ + private function is_toplevel() + { + return $this->toplevel; + } + + /** + * Count the total of our descendants + */ + private function count_descendants() + { + $children = $this->get_children(); + $total = count($children); + if ($total > 0) { + foreach ($children as $child) { + $total += $child->count_descendants(); + } + } + return $total; + } + + public function count_visible_descendants() + { + $total = 0; + $children = $this->get_children(); + if ($children) { + foreach ($children as $child) { + if (! visible_activity($child->data)) { + continue; + } + $total++; + $total += $child->count_visible_descendants(); + } + } + return $total; + } + + + private function label_descendants($count = 0) + { + if (! array_key_exists('sequence', $this->data)) { + if ($count) { + $count++; + } + $this->data['sequence'] = $count; + } + logger('labelled: ' . print_r($this->data, true), LOGGER_DATA); + $children = $this->get_children(); + $total = count($children); + if ($total > 0) { + foreach ($children as $child) { + if (! visible_activity($child->data)) { + continue; + } + if (! array_key_exists('sequence', $this->data)) { + $count++; + $child->data['sequence'] = $count; + logger('labelled_child: ' . print_r($child->data, true), LOGGER_DATA); + } + $child->label_descendants($count); + } + } + } + + private function count_unseen_descendants() + { + $children = $this->get_children(); + $total = count($children); + if ($total > 0) { + $total = 0; + foreach ($children as $child) { + if (! visible_activity($child->data)) { + continue; + } + if (intval($child->data['item_unseen'])) { + $total++; + } + } + } + return $total; + } + + + /** + * Get the template for the comment box + */ + private function get_comment_box_template() + { + return $this->comment_box_template; + } + + /** + * Get the comment box + * + * Returns: + * _ The comment box string (empty if no comment box) + * _ false on failure + */ + private function get_comment_box($indent = 0) + { + + if (!$this->is_toplevel() && !get_config('system', 'thread_allow', true)) { + return ''; + } + + $comment_box = ''; + $conv = $this->get_conversation(); + +// logger('Commentable conv: ' . $conv->is_commentable()); + + if (! $this->is_commentable()) { + return; + } + + $template = get_markup_template($this->get_comment_box_template()); + + $observer = $conv->get_observer(); + + $arr = array('comment_buttons' => '','id' => $this->get_id()); + call_hooks('comment_buttons', $arr); + $comment_buttons = $arr['comment_buttons']; + + $feature_auto_save_draft = ((feature_enabled($conv->get_profile_owner(), 'auto_save_draft')) ? "true" : "false"); + $permanent_draft = ((intval($conv->get_profile_owner()) === intval(local_channel()) && Apps::system_app_installed($conv->get_profile_owner(), 'Drafts')) ? ('Save draft') : EMPTY_STR); + + + + $comment_box = replace_macros($template, array( + '$return_path' => '', + '$threaded' => $this->is_threaded(), + '$jsreload' => $conv->reload, + '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'), + '$id' => $this->get_id(), + '$parent' => $this->get_id(), + '$comment_buttons' => $comment_buttons, + '$profile_uid' => $conv->get_profile_owner(), + '$mylink' => $observer['xchan_url'], + '$mytitle' => t('This is you'), + '$myphoto' => $observer['xchan_photo_s'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$edat' => EMPTY_STR, + '$edbold' => t('Bold'), + '$editalic' => t('Italic'), + '$eduline' => t('Underline'), + '$edquote' => t('Quote'), + '$edcode' => t('Code'), + '$edimg' => t('Image'), + '$edatt' => t('Attach/Upload file'), + '$edurl' => t('Insert Link'), + '$edvideo' => t('Video'), + '$preview' => t('Preview'), + '$reset' => t('Reset'), + '$indent' => $indent, + '$can_upload' => (perm_is_allowed($conv->get_profile_owner(), get_observer_hash(), 'write_storage') && $conv->is_uploadable()), + '$feature_encrypt' => ((Apps::system_app_installed($conv->get_profile_owner(), 'Secrets')) ? true : false), + '$feature_markup' => ((Apps::system_app_installed($conv->get_profile_owner(), 'Markup')) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $conv->get_cipher(), + '$sourceapp' => App::$sourcename, + '$observer' => get_observer_hash(), + '$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(), '', 'post_comments')) ? true : false), + '$anonname' => [ 'anonname', t('Your full name (required)') ], + '$anonmail' => [ 'anonmail', t('Your email address (required)') ], + '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ], + '$auto_save_draft' => $feature_auto_save_draft, + '$save' => $permanent_draft, + '$top' => $this->is_toplevel() + )); + + return $comment_box; + } + + private function get_redirect_url() + { + return $this->redirect_url; + } + + /** + * Check if we are a wall to wall item and set the relevant properties + */ + protected function check_wall_to_wall() + { + $conv = $this->get_conversation(); + $this->wall_to_wall = false; + $this->owner_url = ''; + $this->owner_photo = ''; + $this->owner_name = ''; + $this->owner_censored = false; + + if ($conv->get_mode() === 'channel') { + return; + } + + if ($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) { + $this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']); + $this->owner_photo = $this->data['owner']['xchan_photo_m']; + $this->owner_name = $this->data['owner']['xchan_name']; + $this->wall_to_wall = true; + } + + // present friend-of-friend conversations from hyperdrive as relayed posts from the first friend + // we find among the respondents. + + if ($this->is_toplevel() && (! $this->data['owner']['abook_id'])) { + if ($this->data['children']) { + $friend = $this->find_a_friend($this->data['children']); + if ($friend) { + $this->owner_url = $friend['url']; + $this->owner_photo = $friend['photo']; + $this->owner_name = $friend['name']; + $this->owner_censored = $friend['censored']; + $this->wall_to_wall = true; + } + } + } + } + + private function find_a_friend($items) + { + $ret = null; + if ($items) { + foreach ($items as $child) { + if ($child['author']['abook_id'] && (! intval($child['author']['abook_self']))) { + return [ + 'url' => chanlink_hash($child['author']['xchan_hash']), + 'photo' => $child['author']['xchan_photo_m'], + 'name' => $child['author']['xchan_name'], + 'censored' => (($child['author']['xchan_censored'] || $child['author']['abook_censor']) ? true : false) + ]; + if ($child['children']) { + $ret = $this->find_a_friend($child['children']); + if ($ret) { + break; + } + } + } + } + } + return $ret; + } + + + private function is_wall_to_wall() + { + return $this->wall_to_wall; + } + + private function get_owner_url() + { + return $this->owner_url; + } + + private function get_owner_photo() + { + return $this->owner_photo; + } + + private function get_owner_name() + { + return $this->owner_name; + } + + private function is_visiting() + { + return $this->visiting; + } } - diff --git a/Zotlabs/Lib/ThreadListener.php b/Zotlabs/Lib/ThreadListener.php index ed2ed8f48..1bf4cbe98 100644 --- a/Zotlabs/Lib/ThreadListener.php +++ b/Zotlabs/Lib/ThreadListener.php @@ -2,52 +2,62 @@ namespace Zotlabs\Lib; -class ThreadListener { +class ThreadListener +{ - public static function store($target_id, $portable_id, $ltype = 0) { - $x = self::fetch($target_id,$portable_id,$ltype = 0); - if(! $x) { - $r = q("insert into listeners ( target_id, portable_id, ltype ) values ( '%s', '%s' , %d ) ", - dbesc($target_id), - dbesc($portable_id), - intval($ltype) - ); - } - } + public static function store($target_id, $portable_id, $ltype = 0) + { + $x = self::fetch($target_id, $portable_id, $ltype = 0); + if (! $x) { + $r = q( + "insert into listeners ( target_id, portable_id, ltype ) values ( '%s', '%s' , %d ) ", + dbesc($target_id), + dbesc($portable_id), + intval($ltype) + ); + } + } - public static function fetch($target_id, $portable_id, $ltype = 0) { - $x = q("select * from listeners where target_id = '%s' and portable_id = '%s' and ltype = %d limit 1", - dbesc($target_id), - dbesc($portable_id), - intval($ltype) - ); - if($x) { - return $x[0]; - } - return false; - } + public static function fetch($target_id, $portable_id, $ltype = 0) + { + $x = q( + "select * from listeners where target_id = '%s' and portable_id = '%s' and ltype = %d limit 1", + dbesc($target_id), + dbesc($portable_id), + intval($ltype) + ); + if ($x) { + return $x[0]; + } + return false; + } - public static function fetch_by_target($target_id, $ltype = 0) { - $x = q("select * from listeners where target_id = '%s' and ltype = %d", - dbesc($target_id), - intval($ltype) - ); + public static function fetch_by_target($target_id, $ltype = 0) + { + $x = q( + "select * from listeners where target_id = '%s' and ltype = %d", + dbesc($target_id), + intval($ltype) + ); - return $x; - } + return $x; + } - public static function delete_by_target($target_id, $ltype = 0) { - return q("delete from listeners where target_id = '%s' and ltype = %d", - dbesc($target_id), - intval($ltype) - ); - } - - public static function delete_by_pid($portable_id, $ltype = 0) { - return q("delete from listeners where portable_id = '%s' and ltype = %d", - dbesc($portable_id), - intval($ltype) - ); - } + public static function delete_by_target($target_id, $ltype = 0) + { + return q( + "delete from listeners where target_id = '%s' and ltype = %d", + dbesc($target_id), + intval($ltype) + ); + } + public static function delete_by_pid($portable_id, $ltype = 0) + { + return q( + "delete from listeners where portable_id = '%s' and ltype = %d", + dbesc($portable_id), + intval($ltype) + ); + } } diff --git a/Zotlabs/Lib/ThreadStream.php b/Zotlabs/Lib/ThreadStream.php index 092e572a0..bbbb882e6 100644 --- a/Zotlabs/Lib/ThreadStream.php +++ b/Zotlabs/Lib/ThreadStream.php @@ -1,4 +1,6 @@ -set_mode($mode); - $this->preview = $preview; - $this->uploadable = $uploadable; - $this->prepared_item = $prepared_item; - $c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : ''); - if($c) - $this->cipher = $c; - } + public function __construct($mode, $preview, $uploadable, $prepared_item = '') + { + $this->set_mode($mode); + $this->preview = $preview; + $this->uploadable = $uploadable; + $this->prepared_item = $prepared_item; + $c = ((local_channel()) ? get_pconfig(local_channel(), 'system', 'default_cipher') : ''); + if ($c) { + $this->cipher = $c; + } + } - /** - * Set the mode we'll be displayed on - */ - private function set_mode($mode) { - if($this->get_mode() == $mode) - return; + /** + * Set the mode we'll be displayed on + */ + private function set_mode($mode) + { + if ($this->get_mode() == $mode) { + return; + } - $this->observer = App::get_observer(); - $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); + $this->observer = App::get_observer(); + $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); - switch($mode) { - case 'stream': - $this->profile_owner = local_channel(); - $this->writable = true; - break; - case 'pubstream': - $this->profile_owner = local_channel(); - $this->writable = ((local_channel()) ? true : false); - break; - case 'hq': - $this->profile_owner = local_channel(); - $this->writable = true; - break; - case 'channel': - $this->profile_owner = App::$profile['profile_uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - break; - case 'cards': - $this->profile_owner = App::$profile['profile_uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - $this->reload = $_SESSION['return_url']; - break; - case 'articles': - $this->profile_owner = App::$profile['profile_uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - $this->reload = $_SESSION['return_url']; - break; - case 'display': - // in this mode we set profile_owner after initialisation (from conversation()) and then - // pull some trickery which allows us to re-invoke this function afterward - // it's an ugly hack so @FIXME - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - $this->uploadable = perm_is_allowed($this->profile_owner,$ob_hash,'write_storage'); - break; - case 'page': - $this->profile_owner = App::$profile['uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - break; - default: - logger('[ERROR] Conversation::set_mode : Unhandled mode ('. $mode .').', LOGGER_DEBUG); - return false; - break; - } - $this->mode = $mode; - } + switch ($mode) { + case 'stream': + $this->profile_owner = local_channel(); + $this->writable = true; + break; + case 'pubstream': + $this->profile_owner = local_channel(); + $this->writable = ((local_channel()) ? true : false); + break; + case 'hq': + $this->profile_owner = local_channel(); + $this->writable = true; + break; + case 'channel': + $this->profile_owner = App::$profile['profile_uid']; + $this->writable = perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments'); + break; + case 'cards': + $this->profile_owner = App::$profile['profile_uid']; + $this->writable = perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments'); + $this->reload = $_SESSION['return_url']; + break; + case 'articles': + $this->profile_owner = App::$profile['profile_uid']; + $this->writable = perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments'); + $this->reload = $_SESSION['return_url']; + break; + case 'display': + // in this mode we set profile_owner after initialisation (from conversation()) and then + // pull some trickery which allows us to re-invoke this function afterward + // it's an ugly hack so @FIXME + $this->writable = perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments'); + $this->uploadable = perm_is_allowed($this->profile_owner, $ob_hash, 'write_storage'); + break; + case 'page': + $this->profile_owner = App::$profile['uid']; + $this->writable = perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments'); + break; + default: + logger('[ERROR] Conversation::set_mode : Unhandled mode (' . $mode . ').', LOGGER_DEBUG); + return false; + break; + } + $this->mode = $mode; + } - /** - * Get mode - */ - public function get_mode() { - return $this->mode; - } + /** + * Get mode + */ + public function get_mode() + { + return $this->mode; + } - /** - * Check if page is writable - */ - public function is_writable() { - return $this->writable; - } + /** + * Check if page is writable + */ + public function is_writable() + { + return $this->writable; + } - public function is_commentable() { - return $this->commentable; - } + public function is_commentable() + { + return $this->commentable; + } - public function is_uploadable() { - return $this->uploadable; - } + public function is_uploadable() + { + return $this->uploadable; + } - /** - * Check if page is a preview - */ - public function is_preview() { - return $this->preview; - } + /** + * Check if page is a preview + */ + public function is_preview() + { + return $this->preview; + } - /** - * Get profile owner - */ - public function get_profile_owner() { - return $this->profile_owner; - } + /** + * Get profile owner + */ + public function get_profile_owner() + { + return $this->profile_owner; + } - public function set_profile_owner($uid) { - $this->profile_owner = $uid; - $mode = $this->get_mode(); - $this->mode = null; - $this->set_mode($mode); - } + public function set_profile_owner($uid) + { + $this->profile_owner = $uid; + $mode = $this->get_mode(); + $this->mode = null; + $this->set_mode($mode); + } - public function get_observer() { - return $this->observer; - } + public function get_observer() + { + return $this->observer; + } - public function get_cipher() { - return $this->cipher; - } + public function get_cipher() + { + return $this->cipher; + } - /** - * Add a thread to the conversation - * - * Returns: - * _ The inserted item on success - * _ false on failure - */ - public function add_thread($item) { - $item_id = $item->get_id(); - if(!$item_id) { - logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR); - return false; - } - if($this->get_thread($item->get_id())) { - logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING); - return false; - } + /** + * Add a thread to the conversation + * + * Returns: + * _ The inserted item on success + * _ false on failure + */ + public function add_thread($item) + { + $item_id = $item->get_id(); + if (!$item_id) { + logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR); + return false; + } + if ($this->get_thread($item->get_id())) { + logger('Thread already exists (' . $item->get_id() . ').', LOGGER_DEBUG, LOG_WARNING); + return false; + } - /* - * Only add things that will be displayed - */ - - - if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) { - return false; - } - - $item->set_commentable(false); - $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); - - if(! comments_are_now_closed($item->get_data())) { - if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash)) - $item->set_commentable(true); - - if(intval($item->get_data_value('item_nocomment'))) { - $item->set_commentable(false); - } - elseif(! $item->is_commentable()) { - if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self'])) - $item->set_commentable(perm_is_allowed($this->profile_owner,$ob_hash,'post_comments')); - else - $item->set_commentable(can_comment_on_post($ob_hash,$item->data)); - } - } - if($this->mode === 'pubstream' && (! local_channel())) { - $item->set_commentable(false); - } + /* + * Only add things that will be displayed + */ - $item->set_conversation($this); - $this->threads[] = $item; - return end($this->threads); - } + if (($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'), ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'), ACTIVITY_DISLIKE))) { + return false; + } - /** - * Get data in a form usable by a conversation template - * - * We should find a way to avoid using those arguments (at least most of them) - * - * Returns: - * _ The data requested on success - * _ false on failure - */ - public function get_template_data($conv_responses) { - $result = []; + $item->set_commentable(false); + $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); - foreach($this->threads as $item) { + if (! comments_are_now_closed($item->get_data())) { + if (($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash)) { + $item->set_commentable(true); + } - if(($item->get_data_value('id') == $item->get_data_value('parent')) && $this->prepared_item) { - $item_data = $this->prepared_item; - } - else { - $item_data = $item->get_template_data($conv_responses); - } - if(!$item_data) { - logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR); - return false; - } - $result[] = $item_data; - } + if (intval($item->get_data_value('item_nocomment'))) { + $item->set_commentable(false); + } elseif (! $item->is_commentable()) { + if ((array_key_exists('owner', $item->data)) && intval($item->data['owner']['abook_self'])) { + $item->set_commentable(perm_is_allowed($this->profile_owner, $ob_hash, 'post_comments')); + } else { + $item->set_commentable(can_comment_on_post($ob_hash, $item->data)); + } + } + } + if ($this->mode === 'pubstream' && (! local_channel())) { + $item->set_commentable(false); + } - return $result; - } - /** - * Get a thread based on its item id - * - * Returns: - * _ The found item on success - * _ false on failure - */ - private function get_thread($id) { - foreach($this->threads as $item) { - if($item->get_id() == $id) - return $item; - } + $item->set_conversation($this); + $this->threads[] = $item; + return end($this->threads); + } - return false; - } + /** + * Get data in a form usable by a conversation template + * + * We should find a way to avoid using those arguments (at least most of them) + * + * Returns: + * _ The data requested on success + * _ false on failure + */ + public function get_template_data($conv_responses) + { + $result = []; + + foreach ($this->threads as $item) { + if (($item->get_data_value('id') == $item->get_data_value('parent')) && $this->prepared_item) { + $item_data = $this->prepared_item; + } else { + $item_data = $item->get_template_data($conv_responses); + } + if (!$item_data) { + logger('Failed to get item template data (' . $item->get_id() . ').', LOGGER_DEBUG, LOG_ERR); + return false; + } + $result[] = $item_data; + } + + return $result; + } + + /** + * Get a thread based on its item id + * + * Returns: + * _ The found item on success + * _ false on failure + */ + private function get_thread($id) + { + foreach ($this->threads as $item) { + if ($item->get_id() == $id) { + return $item; + } + } + + return false; + } } diff --git a/Zotlabs/Lib/Verify.php b/Zotlabs/Lib/Verify.php index e1b8f9b2a..04b4114eb 100644 --- a/Zotlabs/Lib/Verify.php +++ b/Zotlabs/Lib/Verify.php @@ -2,13 +2,13 @@ namespace Zotlabs\Lib; - class Verify { public static function create($type, $channel_id, $token, $meta) { - return q("insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )", + return q( + "insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )", dbesc($type), intval($channel_id), dbesc($token), @@ -19,14 +19,16 @@ class Verify public static function match($type, $channel_id, $token, $meta) { - $r = q("select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1", + $r = q( + "select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1", dbesc($type), intval($channel_id), dbesc($token), dbesc($meta) ); if ($r) { - q("delete from verify where id = %d", + q( + "delete from verify where id = %d", intval($r[0]['id']) ); return true; @@ -36,13 +38,15 @@ class Verify public static function get_meta($type, $channel_id, $token) { - $r = q("select id, meta from verify where vtype = '%s' and channel = %d and token = '%s' limit 1", + $r = q( + "select id, meta from verify where vtype = '%s' and channel = %d and token = '%s' limit 1", dbesc($type), intval($channel_id), dbesc($token) ); if ($r) { - q("delete from verify where id = %d", + q( + "delete from verify where id = %d", intval($r[0]['id']) ); return $r[0]['meta']; @@ -58,11 +62,11 @@ class Verify */ public static function purge($type, $interval) { - q("delete from verify where vtype = '%s' and created < ( %s - INTERVAL %s )", + q( + "delete from verify where vtype = '%s' and created < ( %s - INTERVAL %s )", dbesc($type), db_utcnow(), db_quoteinterval($interval) ); } - -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/Webfinger.php b/Zotlabs/Lib/Webfinger.php index fa7aac96c..10d67b62b 100644 --- a/Zotlabs/Lib/Webfinger.php +++ b/Zotlabs/Lib/Webfinger.php @@ -105,4 +105,4 @@ class Webfinger } return false; } -} \ No newline at end of file +} diff --git a/Zotlabs/Lib/XConfig.php b/Zotlabs/Lib/XConfig.php index 0b20b7b5c..a9d86fc88 100644 --- a/Zotlabs/Lib/XConfig.php +++ b/Zotlabs/Lib/XConfig.php @@ -24,153 +24,169 @@ use App; * $var = get_xconfig($observer, 'category', 'key'); * }@endcode */ -class XConfig { +class XConfig +{ - /** - * @brief Loads a full xchan's configuration into a cached storage. - * - * All configuration values of the given observer hash are stored in global - * cache which is available under the global variable App::$config[$xchan]. - * - * @param string $xchan - * The observer's hash - * @return void|false Returns false if xchan is not set - */ - public static function Load($xchan) { + /** + * @brief Loads a full xchan's configuration into a cached storage. + * + * All configuration values of the given observer hash are stored in global + * cache which is available under the global variable App::$config[$xchan]. + * + * @param string $xchan + * The observer's hash + * @return void|false Returns false if xchan is not set + */ + public static function Load($xchan) + { - if(! $xchan) - return false; + if (! $xchan) { + return false; + } - if(! array_key_exists($xchan, App::$config)) - App::$config[$xchan] = []; + if (! array_key_exists($xchan, App::$config)) { + App::$config[$xchan] = []; + } - $r = q("SELECT * FROM xconfig WHERE xchan = '%s'", - dbesc($xchan) - ); + $r = q( + "SELECT * FROM xconfig WHERE xchan = '%s'", + dbesc($xchan) + ); - if($r) { - foreach($r as $rr) { - $k = $rr['k']; - $c = $rr['cat']; - if(! array_key_exists($c, App::$config[$xchan])) { - App::$config[$xchan][$c] = []; - App::$config[$xchan][$c]['config_loaded'] = true; - } - App::$config[$xchan][$c][$k] = $rr['v']; - } - } - } + if ($r) { + foreach ($r as $rr) { + $k = $rr['k']; + $c = $rr['cat']; + if (! array_key_exists($c, App::$config[$xchan])) { + App::$config[$xchan][$c] = []; + App::$config[$xchan][$c]['config_loaded'] = true; + } + App::$config[$xchan][$c][$k] = $rr['v']; + } + } + } - /** - * @brief Get a particular observer's config variable given the category - * name ($family) and a key. - * - * Get a particular observer's config value from the given category ($family) - * and the $key from a cached storage in App::$config[$xchan]. - * - * Returns false if not set. - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @param bool $default (optional) default false - * @return mixed Stored $value or false if it does not exist - */ - public static function Get($xchan, $family, $key, $default = false) { + /** + * @brief Get a particular observer's config variable given the category + * name ($family) and a key. + * + * Get a particular observer's config value from the given category ($family) + * and the $key from a cached storage in App::$config[$xchan]. + * + * Returns false if not set. + * + * @param string $xchan + * The observer's hash + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to query + * @param bool $default (optional) default false + * @return mixed Stored $value or false if it does not exist + */ + public static function Get($xchan, $family, $key, $default = false) + { - if(! $xchan) - return $default; + if (! $xchan) { + return $default; + } - if(! array_key_exists($xchan, App::$config)) - load_xconfig($xchan); + if (! array_key_exists($xchan, App::$config)) { + load_xconfig($xchan); + } - if((! array_key_exists($family, App::$config[$xchan])) || (! array_key_exists($key, App::$config[$xchan][$family]))) - return $default; + if ((! array_key_exists($family, App::$config[$xchan])) || (! array_key_exists($key, App::$config[$xchan][$family]))) { + return $default; + } - return unserialise(App::$config[$xchan][$family][$key]); - } + return unserialise(App::$config[$xchan][$family][$key]); + } - /** - * @brief Sets a configuration value for an observer. - * - * Stores a config value ($value) in the category ($family) under the key ($key) - * for the observer's $xchan hash. - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to set - * @param string $value - * The value to store - * @return mixed Stored $value or false - */ - public static function Set($xchan, $family, $key, $value) { + /** + * @brief Sets a configuration value for an observer. + * + * Stores a config value ($value) in the category ($family) under the key ($key) + * for the observer's $xchan hash. + * + * @param string $xchan + * The observer's hash + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to set + * @param string $value + * The value to store + * @return mixed Stored $value or false + */ + public static function Set($xchan, $family, $key, $value) + { - // manage array value - $dbvalue = ((is_array($value)) ? serialise($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + // manage array value + $dbvalue = ((is_array($value)) ? serialise($value) : $value); + $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - if(self::Get($xchan, $family, $key) === false) { - if(! array_key_exists($xchan, App::$config)) - App::$config[$xchan] = []; - if(! array_key_exists($family, App::$config[$xchan])) - App::$config[$xchan][$family] = []; + if (self::Get($xchan, $family, $key) === false) { + if (! array_key_exists($xchan, App::$config)) { + App::$config[$xchan] = []; + } + if (! array_key_exists($family, App::$config[$xchan])) { + App::$config[$xchan][$family] = []; + } - $ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' )", - dbesc($xchan), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - } - else { - $ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'", - dbesc($dbvalue), - dbesc($xchan), - dbesc($family), - dbesc($key) - ); - } + $ret = q( + "INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' )", + dbesc($xchan), + dbesc($family), + dbesc($key), + dbesc($dbvalue) + ); + } else { + $ret = q( + "UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'", + dbesc($dbvalue), + dbesc($xchan), + dbesc($family), + dbesc($key) + ); + } - App::$config[$xchan][$family][$key] = $value; + App::$config[$xchan][$family][$key] = $value; - if($ret) - return $value; + if ($ret) { + return $value; + } - return $ret; - } + return $ret; + } - /** - * @brief Deletes the given key from the observer's config. - * - * Removes the configured value from the stored cache in App::$config[$xchan] - * and removes it from the database. - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to delete - * @return mixed - */ - public static function Delete($xchan, $family, $key) { + /** + * @brief Deletes the given key from the observer's config. + * + * Removes the configured value from the stored cache in App::$config[$xchan] + * and removes it from the database. + * + * @param string $xchan + * The observer's hash + * @param string $family + * The category of the configuration value + * @param string $key + * The configuration key to delete + * @return mixed + */ + public static function Delete($xchan, $family, $key) + { - if(isset(App::$config[$xchan]) && isset(App::$config[$xchan][$family]) && isset(App::$config[$xchan][$family][$key])) - unset(App::$config[$xchan][$family][$key]); + if (isset(App::$config[$xchan]) && isset(App::$config[$xchan][$family]) && isset(App::$config[$xchan][$family][$key])) { + unset(App::$config[$xchan][$family][$key]); + } - $ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'", - dbesc($xchan), - dbesc($family), - dbesc($key) - ); - - return $ret; - } + $ret = q( + "DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'", + dbesc($xchan), + dbesc($family), + dbesc($key) + ); + return $ret; + } } diff --git a/Zotlabs/Lib/ZotURL.php b/Zotlabs/Lib/ZotURL.php index 5110410dc..1c221cb95 100644 --- a/Zotlabs/Lib/ZotURL.php +++ b/Zotlabs/Lib/ZotURL.php @@ -4,123 +4,123 @@ namespace Zotlabs\Lib; use Zotlabs\Web\HTTPSig; +class ZotURL +{ -class ZotURL { + public static function fetch($url, $channel, $hub = null) + { - public static function fetch($url, $channel, $hub = null) { + $ret = [ 'success' => false ]; - $ret = [ 'success' => false ]; - - if(strpos($url,'x-zot:') !== 0) { - return $ret; - } + if (strpos($url, 'x-zot:') !== 0) { + return $ret; + } - if(! $url) { - return $ret; - } + if (! $url) { + return $ret; + } - $portable_url = substr($url,6); - $u = explode('/',$portable_url); - $portable_id = $u[0]; + $portable_url = substr($url, 6); + $u = explode('/', $portable_url); + $portable_id = $u[0]; - $hosts = self::lookup($portable_id,$hub); + $hosts = self::lookup($portable_id, $hub); - if(! $hosts) { - return $ret; - } + if (! $hosts) { + return $ret; + } - foreach($hosts as $h) { - $newurl = $h . '/id/' . $portable_url; + foreach ($hosts as $h) { + $newurl = $h . '/id/' . $portable_url; - $m = parse_url($newurl); + $m = parse_url($newurl); - $data = json_encode([ 'zot_token' => random_string() ]); + $data = json_encode([ 'zot_token' => random_string() ]); - if($channel && $m) { + if ($channel && $m) { + $headers = [ + 'Accept' => 'application/x-zot+json', + 'Content-Type' => 'application/x-zot+json', + 'X-Zot-Token' => random_string(), + 'Digest' => HTTPSig::generate_digest_header($data), + 'Host' => $m['host'], + '(request-target)' => 'post ' . get_request_string($newurl) + ]; + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false); + } else { + $h = [ 'Accept: application/x-zot+json' ]; + } - $headers = [ - 'Accept' => 'application/x-zot+json', - 'Content-Type' => 'application/x-zot+json', - 'X-Zot-Token' => random_string(), - 'Digest' => HTTPSig::generate_digest_header($data), - 'Host' => $m['host'], - '(request-target)' => 'post ' . get_request_string($newurl) - ]; - $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false); - } - else { - $h = [ 'Accept: application/x-zot+json' ]; - } - - $result = []; + $result = []; - $redirects = 0; - $x = z_post_url($newurl,$data,$redirects, [ 'headers' => $h ] ); - if($x['success']) { - return $x; - } - } + $redirects = 0; + $x = z_post_url($newurl, $data, $redirects, [ 'headers' => $h ]); + if ($x['success']) { + return $x; + } + } - return $ret; + return $ret; + } - } + public static function is_zoturl($s) + { - public static function is_zoturl($s) { - - if(strpos($url,'x-zot:') === 0) { - return true; - } - return false; - } + if (strpos($url, 'x-zot:') === 0) { + return true; + } + return false; + } - public static function lookup($portable_id, $hub) { + public static function lookup($portable_id, $hub) + { - $r = q("select * from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and site_dead = 0 order by hubloc_primary desc", - dbesc($portable_id) - ); + $r = q( + "select * from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and site_dead = 0 order by hubloc_primary desc", + dbesc($portable_id) + ); - if(! $r) { + if (! $r) { + // extend to network lookup - // extend to network lookup + $path = '/q/' . $portable_id; - $path = '/q/' . $portable_id; + // first check sending hub since they have recently communicated with this object - // first check sending hub since they have recently communicated with this object + $redirects = 0; - $redirects = 0; + if ($hub) { + $x = z_fetch_url($hub['hubloc_url'] . $path, false, $redirects); + $u = self::parse_response($x); + if ($u) { + return $u; + } + } - if($hub) { - $x = z_fetch_url($hub['hubloc_url'] . $path, false, $redirects); - $u = self::parse_response($x); - if($u) { - return $u; - } - } + // If this fails, fallback on directory servers - // If this fails, fallback on directory servers - - return false; - } - return ids_to_array($r,'hubloc_url'); - } + return false; + } + return ids_to_array($r, 'hubloc_url'); + } - public static function parse_response($arr) { - if(! $arr['success']) { - return false; - } - $a = json_decode($arr['body'],true); - if($a['success'] && array_key_exists('results', $a) && is_array($a['results']) && count($a['results'])) { - foreach($a['results'] as $b) { - $m = discover_by_webbie($b); - if($m) { - return([ $b ]); - } - } - } - return false; - } - -} \ No newline at end of file + public static function parse_response($arr) + { + if (! $arr['success']) { + return false; + } + $a = json_decode($arr['body'], true); + if ($a['success'] && array_key_exists('results', $a) && is_array($a['results']) && count($a['results'])) { + foreach ($a['results'] as $b) { + $m = discover_by_webbie($b); + if ($m) { + return([ $b ]); + } + } + } + return false; + } +} diff --git a/Zotlabs/Lib/Zotfinger.php b/Zotlabs/Lib/Zotfinger.php index 9ebc7e0c8..4d7d2fd7b 100644 --- a/Zotlabs/Lib/Zotfinger.php +++ b/Zotlabs/Lib/Zotfinger.php @@ -24,7 +24,6 @@ class Zotfinger $data = json_encode(['zot_token' => random_string()]); if ($channel && $m) { - $headers = [ 'Accept' => 'application/x-zot+json', 'Content-Type' => 'application/x-zot+json', @@ -44,7 +43,6 @@ class Zotfinger $x = z_post_url($resource, $data, $redirects, ['headers' => $h]); if ($x['success']) { - if ($verify) { $result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6'); } @@ -60,5 +58,4 @@ class Zotfinger return false; } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 76661a00d..e0f764ae9 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -70,11 +70,11 @@ class Acl extends Controller $permitted = []; if (in_array($type, ['m', 'a', 'f'])) { - // These queries require permission checking. We'll create a simple array of xchan_hash for those with // the requisite permissions which we can check against. - $x = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s'", + $x = q( + "select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s'", intval(local_channel()), dbesc(($type === 'm') ? '%post_mail%' : '%tag_deliver%') ); @@ -102,8 +102,6 @@ class Acl extends Controller $sql_extra3 = "AND ( xchan_addr like " . protect_sprintf("'%" . dbesc(punify($search)) . "%'") . " OR xchan_name like " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR abook_alias like " . protect_sprintf("'%" . dbesc($search) . "%'") . " ) "; $sql_extra4 = "AND ( xchan_name LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR xchan_addr LIKE " . protect_sprintf("'%" . dbesc(punify($search)) . ((strpos($search, '@') === false) ? "%@%'" : "%'")) . " OR abook_alias LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . ") "; - - } else { $sql_extra = $sql_extra2 = $sql_extra3 = $sql_extra4 = ""; } @@ -113,10 +111,10 @@ class Acl extends Controller $contacts = []; if ($type == '' || $type == 'g') { - // Normal privacy groups - $r = q("SELECT pgrp.id, pgrp.hash, pgrp.gname + $r = q( + "SELECT pgrp.id, pgrp.hash, pgrp.gname FROM pgrp, pgrp_member WHERE pgrp.deleted = 0 AND pgrp.uid = %d AND pgrp_member.gid = pgrp.id @@ -131,7 +129,7 @@ class Acl extends Controller if ($r) { foreach ($r as $g) { - // logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(),$g['id'])); + // logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(),$g['id'])); $groups[] = [ "type" => "g", "photo" => "images/twopeople.png", @@ -146,40 +144,36 @@ class Acl extends Controller } if ($type == '' || $type == 'c' || $type === 'f') { - // Getting info from the abook is better for local users because it contains info about permissions if (local_channel()) { - // add connections - $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, xchan_type, abook_flags, abook_self + $r = q( + "SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, xchan_type, abook_flags, abook_self FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra4 order by xchan_name asc limit $count", intval(local_channel()) ); - } else { // Visitors - $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_flags, 0 as abook_self + $r = q( + "SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_flags, 0 as abook_self FROM xchan left join xlink on xlink_link = xchan_hash WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc limit $count", dbesc(get_observer_hash()) ); - } if ((count($r) < 100) && $type == 'c') { $r2 = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_flags, 0 as abook_self - FROM xchan WHERE xchan_deleted = 0 and xchan_network != 'unknown' $sql_extra2 order by $order_extra2 xchan_name asc limit $count" - ); + FROM xchan WHERE xchan_deleted = 0 and xchan_network != 'unknown' $sql_extra2 order by $order_extra2 xchan_name asc limit $count"); if ($r2) { $r = array_merge($r, $r2); $r = unique_multidim_array($r, 'hash'); } } - } elseif ($type == 'm') { - $r = []; - $z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url + $z = q( + "SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and xchan_deleted = 0 @@ -194,19 +188,18 @@ class Acl extends Controller } } } - } elseif ($type == 'a') { - - $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag FROM abook left join xchan on abook_xchan = xchan_hash + $r = q( + "SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and xchan_deleted = 0 $sql_extra3 ORDER BY xchan_name ASC ", intval(local_channel()) ); - } elseif ($type == 'z') { - $r = q("SELECT xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag FROM xchan left join abook on xchan_hash = abook_xchan + $r = q( + "SELECT xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag FROM xchan left join abook on xchan_hash = abook_xchan WHERE ( abook_channel = %d OR abook_channel IS NULL ) and xchan_deleted = 0 $sql_extra3 @@ -240,7 +233,6 @@ class Acl extends Controller if ($r) { foreach ($r as $g) { - if (isset($g['network']) && in_array($g['network'], ['rss', 'anon', 'unknown']) && ($type != 'a')) { continue; } @@ -301,7 +293,7 @@ class Acl extends Controller public function navbar_complete() { - // logger('navbar_complete'); + // logger('navbar_complete'); if (observer_prohibited()) { return; diff --git a/Zotlabs/Module/Activity.php b/Zotlabs/Module/Activity.php index 1051ace07..84d45de7d 100644 --- a/Zotlabs/Module/Activity.php +++ b/Zotlabs/Module/Activity.php @@ -1,4 +1,5 @@ [ ACTIVITYSTREAMS_JSONLD_REV, @@ -279,11 +293,9 @@ class Activity extends Controller HTTPSig::set_headers($h); echo $ret; killme(); - } goaway(z_root() . '/item/' . argv(1)); } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index b7f1f733f..dcba31e2d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1,4 +1,5 @@ 0 THEN 1 ELSE NULL END) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires > '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account", + $r = q( + "SELECT COUNT(CASE WHEN account_id > 0 THEN 1 ELSE NULL END) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires > '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account", db_utcnow(), db_utcnow(), dbesc(NULL_DATE), @@ -127,7 +128,8 @@ class Admin extends Controller // pending registrations - $pdg = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ", + $pdg = q( + "SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ", intval(ACCOUNT_PENDING) ); @@ -189,5 +191,4 @@ class Admin extends Controller '$build' => Config::Get('system', 'db_version') ]); } - } diff --git a/Zotlabs/Module/Admin/Account_edit.php b/Zotlabs/Module/Admin/Account_edit.php index 5f3847c34..00262f8fa 100644 --- a/Zotlabs/Module/Admin/Account_edit.php +++ b/Zotlabs/Module/Admin/Account_edit.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module\Admin; - class Account_edit { @@ -11,38 +10,42 @@ class Account_edit $account_id = $_REQUEST['aid']; - if (!$account_id) + if (!$account_id) { return; + } $pass1 = trim($_REQUEST['pass1']); $pass2 = trim($_REQUEST['pass2']); if ($pass1 && $pass2 && ($pass1 === $pass2)) { $salt = random_string(32); $password_encoded = hash('whirlpool', $salt . $pass1); - $r = q("update account set account_salt = '%s', account_password = '%s', + $r = q( + "update account set account_salt = '%s', account_password = '%s', account_password_changed = '%s' where account_id = %d", dbesc($salt), dbesc($password_encoded), dbesc(datetime_convert()), intval($account_id) ); - if ($r) + if ($r) { info(sprintf(t('Password changed for account %d.'), $account_id) . EOL); - + } } $service_class = trim($_REQUEST['service_class']); $account_language = trim($_REQUEST['account_language']); - $r = q("update account set account_service_class = '%s', account_language = '%s' + $r = q( + "update account set account_service_class = '%s', account_language = '%s' where account_id = %d", dbesc($service_class), dbesc($account_language), intval($account_id) ); - if ($r) + if ($r) { info(t('Account settings updated.') . EOL); + } goaway(z_root() . '/admin/accounts'); } @@ -50,10 +53,12 @@ class Account_edit public function get() { - if (argc() > 2) + if (argc() > 2) { $account_id = argv(2); + } - $x = q("select * from account where account_id = %d limit 1", + $x = q( + "select * from account where account_id = %d limit 1", intval($account_id) ); @@ -71,13 +76,8 @@ class Account_edit '$account_language' => ['account_language', t('Account language (for emails)'), $x[0]['account_language'], '', language_list()], '$service_class' => ['service_class', t('Service class'), $x[0]['account_service_class'], ''], '$submit' => t('Submit'), - ] - ); + ]); return $a; - - } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php index 1c703c93d..b59e33bee 100644 --- a/Zotlabs/Module/Admin/Accounts.php +++ b/Zotlabs/Module/Admin/Accounts.php @@ -31,7 +31,8 @@ class Accounts for ($i = 0; $i < count($users); $i++) { // if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag $op = ($blocked[$i]) ? '& ~' : '| '; - q("UPDATE account SET account_flags = (account_flags $op %d) WHERE account_id = %d", + q( + "UPDATE account SET account_flags = (account_flags $op %d) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($users[$i]) ); @@ -78,7 +79,8 @@ class Accounts { if (argc() > 2) { $uid = argv(3); - $account = q("SELECT * FROM account WHERE account_id = %d", + $account = q( + "SELECT * FROM account WHERE account_id = %d", intval($uid) ); @@ -97,7 +99,8 @@ class Accounts notice(sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL); break; case 'block': - q("UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d", + q( + "UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($uid) ); @@ -105,7 +108,8 @@ class Accounts notice(sprintf(t("Account '%s' blocked"), $account[0]['account_email']) . EOL); break; case 'unblock': - q("UPDATE account SET account_flags = ( account_flags & ~ %d ) WHERE account_id = %d", + q( + "UPDATE account SET account_flags = ( account_flags & ~ %d ) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($uid) ); @@ -118,7 +122,8 @@ class Accounts } /* get pending */ - $pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) != 0 ", + $pending = q( + "SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) != 0 ", intval(ACCOUNT_PENDING) ); @@ -141,7 +146,8 @@ class Accounts $base = z_root() . '/admin/accounts?f='; $odir = (($dir === 'asc') ? '0' : '1'); - $users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked, + $users = q( + "SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked, (SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac where true $serviceclass and account_flags != %d order by $key $dir limit %d offset %d ", intval(ACCOUNT_BLOCKED), diff --git a/Zotlabs/Module/Admin/Addons.php b/Zotlabs/Module/Admin/Addons.php index 5fe8e1c3a..62f57c364 100644 --- a/Zotlabs/Module/Admin/Addons.php +++ b/Zotlabs/Module/Admin/Addons.php @@ -226,7 +226,7 @@ class Addons foreach ($git->git->tree('master') as $object) { if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { $repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash'])); - } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { + } elseif ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { $repo['manifest'] = $git->git->cat->blob($object['hash']); } } @@ -297,8 +297,9 @@ class Addons if ($pinstalled) { @require_once("addon/$plugin/$plugin.php"); - if (function_exists($plugin . '_plugin_admin')) + if (function_exists($plugin . '_plugin_admin')) { goaway(z_root() . '/admin/addons/' . $plugin); + } } goaway(z_root() . '/admin/addons'); } @@ -317,13 +318,14 @@ class Addons if (is_file("addon/$plugin/README.md")) { $readme = file_get_contents("addon/$plugin/README.md"); $readme = MarkdownExtra::defaultTransform($readme); - } else if (is_file("addon/$plugin/README")) { + } elseif (is_file("addon/$plugin/README")) { $readme = "
" . file_get_contents("addon/$plugin/README") . "
"; } $admin_form = ''; - $r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1", + $r = q( + "select * from addon where plugin_admin = 1 and aname = '%s' limit 1", dbesc($plugin) ); @@ -409,7 +411,8 @@ class Addons } $admin_plugins_add_repo_form = replace_macros( - get_markup_template('admin_plugins_addrepo.tpl'), array( + get_markup_template('admin_plugins_addrepo.tpl'), + array( '$post' => 'admin/addons/addrepo', '$desc' => t('Enter the public git repository URL of the addon repo.'), '$repoURL' => array('repoURL', t('Addon repo git URL'), '', ''), @@ -419,7 +422,8 @@ class Addons ); $newRepoModalID = random_string(3); $newRepoModal = replace_macros( - get_markup_template('generic_modal.tpl'), array( + get_markup_template('generic_modal.tpl'), + array( '$id' => $newRepoModalID, '$title' => t('Install new repo'), '$ok' => t('Install'), @@ -480,5 +484,4 @@ class Addons { return (strcmp(strtolower($a[2]['name']), strtolower($b[2]['name']))); } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Channels.php b/Zotlabs/Module/Admin/Channels.php index 78047daf4..b34bcd182 100644 --- a/Zotlabs/Module/Admin/Channels.php +++ b/Zotlabs/Module/Admin/Channels.php @@ -27,7 +27,8 @@ class Channels if (x($_POST, 'page_channels_block')) { foreach ($channels as $uid) { - q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", + q( + "UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", intval(PAGE_CENSORED), intval($uid) ); @@ -37,7 +38,8 @@ class Channels } if (x($_POST, 'page_channels_code')) { foreach ($channels as $uid) { - q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", + q( + "UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", intval(PAGE_ALLOWCODE), intval($uid) ); @@ -63,7 +65,8 @@ class Channels { if (argc() > 2) { $uid = argv(3); - $channel = q("SELECT * FROM channel WHERE channel_id = %d", + $channel = q( + "SELECT * FROM channel WHERE channel_id = %d", intval($uid) ); @@ -80,34 +83,36 @@ class Channels channel_remove($uid, true); notice(sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL); - } + } break; case "block": { check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); $pflags = $channel[0]['channel_pageflags'] ^ PAGE_CENSORED; - q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", + q( + "UPDATE channel SET channel_pageflags = %d where channel_id = %d", intval($pflags), intval($uid) ); Run::Summon(['Directory', $uid, 'nopush']); notice(sprintf((($pflags & PAGE_CENSORED) ? t("Channel '%s' censored") : t("Channel '%s' uncensored")), $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')') . EOL); - } + } break; case "code": { check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); $pflags = $channel[0]['channel_pageflags'] ^ PAGE_ALLOWCODE; - q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", + q( + "UPDATE channel SET channel_pageflags = %d where channel_id = %d", intval($pflags), intval($uid) ); notice(sprintf((($pflags & PAGE_ALLOWCODE) ? t("Channel '%s' code allowed") : t("Channel '%s' code disallowed")), $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')') . EOL); - } + } break; default: @@ -118,8 +123,9 @@ class Channels $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); $dir = 'asc'; - if (array_key_exists('dir', $_REQUEST)) + if (array_key_exists('dir', $_REQUEST)) { $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); + } $base = z_root() . '/admin/channels?f='; $odir = (($dir === 'asc') ? '0' : '1'); @@ -132,22 +138,25 @@ class Channels App::set_pager_itemspage(100); } - $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ", + $channels = q( + "SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']) ); if ($channels) { for ($x = 0; $x < count($channels); $x++) { - if ($channels[$x]['channel_pageflags'] & PAGE_CENSORED) + if ($channels[$x]['channel_pageflags'] & PAGE_CENSORED) { $channels[$x]['blocked'] = true; - else + } else { $channels[$x]['blocked'] = false; + } - if ($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE) + if ($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE) { $channels[$x]['allowcode'] = true; - else + } else { $channels[$x]['allowcode'] = false; + } $channels[$x]['channel_link'] = z_root() . '/channel/' . $channels[$x]['channel_address']; } @@ -187,5 +196,4 @@ class Channels return $o; } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Cover_photo.php b/Zotlabs/Module/Admin/Cover_photo.php index 27b1d390c..d411e92bf 100644 --- a/Zotlabs/Module/Admin/Cover_photo.php +++ b/Zotlabs/Module/Admin/Cover_photo.php @@ -1,4 +1,5 @@ 0 order by imgscale asc LIMIT 1", + $r = q( + "SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale > 0 order by imgscale asc LIMIT 1", dbesc($image_id), intval($channel['channel_id']) ); if ($r) { - $max_thumb = intval(get_config('system', 'max_thumbnail', 1600)); $iscaled = false; if (intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) { $imagick_path = get_config('system', 'imagick_convert_path'); if ($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) { - $fname = dbunescbin($r[0]['content']); $tmp_name = $fname . '-001'; $newsize = photo_calculate_scale(array_merge(getimagesize($fname), ['max' => $max_thumb])); $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $fname) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); - // logger('imagick thumbnail command: ' . $cmd); + // logger('imagick thumbnail command: ' . $cmd); for ($x = 0; $x < 4; $x++) { exec($cmd); if (file_exists($tmp_name)) { @@ -128,14 +128,14 @@ class Cover_photo $im = photo_factory($base_image['content'], $base_image['mimetype']); if ($im->is_valid()) { - // We are scaling and cropping the relative pixel locations to the original photo instead of the // scaled photo we operated on. // First load the scaled photo to check its size. (Should probably pass this in the post form and save // a query.) - $g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3", + $g = q( + "select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3", dbesc($image_id), intval($channel['channel_id']) ); @@ -151,7 +151,8 @@ class Cover_photo // unset all other cover photos - q("update photo set photo_usage = %d where photo_usage = %d and uid = %d", + q( + "update photo set photo_usage = %d where photo_usage = %d and uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_COVER), intval($channel['channel_id']) @@ -196,19 +197,19 @@ class Cover_photo if ($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice(t('Image resize failed.') . EOL); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ", + $x = q( + "delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ", dbesc($base_image['resource_id']), intval($channel['channel_id']) ); return; } - - } else + } else { notice(t('Unable to process image') . EOL); + } } goaway(z_root() . '/admin'); - } @@ -260,7 +261,6 @@ class Cover_photo logger('attach_store: ' . print_r($res, true), LOGGER_DEBUG); json_return_and_die(['message' => $hash]); - } @@ -284,12 +284,14 @@ class Cover_photo $newuser = false; - if (argc() == 3 && argv(1) === 'new') + if (argc() == 3 && argv(1) === 'new') { $newuser = true; + } if (argv(2) === 'reset') { - q("update photo set photo_usage = %d where photo_usage = %d and uid = %d", + q( + "update photo set photo_usage = %d where photo_usage = %d and uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_COVER), intval($channel['channel_id']) @@ -302,11 +304,12 @@ class Cover_photo return; } - // check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); + // check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); $resource_id = argv(3); - $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC", + $r = q( + "SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC", intval($channel['channel_id']), dbesc($resource_id) ); @@ -321,10 +324,10 @@ class Cover_photo } } - $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q( + "SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval($channel['channel_id']) - ); if (!$r) { notice(t('Photo not available.') . EOL); @@ -341,7 +344,8 @@ class Cover_photo $smallest = 0; if ($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0", + $i = q( + "select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0", dbesc($r[0]['resource_id']), intval($channel['channel_id']) ); @@ -359,7 +363,6 @@ class Cover_photo if (!array_key_exists('imagecrop', App::$data)) { - $o .= replace_macros(get_markup_template('admin_cover_photo.tpl'), [ '$user' => $channel['channel_address'], '$channel_id' => $channel['channel_id'], @@ -438,6 +441,4 @@ class Cover_photo App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []); return; } - - } diff --git a/Zotlabs/Module/Admin/Dbsync.php b/Zotlabs/Module/Admin/Dbsync.php index 8d8cda46e..4e7519a0b 100644 --- a/Zotlabs/Module/Admin/Dbsync.php +++ b/Zotlabs/Module/Admin/Dbsync.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module\Admin; - class Dbsync { @@ -15,14 +14,14 @@ class Dbsync // remove the old style config if it exists del_config('database', 'update_r' . intval(argv(3))); set_config('database', '_' . intval(argv(3)), 'success'); - if (intval(get_config('system', 'db_version')) < intval(argv(3))) + if (intval(get_config('system', 'db_version')) < intval(argv(3))) { set_config('system', 'db_version', intval(argv(3))); + } info(t('Update has been marked successful') . EOL); goaway(z_root() . '/admin/dbsync'); } if (argc() > 3 && intval(argv(3)) && argv(2) === 'verify') { - $s = '_' . intval(argv(3)); $cls = '\\Zotlabs\Update\\' . $s; if (class_exists($cls)) { @@ -34,13 +33,15 @@ class Dbsync } elseif ($retval === UPDATE_SUCCESS) { $o .= sprintf(t('Update %s was successfully applied.'), $s); set_config('database', $s, 'success'); - } else + } else { $o .= sprintf(t('Verifying update %s did not return a status. Unknown if it succeeded.'), $s); + } } else { $o .= sprintf(t('Update %s does not contain a verification function.'), $s); } - } else + } else { $o .= sprintf(t('Update function %s could not be found.'), $s); + } return $o; @@ -48,8 +49,9 @@ class Dbsync // remove the old style config if it exists del_config('database', 'update_r' . intval(argv(3))); set_config('database', '_' . intval(argv(3)), 'success'); - if (intval(get_config('system', 'db_version')) < intval(argv(3))) + if (intval(get_config('system', 'db_version')) < intval(argv(3))) { set_config('system', 'db_version', intval(argv(3))); + } info(t('Update has been marked successful') . EOL); goaway(z_root() . '/admin/dbsync'); } @@ -66,10 +68,12 @@ class Dbsync } elseif ($retval === UPDATE_SUCCESS) { $o .= sprintf(t('Update %s was successfully applied.'), $s); set_config('database', $s, 'success'); - } else + } else { $o .= sprintf(t('Update %s did not return a status. It cannot be determined if it was successful.'), $s); - } else + } + } else { $o .= sprintf(t('Update function %s could not be found.'), $s); + } return $o; } @@ -79,8 +83,9 @@ class Dbsync if (count($r)) { foreach ($r as $rr) { $upd = intval(substr($rr['k'], -4)); - if ($rr['v'] === 'success') + if ($rr['v'] === 'success') { continue; + } $failed[] = $upd; } } @@ -100,4 +105,4 @@ class Dbsync return $o; } -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Logs.php b/Zotlabs/Module/Admin/Logs.php index f5c5fa325..e41b80675 100644 --- a/Zotlabs/Module/Admin/Logs.php +++ b/Zotlabs/Module/Admin/Logs.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module\Admin; - class Logs { @@ -64,13 +63,15 @@ class Logs $fstat = fstat($fp); $size = $fstat['size']; if ($size != 0) { - if ($size > 5000000 || $size < 0) + if ($size > 5000000 || $size < 0) { $size = 5000000; + } $seek = fseek($fp, 0 - $size, SEEK_END); if ($seek === 0) { $data = escape_tags(fread($fp, $size)); - while (!feof($fp)) + while (!feof($fp)) { $data .= escape_tags(fread($fp, 4096)); + } } } fclose($fp); @@ -94,6 +95,4 @@ class Logs '$form_security_token' => get_form_security_token('admin_logs'), )); } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Profile_photo.php b/Zotlabs/Module/Admin/Profile_photo.php index a888503ec..bfe966ddb 100644 --- a/Zotlabs/Module/Admin/Profile_photo.php +++ b/Zotlabs/Module/Admin/Profile_photo.php @@ -1,4 +1,5 @@ is_valid()) { - $im->cropImage(300, $srcX, $srcY, $srcW, $srcH); $aid = 0; @@ -144,7 +143,8 @@ class Profile_photo if ($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice(t('Image resize failed.') . EOL); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", + $x = q( + "delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", dbesc($base_image['resource_id']), $channel['channel_id'], intval(PHOTO_RES_PROFILE_300), @@ -155,7 +155,8 @@ class Profile_photo } - $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d + $r = q( + "UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), @@ -169,7 +170,8 @@ class Profile_photo // changed to a generic URL by a clone operation. Otherwise the new photo may // not get pushed to other sites correctly. - $r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' + $r = q( + "UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'", dbesc($im->getType()), dbesc(datetime_convert()), @@ -185,7 +187,6 @@ class Profile_photo Config::Set('system', 'site_icon_url', z_root() . '/photo/profile/m/' . $channel['channel_id']); info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); - } else { notice(t('Unable to process image') . EOL); } @@ -207,7 +208,6 @@ class Profile_photo $hash = $_REQUEST['importfile']; $importing = true; } else { - $matches = []; $partial = false; @@ -256,7 +256,8 @@ class Profile_photo } if (($res && intval($res['data']['is_photo'])) || $importing) { - $i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale", + $i = q( + "select * from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($hash), intval($channel['channel_hash']) ); @@ -330,7 +331,8 @@ class Profile_photo $pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0); - $c = q("select id, is_default from profile where uid = %d", + $c = q( + "select id, is_default from profile where uid = %d", intval($channel['channel_id']) ); @@ -343,7 +345,8 @@ class Profile_photo $_REQUEST['profile'] = $pf; } - $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", + $r = q( + "SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", intval($channel['channel_id']), dbesc($resource_id) ); @@ -362,19 +365,22 @@ class Profile_photo if ($havescale) { // unset any existing profile photos - $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", + $r = q( + "UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval($channel['channel_id']) ); - $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", + $r = q( + "UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", intval(PHOTO_PROFILE), intval($channel['channel_id']), dbesc($resource_id) ); - $r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", + $r = q( + "UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($channel['xchan_hash']) ); @@ -382,10 +388,10 @@ class Profile_photo goaway(z_root() . '/admin'); } - $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q( + "SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval($channel['channel_id']) - ); if (!$r) { notice(t('Photo not available.') . EOL); @@ -402,7 +408,8 @@ class Profile_photo $smallest = 0; if ($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale", + $i = q( + "select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($r[0]['resource_id']), intval($channel['channel_id']) ); @@ -424,12 +431,12 @@ class Profile_photo } // falls through with App::$data['imagecrop'] set so we go straight to the cropping section - } // present an upload form - $profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc", + $profiles = q( + "select id, profile_name as name, is_default from profile where uid = %d order by id asc", intval($channel['channel_id']) ); @@ -448,7 +455,6 @@ class Profile_photo $importing = ((array_key_exists('importfile', App::$data)) ? true : false); if (!array_key_exists('imagecrop', App::$data)) { - $tpl = get_markup_template('admin_profile_photo.tpl'); $o .= replace_macros($tpl, [ @@ -480,7 +486,6 @@ class Profile_photo call_hooks('profile_photo_content_end', $o); return $o; } else { - // present a cropping form $filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution']; diff --git a/Zotlabs/Module/Admin/Profs.php b/Zotlabs/Module/Admin/Profs.php index 9a42444dc..4a09d372c 100644 --- a/Zotlabs/Module/Admin/Profs.php +++ b/Zotlabs/Module/Admin/Profs.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module\Admin; - class Profs { @@ -20,10 +19,11 @@ class Profs } } } - if (!$narr) + if (!$narr) { del_config('system', 'profile_fields_basic'); - else + } else { set_config('system', 'profile_fields_basic', $narr); + } if (array_key_exists('advanced', $_REQUEST)) { @@ -37,11 +37,11 @@ class Profs } } } - if (!$narr) + if (!$narr) { del_config('system', 'profile_fields_advanced'); - else + } else { set_config('system', 'profile_fields_advanced', $narr); - + } } goaway(z_root() . '/admin/profs'); } @@ -49,7 +49,8 @@ class Profs if (array_key_exists('field_name', $_REQUEST)) { if ($_REQUEST['id']) { - $r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d", + $r = q( + "update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d", dbesc($_REQUEST['field_name']), dbesc($_REQUEST['field_type']), dbesc($_REQUEST['field_desc']), @@ -58,7 +59,8 @@ class Profs intval($_REQUEST['id']) ); } else { - $r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )", + $r = q( + "insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )", dbesc($_REQUEST['field_name']), dbesc($_REQUEST['field_type']), dbesc($_REQUEST['field_desc']), @@ -78,7 +80,8 @@ class Profs { if ((argc() > 3) && argv(2) == 'drop' && intval(argv(3))) { - $r = q("delete from profdef where id = %d", + $r = q( + "delete from profdef where id = %d", intval(argv(3)) ); // remove from allowed fields @@ -98,7 +101,8 @@ class Profs } if ((argc() > 2) && intval(argv(2))) { - $r = q("select * from profdef where id = %d limit 1", + $r = q( + "select * from profdef where id = %d limit 1", intval(argv(2)) ); if (!$r) { @@ -121,12 +125,14 @@ class Profs $barr = []; $fields = get_profile_fields_basic(); - if (!$fields) + if (!$fields) { $fields = get_profile_fields_basic(1); + } if ($fields) { foreach ($fields as $k => $v) { - if ($basic) + if ($basic) { $basic .= ', '; + } $basic .= trim($k); $barr[] = trim($k); } @@ -134,14 +140,17 @@ class Profs $advanced = ''; $fields = get_profile_fields_advanced(); - if (!$fields) + if (!$fields) { $fields = get_profile_fields_advanced(1); + } if ($fields) { foreach ($fields as $k => $v) { - if (in_array(trim($k), $barr)) + if (in_array(trim($k), $barr)) { continue; - if ($advanced) + } + if ($advanced) { $advanced .= ', '; + } $advanced .= trim($k); } } @@ -150,8 +159,9 @@ class Profs $fields = get_profile_fields_advanced(1); if ($fields) { foreach ($fields as $k => $v) { - if ($all) + if ($all) { $all .= ', '; + } $all .= trim($k); } } @@ -159,8 +169,9 @@ class Profs $r = q("select * from profdef where true"); if ($r) { foreach ($r as $rr) { - if ($all) + if ($all) { $all .= ', '; + } $all .= $rr['field_name']; } } @@ -181,9 +192,5 @@ class Profs )); return $o; - - } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Queue.php b/Zotlabs/Module/Admin/Queue.php index b6fd6b291..136dd46f5 100644 --- a/Zotlabs/Module/Admin/Queue.php +++ b/Zotlabs/Module/Admin/Queue.php @@ -46,6 +46,4 @@ class Queue return $o; } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Security.php b/Zotlabs/Module/Admin/Security.php index b966322ce..70c5673fe 100644 --- a/Zotlabs/Module/Admin/Security.php +++ b/Zotlabs/Module/Admin/Security.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module\Admin; - class Security { @@ -19,13 +18,13 @@ class Security $anonymous_comments = ((x($_POST, 'anonymous_comments')) ? intval($_POST['anonymous_comments']) : 0); set_config('system', 'anonymous_comments', $anonymous_comments); - $block_public = ((x($_POST, 'block_public')) ? True : False); + $block_public = ((x($_POST, 'block_public')) ? true : false); set_config('system', 'block_public', $block_public); $block_public_search = ((x($_POST, 'block_public_search')) ? 1 : 0); set_config('system', 'block_public_search', $block_public_search); - $block_public_dir = ((x($_POST, 'block_public_directory')) ? True : False); + $block_public_dir = ((x($_POST, 'block_public_directory')) ? true : false); set_config('system', 'block_public_directory', $block_public_dir); $localdir_hide = ((x($_POST, 'localdir_hide')) ? 1 : 0); @@ -67,7 +66,7 @@ class Security $bc = $this->trim_array_elems(explode("\n", $_POST['pubstream_denied_channels'])); set_config('system', 'pubstream_denied_channels', $bc); - $embed_sslonly = ((x($_POST, 'embed_sslonly')) ? True : False); + $embed_sslonly = ((x($_POST, 'embed_sslonly')) ? true : false); set_config('system', 'embed_sslonly', $embed_sslonly); $we = $this->trim_array_elems(explode("\n", $_POST['embed_allow'])); @@ -76,10 +75,10 @@ class Security $be = $this->trim_array_elems(explode("\n", $_POST['embed_deny'])); set_config('system', 'embed_deny', $be); - $ts = ((x($_POST, 'transport_security')) ? True : False); + $ts = ((x($_POST, 'transport_security')) ? true : false); set_config('system', 'transport_security_header', $ts); - $cs = ((x($_POST, 'content_security')) ? True : False); + $cs = ((x($_POST, 'content_security')) ? true : false); set_config('system', 'content_security_policy', $cs); goaway(z_root() . '/admin/security'); @@ -165,7 +164,7 @@ class Security '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $allowedembeds_str, t('One site per line. By default embedded content is filtered.')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $deniedembeds_str, ''), -// '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), +// '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), '$submit' => t('Submit') )); @@ -179,12 +178,11 @@ class Security if ($arr && is_array($arr)) { for ($x = 0; $x < count($arr); $x++) { $y = trim($arr[$x]); - if ($y) + if ($y) { $narr[] = $y; + } } } return $narr; } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 5e0326759..f31f3a58f 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -34,14 +34,14 @@ class Site $siteinfo = ((x($_POST, 'siteinfo')) ? trim($_POST['siteinfo']) : ''); $language = ((x($_POST, 'language')) ? notags(trim($_POST['language'])) : 'en'); $theme = ((x($_POST, 'theme')) ? notags(trim($_POST['theme'])) : ''); -// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); -// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); +// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); +// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); $maximagesize = ((x($_POST, 'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); $register_policy = ((x($_POST, 'register_policy')) ? intval(trim($_POST['register_policy'])) : 0); $minimum_age = ((x($_POST, 'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13); $access_policy = ((x($_POST, 'access_policy')) ? intval(trim($_POST['access_policy'])) : 0); - $invite_only = ((x($_POST, 'invite_only')) ? True : False); + $invite_only = ((x($_POST, 'invite_only')) ? true : false); $abandon_days = ((x($_POST, 'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0); $register_text = ((x($_POST, 'register_text')) ? notags(trim($_POST['register_text'])) : ''); @@ -56,14 +56,14 @@ class Site } $mirror_frontpage = ((x($_POST, 'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0); $directory_server = ((x($_POST, 'directory_server')) ? trim($_POST['directory_server']) : ''); - $force_publish = ((x($_POST, 'publish_all')) ? True : False); - $open_pubstream = ((x($_POST, 'open_pubstream')) ? True : False); + $force_publish = ((x($_POST, 'publish_all')) ? true : false); + $open_pubstream = ((x($_POST, 'open_pubstream')) ? true : false); $public_stream_mode = ((x($_POST, 'public_stream_mode')) ? intval($_POST['public_stream_mode']) : PUBLIC_STREAM_NONE); - $animations = ((x($_POST, 'animations')) ? True : False); - $login_on_homepage = ((x($_POST, 'login_on_homepage')) ? True : False); - $enable_context_help = ((x($_POST, 'enable_context_help')) ? True : False); + $animations = ((x($_POST, 'animations')) ? true : false); + $login_on_homepage = ((x($_POST, 'login_on_homepage')) ? true : false); + $enable_context_help = ((x($_POST, 'enable_context_help')) ? true : false); $global_directory = ((x($_POST, 'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : ''); - $no_community_page = !((x($_POST, 'no_community_page')) ? True : False); + $no_community_page = !((x($_POST, 'no_community_page')) ? true : false); $default_expire_days = ((array_key_exists('default_expire_days', $_POST)) ? intval($_POST['default_expire_days']) : 0); $active_expire_days = ((array_key_exists('active_expire_days', $_POST)) ? intval($_POST['active_expire_days']) : 7); $max_imported_follow = ((x($_POST, 'max_imported_follow')) ? intval(trim($_POST['max_imported_follow'])) : MAX_IMPORTED_FOLLOW); @@ -72,7 +72,7 @@ class Site $from_email = ((array_key_exists('from_email', $_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . App::get_hostname()); $from_email_name = ((array_key_exists('from_email_name', $_POST) && trim($_POST['from_email_name'])) ? trim($_POST['from_email_name']) : System::get_site_name()); - $verifyssl = ((x($_POST, 'verifyssl')) ? True : False); + $verifyssl = ((x($_POST, 'verifyssl')) ? true : false); $proxyuser = ((x($_POST, 'proxyuser')) ? notags(trim($_POST['proxyuser'])) : ''); $proxy = ((x($_POST, 'proxy')) ? notags(trim($_POST['proxy'])) : ''); $timeout = ((x($_POST, 'timeout')) ? intval(trim($_POST['timeout'])) : 60); @@ -83,7 +83,7 @@ class Site $delivery_batch_count = ((x($_POST, 'delivery_batch_count') && $_POST['delivery_batch_count'] > 0) ? intval(trim($_POST['delivery_batch_count'])) : 3); $poll_interval = ((x($_POST, 'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0); $maxloadavg = ((x($_POST, 'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); -// $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); +// $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); $ap_contacts = ((x($_POST, 'ap_contacts')) ? intval($_POST['ap_contacts']) : 0); $verify_email = ((x($_POST, 'verify_email')) ? 1 : 0); $imagick_path = ((x($_POST, 'imagick_path')) ? trim($_POST['imagick_path']) : ''); @@ -93,7 +93,7 @@ class Site $permissions_role = escape_tags(trim($_POST['permissions_role'])); -// set_config('system', 'feed_contacts', $feed_contacts); +// set_config('system', 'feed_contacts', $feed_contacts); set_config('system', 'activitypub', $ap_contacts); set_config('system', 'delivery_interval', $delivery_interval); set_config('system', 'delivery_batch_count', $delivery_batch_count); @@ -138,19 +138,23 @@ class Site // sync sitename and siteinfo updates to the system channel - q("update profile set about = '%s' where uid = %d and is_default = 1", + q( + "update profile set about = '%s' where uid = %d and is_default = 1", dbesc($siteinfo), intval($sys['channel_id']) ); - q("update profile set fullname = '%s' where uid = %d and is_default = 1", + q( + "update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($sitename), intval($sys['channel_id']) ); - q("update channel set channel_name = '%s' where channel_id = %d", + q( + "update channel set channel_name = '%s' where channel_id = %d", dbesc($sitename), intval($sys['channel_id']) ); - q("update xchan set xchan_name = '%s' , xchan_name_updated = '%s' where xchan_hash = '%s'", + q( + "update xchan set xchan_name = '%s' , xchan_name_updated = '%s' where xchan_hash = '%s'", dbesc($sitename), dbesc(datetime_convert()), dbesc($sys['channel_hash']) @@ -158,7 +162,7 @@ class Site set_config('system', 'language', $language); set_config('system', 'theme', $theme); - // set_config('system','site_channel', $site_channel); + // set_config('system','site_channel', $site_channel); set_config('system', 'maximagesize', $maximagesize); set_config('system', 'register_policy', $register_policy); @@ -203,8 +207,9 @@ class Site $langs = glob('view/*/strings.php'); if (is_array($langs) && count($langs)) { - if (!in_array('view/en/strings.php', $langs)) + if (!in_array('view/en/strings.php', $langs)) { $langs[] = 'view/en/'; + } asort($langs); foreach ($langs as $l) { $t = explode("/", $l); @@ -228,14 +233,18 @@ class Site continue; } - if (file_exists($file . '/library')) + if (file_exists($file . '/library')) { continue; - if (file_exists($file . '/mobile')) + } + if (file_exists($file . '/mobile')) { $vars = t('mobile'); - if (file_exists($file . '/experimental')) + } + if (file_exists($file . '/experimental')) { $vars .= t('experimental'); - if (file_exists($file . '/unsupported')) + } + if (file_exists($file . '/unsupported')) { $vars .= t('unsupported'); + } if ($vars) { $theme_choices[$f] = $f . ' (' . $vars . ')'; $theme_choices_mobile[$f] = $f . ' (' . $vars . ')'; @@ -254,7 +263,8 @@ class Site // avoid older redmatrix servers which don't have modern encryption if ($dirmode == DIRECTORY_MODE_NORMAL) { - $x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s' and site_dead = 0", + $x = q( + "select site_url from site where site_flags in (%d,%d) and site_realm = '%s' and site_dead = 0", intval(DIRECTORY_MODE_SECONDARY), intval(DIRECTORY_MODE_PRIMARY), dbesc($realm) @@ -311,8 +321,8 @@ class Site '$siteinfo' => ['siteinfo', t('Site Information'), get_config('system', 'siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode may be used here.")], '$language' => ['language', t("System language"), get_config('system', 'language', 'en'), "", $lang_choices], '$theme' => ['theme', t("System theme"), get_config('system', 'theme'), t("Default system theme - may be over-ridden by user profiles - change theme settings"), $theme_choices], -// '$theme_mobile' => [ 'theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile ], -// '$site_channel' => [ 'site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel") ], +// '$theme_mobile' => [ 'theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile ], +// '$site_channel' => [ 'site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel") ], '$ap_contacts' => ['ap_contacts', t('ActivityPub protocol'), get_config('system', 'activitypub', ACTIVITYPUB_ENABLED), t('Provides access to software supporting the ActivityPub protocol.')], '$maximagesize' => ['maximagesize', t("Maximum image size"), intval(get_config('system', 'maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")], '$cache_images' => ['cache_images', t('Cache all public images'), intval(get_config('system', 'cache_images', 1)), t('If disabled, proxy non-SSL images, but do not store locally')], @@ -366,5 +376,4 @@ class Site '$form_security_token' => get_form_security_token("admin_site"), ]); } - } diff --git a/Zotlabs/Module/Admin/Themes.php b/Zotlabs/Module/Admin/Themes.php index 2f30f1618..20bbd508b 100644 --- a/Zotlabs/Module/Admin/Themes.php +++ b/Zotlabs/Module/Admin/Themes.php @@ -27,8 +27,9 @@ class Themes } } info(t('Theme settings updated.')); - if (is_ajax()) + if (is_ajax()) { return; + } goaway(z_root() . '/admin/themes/' . $theme); } @@ -44,10 +45,13 @@ class Themes $allowed_themes_str = get_config('system', 'allowed_themes'); $allowed_themes_raw = explode(',', $allowed_themes_str); $allowed_themes = []; - if (count($allowed_themes_raw)) - foreach ($allowed_themes_raw as $x) - if (strlen(trim($x))) + if (count($allowed_themes_raw)) { + foreach ($allowed_themes_raw as $x) { + if (strlen(trim($x))) { $allowed_themes[] = trim($x); + } + } + } $themes = []; $files = glob('view/theme/*'); @@ -84,10 +88,11 @@ class Themes $this->toggle_theme($themes, $theme, $result); $s = $this->rebuild_theme_table($themes); - if ($result) + if ($result) { info(sprintf('Theme %s enabled.', $theme)); - else + } else { info(sprintf('Theme %s disabled.', $theme)); + } set_config('system', 'allowed_themes', $s); goaway(z_root() . '/admin/themes'); @@ -103,11 +108,11 @@ class Themes $action = t("Enable"); } - $readme = Null; + $readme = null; if (is_file("view/theme/$theme/README.md")) { $readme = file_get_contents("view/theme/$theme/README.md"); $readme = MarkdownExtra::defaultTransform($readme); - } else if (is_file("view/theme/$theme/README")) { + } elseif (is_file("view/theme/$theme/README")) { $readme = '
' . file_get_contents("view/theme/$theme/README") . '
'; } @@ -120,8 +125,9 @@ class Themes } $screenshot = array(get_theme_screenshot($theme), t('Screenshot')); - if (!stristr($screenshot[0], $theme)) + if (!stristr($screenshot[0], $theme)) { $screenshot = null; + } $t = get_markup_template('admin_plugins_details.tpl'); return replace_macros($t, array( @@ -223,13 +229,13 @@ class Themes if (count($themes)) { foreach ($themes as $th) { if ($th['allowed']) { - if (strlen($o)) + if (strlen($o)) { $o .= ','; + } $o .= $th['name']; } } } return $o; } - } diff --git a/Zotlabs/Module/Affinity.php b/Zotlabs/Module/Affinity.php index 052245114..1df26928b 100644 --- a/Zotlabs/Module/Affinity.php +++ b/Zotlabs/Module/Affinity.php @@ -18,20 +18,20 @@ class Affinity extends Controller if ($_POST['affinity-submit']) { $cmax = intval($_POST['affinity_cmax']); - if ($cmax < 0 || $cmax > 99) + if ($cmax < 0 || $cmax > 99) { $cmax = 99; + } $cmin = intval($_POST['affinity_cmin']); - if ($cmin < 0 || $cmin > 99) + if ($cmin < 0 || $cmin > 99) { $cmin = 0; + } set_pconfig(local_channel(), 'affinity', 'cmin', 0); set_pconfig(local_channel(), 'affinity', 'cmax', $cmax); info(t('Friend Zoom settings updated.') . EOL); - } Libsync::build_sync_packet(); - } @@ -52,12 +52,11 @@ class Affinity extends Controller $cmax = intval(get_pconfig(local_channel(), 'affinity', 'cmax')); $cmax = (($cmax) ? $cmax : 99); -// $setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array( -// '$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, t('0-99 default 99')) -// )); +// $setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array( +// '$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, t('0-99 default 99')) +// )); if (Apps::system_app_installed(local_channel(), 'Friend Zoom')) { - $labels = array( 0 => t('Me'), 20 => t('Family'), @@ -90,6 +89,4 @@ class Affinity extends Controller return $s; } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Album.php b/Zotlabs/Module/Album.php index 81dd48a26..dda4d9bce 100644 --- a/Zotlabs/Module/Album.php +++ b/Zotlabs/Module/Album.php @@ -1,4 +1,5 @@ 2) { $folder = argv(2); - $r = q("select * from attach where is_dir = 1 and hash = '%s' and uid = %d $sql_extra limit 1", + $r = q( + "select * from attach where is_dir = 1 and hash = '%s' and uid = %d $sql_extra limit 1", dbesc($folder), intval($channel['channel_id']) ); @@ -73,7 +74,8 @@ class Album extends Controller http_status_exit(403, 'Permission denied.'); } - $x = q("select * from attach where folder = '%s' and uid = %d $sql_extra", + $x = q( + "select * from attach where folder = '%s' and uid = %d $sql_extra", dbesc($folder), intval($channel['channel_id']) ); @@ -96,8 +98,6 @@ class Album extends Controller $obj = Activity::encode_simple_collection($contents, App::$query_string, 'OrderedCollection', count($contents)); as_return_and_die($obj, $channel); - } - } -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Ap_probe.php b/Zotlabs/Module/Ap_probe.php index ee60ab8e8..478a1eb62 100644 --- a/Zotlabs/Module/Ap_probe.php +++ b/Zotlabs/Module/Ap_probe.php @@ -1,4 +1,5 @@ ' . str_replace('\\n', "\n", htmlspecialchars(json_encode($x, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT))) . ''; } - } return $o; } - } diff --git a/Zotlabs/Module/Api.php b/Zotlabs/Module/Api.php index 6a6874412..a64a7fad6 100644 --- a/Zotlabs/Module/Api.php +++ b/Zotlabs/Module/Api.php @@ -1,4 +1,5 @@ oauth_get_client($request); - if (is_null($app)) + if (is_null($app)) { return "Invalid request. Unknown token."; + } $consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']); @@ -74,8 +72,9 @@ class Api extends Controller if ($consumer->callback_url != null) { $params = $request->get_parameters(); $glue = '?'; - if (strstr($consumer->callback_url, $glue)) + if (strstr($consumer->callback_url, $glue)) { $glue = '?'; + } goaway($consumer->callback_url . $glue . "oauth_token=" . OAuth1Util::urlencode_rfc3986($params['oauth_token']) . "&oauth_verifier=" . OAuth1Util::urlencode_rfc3986($verifier)); killme(); } @@ -98,8 +97,9 @@ class Api extends Controller } $app = $this->oauth_get_client($request); - if (is_null($app)) + if (is_null($app)) { return "Invalid request. Unknown token."; + } $tpl = get_markup_template('oauth_authorize.tpl'); $o = replace_macros($tpl, array( @@ -125,15 +125,15 @@ class Api extends Controller $params = $request->get_parameters(); $token = $params['oauth_token']; - $r = q("SELECT clients.* FROM clients, tokens WHERE clients.client_id = tokens.client_id + $r = q( + "SELECT clients.* FROM clients, tokens WHERE clients.client_id = tokens.client_id AND tokens.id = '%s' AND tokens.auth_scope = 'request' ", dbesc($token) ); - if ($r) + if ($r) { return $r[0]; + } return null; - } - } diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index 105aa7792..8963b3f6b 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -1,6 +1,6 @@ $embed, '$submit' => t('Submit') ]); - } - } diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index 6f5d14fc0..99cfacc64 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -1,4 +1,5 @@ (($available) ? EMPTY_STR : t('Manage apps')), '$create' => (($mode == 'edit') ? t('Create Custom App') : '') )); - } - } diff --git a/Zotlabs/Module/Apschema.php b/Zotlabs/Module/Apschema.php index 53e7f0dbe..9b5c68e0b 100644 --- a/Zotlabs/Module/Apschema.php +++ b/Zotlabs/Module/Apschema.php @@ -18,8 +18,5 @@ class Apschema extends Controller header('Content-Type: application/ld+json'); echo json_encode($arr, JSON_UNESCAPED_SLASHES); killme(); - } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php index 9aa254bc8..4c45b2bee 100644 --- a/Zotlabs/Module/Attach.php +++ b/Zotlabs/Module/Attach.php @@ -1,4 +1,5 @@ send(); killme(); } - } diff --git a/Zotlabs/Module/Block.php b/Zotlabs/Module/Block.php index 1dfdae59a..4b16d03bd 100644 --- a/Zotlabs/Module/Block.php +++ b/Zotlabs/Module/Block.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } @@ -64,7 +65,8 @@ class Blocks extends Controller if (!$owner) { // Figure out who the page owner is. - $r = q("select channel_id from channel where channel_address = '%s'", + $r = q( + "select channel_id from channel where channel_address = '%s'", dbesc($which) ); if ($r) { @@ -109,17 +111,21 @@ class Blocks extends Controller 'bbcode' => true ); - if ($_REQUEST['title']) + if ($_REQUEST['title']) { $x['title'] = $_REQUEST['title']; - if ($_REQUEST['body']) + } + if ($_REQUEST['body']) { $x['body'] = $_REQUEST['body']; - if ($_REQUEST['pagetitle']) + } + if ($_REQUEST['pagetitle']) { $x['pagetitle'] = $_REQUEST['pagetitle']; + } $editor = status_editor($x); - $r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig + $r = q( + "select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig left join item on iconfig.iid = item.id where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' and item_type = %d order by item.created desc", @@ -176,5 +182,4 @@ class Blocks extends Controller return $o; } - } diff --git a/Zotlabs/Module/Ca.php b/Zotlabs/Module/Ca.php index 749c082bb..96caace69 100644 --- a/Zotlabs/Module/Ca.php +++ b/Zotlabs/Module/Ca.php @@ -1,7 +1,9 @@ var profile_uid = " . ((App::$data['channel']) ? App::$data['channel']['channel_id'] : 0) . "; "; - } return; @@ -115,26 +113,29 @@ class Cal extends Controller } if ($mode == 'view') { - /* edit/create form */ if ($event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval($channel['channel_id']) ); - if (count($r)) + if (count($r)) { $orig_event = $r[0]; + } } // Passed parameters overrides anything found in the DB - if (!x($orig_event)) + if (!x($orig_event)) { $orig_event = []; + } $tz = date_default_timezone_get(); - if (x($orig_event)) + if (x($orig_event)) { $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC'); + } $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); $smonth = datetime_convert('UTC', $tz, $sdt, 'm'); @@ -157,8 +158,9 @@ class Cal extends Controller $type = ((x($orig_event)) ? $orig_event['etype'] : 'event'); $f = get_config('system', 'event_input_format'); - if (!$f) + if (!$f) { $f = 'ymd'; + } $catsenabled = Apps::system_app_installed(local_channel(), 'Categories'); @@ -173,18 +175,22 @@ class Cal extends Controller $thisyear = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); $thismonth = datetime_convert('UTC', date_default_timezone_get(), 'now', 'm'); - if (!$y) + if (!$y) { $y = intval($thisyear); - if (!$m) + } + if (!$m) { $m = intval($thismonth); + } // Put some limits on dates. The PHP date functions don't seem to do so well before 1900. // An upper limit was chosen to keep search engines from exploring links millions of years in the future. - if ($y < 1901) + if ($y < 1901) { $y = 1900; - if ($y > 2099) + } + if ($y > 2099) { $y = 2100; + } $nextyear = $y; $nextmonth = $m + 1; @@ -194,9 +200,9 @@ class Cal extends Controller } $prevyear = $y; - if ($m > 1) + if ($m > 1) { $prevmonth = $m - 1; - else { + } else { $prevmonth = 12; $prevyear--; } @@ -207,8 +213,12 @@ class Cal extends Controller if (argv(2) === 'json') { - if (x($_GET, 'start')) $start = $_GET['start']; - if (x($_GET, 'end')) $finish = $_GET['end']; + if (x($_GET, 'start')) { + $start = $_GET['start']; + } + if (x($_GET, 'end')) { + $finish = $_GET['end']; + } } $start = datetime_convert('UTC', 'UTC', $start); @@ -218,11 +228,13 @@ class Cal extends Controller $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); - if (!perm_is_allowed(App::$profile['uid'], get_observer_hash(), 'view_contacts')) + if (!perm_is_allowed(App::$profile['uid'], get_observer_hash(), 'view_contacts')) { $sql_extra .= " and etype != 'birthday' "; + } if (x($_GET, 'id')) { - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1", intval($channel['channel_id']), intval($_GET['id']) @@ -233,7 +245,8 @@ class Cal extends Controller // Noting this for now - it will need to be fixed here and in Friendica. // Ultimately the finish date shouldn't be involved in the query. - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on event_hash = resource_id where resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) @@ -244,7 +257,6 @@ class Cal extends Controller dbesc($adjust_start), dbesc($adjust_finish) ); - } $links = []; @@ -259,8 +271,9 @@ class Cal extends Controller if ($r) { foreach ($r as $rr) { $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'j') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'j')); - if (!x($links, $j)) + if (!x($links, $j)) { $links[$j] = z_root() . '/' . App::$cmd . '#link-' . $j; + } } } @@ -270,9 +283,7 @@ class Cal extends Controller $fmt = t('l, F j'); if ($r) { - foreach ($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'j') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'j')); $d = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], $fmt) : datetime_convert('UTC', 'UTC', $rr['dtstart'], $fmt)); $d = day_translate($d); @@ -319,8 +330,6 @@ class Cal extends Controller 'html' => $html, 'plink' => array($rr['plink'], t('Link to Source'), '', ''), ); - - } } @@ -362,7 +371,5 @@ class Cal extends Controller return $o; } - } - } diff --git a/Zotlabs/Module/Calendar.php b/Zotlabs/Module/Calendar.php index 31cb47209..5794d0bbf 100644 --- a/Zotlabs/Module/Calendar.php +++ b/Zotlabs/Module/Calendar.php @@ -1,4 +1,5 @@ 2) && (argv(1) === 'ignore') && intval(argv(2))) { - $r = q("update event set dismissed = 1 where id = %d and uid = %d", + $r = q( + "update event set dismissed = 1 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } if ((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { - $r = q("update event set dismissed = 0 where id = %d and uid = %d", + $r = q( + "update event set dismissed = 0 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); @@ -309,10 +315,10 @@ class Calendar extends Controller } if ($mode == 'view') { - /* edit/create form */ if ($event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); @@ -339,14 +345,16 @@ class Calendar extends Controller $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); if (x($_GET, 'id')) { - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id from event left join item on item.resource_id = event.event_hash where item.resource_type = 'event' and event.uid = %d and event.id = %d limit 1", intval(local_channel()), intval($_GET['id']) ); } elseif ($export) { - $r = q("SELECT * from event where uid = %d", + $r = q( + "SELECT * from event where uid = %d", intval(local_channel()) ); } else { @@ -355,7 +363,8 @@ class Calendar extends Controller // Noting this for now - it will need to be fixed here and in Friendica. // Ultimately the finish date shouldn't be involved in the query. - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id from event left join item on event.event_hash = item.resource_id where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ) @@ -366,7 +375,6 @@ class Calendar extends Controller dbesc($adjust_start), dbesc($adjust_finish) ); - } if ($r && !$export) { @@ -379,7 +387,6 @@ class Calendar extends Controller $events = []; if ($r) { - foreach ($r as $rr) { $start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c')); if ($rr['nofinish']) { @@ -390,8 +397,9 @@ class Calendar extends Controller // give a fake end to birthdays so they get crammed into a // single day on the calendar - if ($rr['etype'] === 'birthday') + if ($rr['etype'] === 'birthday') { $end = null; + } } $catsenabled = Apps::system_app_installed($x['profile_uid'], 'Categories'); @@ -405,10 +413,12 @@ class Calendar extends Controller $allDay = false; // allDay event rules - if (!strpos($start, 'T') && !strpos($end, 'T')) + if (!strpos($start, 'T') && !strpos($end, 'T')) { $allDay = true; - if (strpos($start, 'T00:00:00') && strpos($end, 'T00:00:00')) + } + if (strpos($start, 'T00:00:00') && strpos($end, 'T00:00:00')) { $allDay = true; + } $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root() . '/events/' . $rr['event_hash'] . '?expandform=1', t('Edit event'), '', '') : false); @@ -452,7 +462,8 @@ class Calendar extends Controller if ($mode === 'drop' && $event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); @@ -460,12 +471,14 @@ class Calendar extends Controller $sync_event = $r[0]; if ($r) { - $r = q("delete from event where event_hash = '%s' and uid = %d", + $r = q( + "delete from event where event_hash = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); if ($r) { - $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", + $r = q( + "update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); @@ -477,7 +490,5 @@ class Calendar extends Controller killme(); } } - } - } diff --git a/Zotlabs/Module/Card_edit.php b/Zotlabs/Module/Card_edit.php index bd6246591..6be63109d 100644 --- a/Zotlabs/Module/Card_edit.php +++ b/Zotlabs/Module/Card_edit.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } /** @@ -103,7 +104,6 @@ class Cards extends Controller if (perm_is_allowed($owner, $ob_hash, 'write_pages')) { - $x = [ 'webpage' => ITEM_TYPE_CARD, 'is_owner' => true, @@ -112,8 +112,11 @@ class Cards extends Controller 'nickname' => $channel['channel_address'], 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl, false, - PermissionDescription::fromGlobalPermission('view_pages')) : ''), + 'acl' => (($is_owner) ? populate_acl( + $channel_acl, + false, + PermissionDescription::fromGlobalPermission('view_pages') + ) : ''), 'permissions' => $channel_acl, 'showacl' => (($is_owner) ? true : false), 'visitor' => true, @@ -130,10 +133,12 @@ class Cards extends Controller 'bbcode' => true ]; - if ($_REQUEST['title']) + if ($_REQUEST['title']) { $x['title'] = $_REQUEST['title']; - if ($_REQUEST['body']) + } + if ($_REQUEST['body']) { $x['body'] = $_REQUEST['body']; + } $editor = status_editor($x); } else { @@ -150,7 +155,8 @@ class Cards extends Controller $sql_item = ''; if ($selected_card) { - $r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1", + $r = q( + "select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1", dbesc($selected_card) ); if ($r) { @@ -158,7 +164,8 @@ class Cards extends Controller } } - $r = q("select * from item + $r = q( + "select * from item where uid = %d and item_type = %d $sql_extra $sql_item order by item.created desc $pager_sql", intval($owner), @@ -171,12 +178,12 @@ class Cards extends Controller $items_result = []; if ($r) { - $pager_total = count($r); $parents_str = ids_to_querystr($r, 'id'); - $items = q("SELECT item.*, item.id AS item_id + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE item.uid = %d $item_normal AND item.parent IN ( %s ) @@ -193,10 +200,11 @@ class Cards extends Controller $mode = 'cards'; - if (get_pconfig(local_channel(), 'system', 'articles_list_mode') && (!$selected_card)) + if (get_pconfig(local_channel(), 'system', 'articles_list_mode') && (!$selected_card)) { $page_mode = 'pager_list'; - else + } else { $page_mode = 'traditional'; + } $content = conversation($items_result, $mode, false, $page_mode); @@ -209,5 +217,4 @@ class Cards extends Controller return $o; } - } diff --git a/Zotlabs/Module/Categories.php b/Zotlabs/Module/Categories.php index 284352b9c..e168bc6fe 100644 --- a/Zotlabs/Module/Categories.php +++ b/Zotlabs/Module/Categories.php @@ -22,7 +22,6 @@ class Categories extends Controller } Libprofile::load($which, 0); } - } @@ -39,8 +38,5 @@ class Categories extends Controller $c = new Comanche(); return $c->widget('catcloud', EMPTY_STR); - } - - } diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index 206f6852f..ceb364c6e 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -1,4 +1,5 @@ setRealm(ucfirst(System::get_platform_name()) . ' ' . 'CalDAV/CardDAV'); if (local_channel()) { - logger('loggedin'); if ((argv(1) == 'addressbooks') && (!Apps::system_app_installed(local_channel(), 'CardDAV'))) { @@ -179,7 +180,6 @@ class Cdav extends Controller return; } } - } @@ -235,16 +235,15 @@ class Cdav extends Controller $server->exec(); killme(); - } - } public function post() { - if (!local_channel()) + if (!local_channel()) { return; + } if ((argv(1) === 'addressbook') && (!Apps::system_app_installed(local_channel(), 'CardDAV'))) { return; @@ -253,15 +252,15 @@ class Cdav extends Controller $channel = App::get_channel(); $principalUri = 'principals/' . $channel['channel_address']; - if (!cdav_principal($principalUri)) + if (!cdav_principal($principalUri)) { return; + } $pdo = DBA::$dba->db; require_once 'vendor/autoload.php'; if (argc() == 2 && argv(1) === 'calendar') { - $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $calendars = $caldavBackend->getCalendarsForUser($principalUri); @@ -271,7 +270,8 @@ class Cdav extends Controller $duplicate = false; $calendarUri = random_string(40); - $r = q("SELECT uri FROM calendarinstances WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + $r = q( + "SELECT uri FROM calendarinstances WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principalUri), dbesc($calendarUri) ); @@ -295,11 +295,11 @@ class Cdav extends Controller //create new calendar object via ajax request if ($_REQUEST['submit'] === 'create_event' && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) { - $id = explode(':', $_REQUEST['target']); - if (!cdav_perms($id[0], $calendars, true)) + if (!cdav_perms($id[0], $calendars, true)) { return; + } $title = $_REQUEST['title']; $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']); @@ -315,13 +315,15 @@ class Cdav extends Controller $duplicate = false; $objectUri = random_string(40) . '.ics'; - $r = q("SELECT uri FROM calendarobjects WHERE calendarid = %s AND uri = '%s' LIMIT 1", + $r = q( + "SELECT uri FROM calendarobjects WHERE calendarid = %s AND uri = '%s' LIMIT 1", intval($id[0]), dbesc($objectUri) ); - if (count($r)) + if (count($r)) { $duplicate = true; + } } while ($duplicate == true); @@ -335,10 +337,12 @@ class Cdav extends Controller $vcalendar->VEVENT->add('DTEND', $dtend); $vcalendar->VEVENT->DTEND['TZID'] = App::$timezone; } - if ($description) + if ($description) { $vcalendar->VEVENT->add('DESCRIPTION', $description); - if ($location) + } + if ($location) { $vcalendar->VEVENT->add('LOCATION', $location); + } $vcalendar->VEVENT->DTSTART['TZID'] = App::$timezone; @@ -351,7 +355,6 @@ class Cdav extends Controller // edit calendar name and color if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['edit'] && $_REQUEST['id']) { - $id = explode(':', $_REQUEST['id']); if (!cdav_perms($id[0], $calendars)) { @@ -372,11 +375,11 @@ class Cdav extends Controller // edit calendar object via ajax request if ($_REQUEST['submit'] === 'update_event' && $_REQUEST['uri'] && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) { - $id = explode(':', $_REQUEST['target']); - if (!cdav_perms($id[0], $calendars, true)) + if (!cdav_perms($id[0], $calendars, true)) { return; + } $uri = $_REQUEST['uri']; $title = $_REQUEST['title']; @@ -419,7 +422,6 @@ class Cdav extends Controller // delete calendar object via ajax request if ($_REQUEST['delete'] && $_REQUEST['uri'] && $_REQUEST['target']) { - $id = explode(':', $_REQUEST['target']); if (!cdav_perms($id[0], $calendars, true)) { @@ -434,7 +436,6 @@ class Cdav extends Controller // edit calendar object date/timeme via ajax request (drag and drop) if ($_REQUEST['update'] && $_REQUEST['id'] && $_REQUEST['uri']) { - $id = [$_REQUEST['id'][0], $_REQUEST['id'][1]]; if (!cdav_perms($id[0], $calendars, true)) { @@ -471,7 +472,6 @@ class Cdav extends Controller // share a calendar - this only works on local system (with channels on the same server) if ($_REQUEST['sharee'] && $_REQUEST['share']) { - $id = [intval($_REQUEST['calendarid']), intval($_REQUEST['instanceid'])]; if (!cdav_perms($id[0], $calendars)) { @@ -494,7 +494,6 @@ class Cdav extends Controller } if (argc() >= 2 && argv(1) === 'addressbook') { - $carddavBackend = new PDO($pdo); $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); @@ -504,7 +503,8 @@ class Cdav extends Controller $duplicate = false; $addressbookUri = random_string(20); - $r = q("SELECT uri FROM addressbooks WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + $r = q( + "SELECT uri FROM addressbooks WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principalUri), dbesc($addressbookUri) ); @@ -521,7 +521,6 @@ class Cdav extends Controller // edit addressbook if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['edit'] && intval($_REQUEST['id'])) { - $id = $_REQUEST['id']; if (!cdav_perms($id, $addressbooks)) { @@ -547,7 +546,8 @@ class Cdav extends Controller $duplicate = false; $uri = random_string(40) . '.vcf'; - $r = q("SELECT uri FROM cards WHERE addressbookid = %s AND uri = '%s' LIMIT 1", + $r = q( + "SELECT uri FROM cards WHERE addressbookid = %s AND uri = '%s' LIMIT 1", intval($id), dbesc($uri) ); @@ -645,12 +645,10 @@ class Cdav extends Controller $cardData = $vcard->serialize(); $carddavBackend->createCard($id, $uri, $cardData); - } // edit addressbook card if ($_REQUEST['update'] && $_REQUEST['uri'] && $_REQUEST['target']) { - $id = $_REQUEST['target']; if (!cdav_perms($id, $addressbooks)) { @@ -771,7 +769,6 @@ class Cdav extends Controller // delete addressbook card if ($_REQUEST['delete'] && $_REQUEST['uri'] && $_REQUEST['target']) { - $id = $_REQUEST['target']; if (!cdav_perms($id, $addressbooks)) { @@ -786,11 +783,9 @@ class Cdav extends Controller // Import calendar or addressbook if (($_FILES) && array_key_exists('userfile', $_FILES) && intval($_FILES['userfile']['size']) && $_REQUEST['target']) { - $src = $_FILES['userfile']['tmp_name']; if ($src) { - if ($_REQUEST['c_upload']) { if ($_REQUEST['target'] == 'calendar') { $result = parse_ical_file($src, local_channel()); @@ -824,7 +819,6 @@ class Cdav extends Controller } while ($object = $objects->getNext()) { - if ($_REQUEST['a_upload']) { $object = $object->convert(Document::VCARD40); } @@ -840,7 +834,8 @@ class Cdav extends Controller $duplicate = false; $objectUri = random_string(40) . '.' . $ext; - $r = q("SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", + $r = q( + "SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", dbesc($id[0]), dbesc($objectUri) ); @@ -862,15 +857,13 @@ class Cdav extends Controller notice('' . t('INVALID EVENT DISMISSED!') . '' . EOL . '' . t('Summary: ') . '' . (($object->VEVENT->SUMMARY) ? $object->VEVENT->SUMMARY : t('Unknown')) . EOL . '' . t('Date: ') . '' . (($object->VEVENT->DTSTART) ? $object->VEVENT->DTSTART : t('Unknown')) . EOL . - '' . t('Reason: ') . '' . $ret[0]['message'] . EOL - ); + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL); } if ($_REQUEST['a_upload']) { notice('' . t('INVALID CARD DISMISSED!') . '' . EOL . '' . t('Name: ') . '' . (($object->FN) ? $object->FN : t('Unknown')) . EOL . - '' . t('Reason: ') . '' . $ret[0]['message'] . EOL - ); + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL); } } } @@ -921,7 +914,6 @@ class Cdav extends Controller // Display calendar(s) here if (argc() <= 3 && argv(1) === 'calendar') { - head_add_css('/library/fullcalendar/packages/core/main.min.css'); head_add_css('/library/fullcalendar/packages/daygrid/main.min.css'); head_add_css('/library/fullcalendar/packages/timegrid/main.min.css'); @@ -943,7 +935,8 @@ class Cdav extends Controller } if ($resource_id) { - $r = q("SELECT event.*, item.author_xchan, item.owner_xchan, item.plink, item.id as item_id FROM event LEFT JOIN item ON event.event_hash = item.resource_id + $r = q( + "SELECT event.*, item.author_xchan, item.owner_xchan, item.plink, item.id as item_id FROM event LEFT JOIN item ON event.event_hash = item.resource_id WHERE event.uid = %d AND event.event_hash = '%s' LIMIT 1", intval(local_channel()), dbesc($resource_id) @@ -969,7 +962,8 @@ class Cdav extends Controller } if ($r[0]['dismissed'] == 0) { - q("UPDATE event SET dismissed = 1 WHERE event.uid = %d AND event.event_hash = '%s'", + q( + "UPDATE event SET dismissed = 1 WHERE event.uid = %d AND event.event_hash = '%s'", intval(local_channel()), dbesc($resource_id) ); @@ -1080,12 +1074,10 @@ class Cdav extends Controller ]); return $o; - } // Provide json data for calendar if (argc() == 5 && argv(1) === 'calendar' && argv(2) === 'json' && intval(argv(3)) && intval(argv(4))) { - $events = []; $id = [argv(3), argv(4)]; @@ -1112,7 +1104,6 @@ class Cdav extends Controller if ($uris) { $objects = $caldavBackend->getMultipleCalendarObjects($id, $uris); foreach ($objects as $object) { - $vcalendar = Reader::read($object['calendardata']); if (isset($vcalendar->VEVENT->RRULE)) { @@ -1193,7 +1184,6 @@ class Cdav extends Controller // drop sharee if (argc() == 6 && argv(1) === 'calendar' && argv(2) === 'dropsharee' && intval(argv(3)) && intval(argv(4))) { - $id = [argv(3), argv(4)]; $hash = argv(5); @@ -1222,7 +1212,6 @@ class Cdav extends Controller // Display Adressbook here if (argc() == 3 && argv(1) === 'addressbook' && intval(argv(2))) { - $id = argv(2); $displayname = cdav_perms($id, $addressbooks); @@ -1400,7 +1389,6 @@ class Cdav extends Controller $carddavBackend->deleteAddressBook($id); killme(); } - } public function activate($pdo, $channel) @@ -1413,17 +1401,20 @@ class Cdav extends Controller $uri = 'principals/' . $channel['channel_address']; - $r = q("select * from principals where uri = '%s' limit 1", + $r = q( + "select * from principals where uri = '%s' limit 1", dbesc($uri) ); if ($r) { - $r = q("update principals set email = '%s', displayname = '%s' where uri = '%s' ", + $r = q( + "update principals set email = '%s', displayname = '%s' where uri = '%s' ", dbesc($channel['xchan_addr']), dbesc($channel['channel_name']), dbesc($uri) ); } else { - $r = q("insert into principals ( uri, email, displayname ) values('%s','%s','%s') ", + $r = q( + "insert into principals ( uri, email, displayname ) values('%s','%s','%s') ", dbesc($uri), dbesc($channel['xchan_addr']), dbesc($channel['channel_name']) @@ -1445,8 +1436,6 @@ class Cdav extends Controller $carddavBackend = new PDO($pdo); $properties = ['{DAV:}displayname' => t('Default Addressbook')]; $carddavBackend->createAddressBook($uri, 'default', $properties); - } } - } diff --git a/Zotlabs/Module/Changeaddr.php b/Zotlabs/Module/Changeaddr.php index e79b6f9bc..5e4ad254d 100644 --- a/Zotlabs/Module/Changeaddr.php +++ b/Zotlabs/Module/Changeaddr.php @@ -30,14 +30,17 @@ class Changeaddr extends Controller return; } - if ((!x($_POST, 'qxz_password')) || (!strlen(trim($_POST['qxz_password'])))) + if ((!x($_POST, 'qxz_password')) || (!strlen(trim($_POST['qxz_password'])))) { return; + } - if ((!x($_POST, 'verify')) || (!strlen(trim($_POST['verify'])))) + if ((!x($_POST, 'verify')) || (!strlen(trim($_POST['verify'])))) { return; + } - if ($_POST['verify'] !== $_SESSION['remove_account_verify']) + if ($_POST['verify'] !== $_SESSION['remove_account_verify']) { return; + } $account = App::get_account(); @@ -58,8 +61,9 @@ class Changeaddr extends Controller $new_address = trim($_POST['newname']); - if ($new_address === $channel['channel_address']) + if ($new_address === $channel['channel_address']) { return; + } if ($new_address === 'sys') { notice(t('Reserved nickname. Please choose another.') . EOL); @@ -74,7 +78,6 @@ class Changeaddr extends Controller channel_change_address($channel, $new_address); goaway(z_root() . '/changeaddr'); - } @@ -109,7 +112,5 @@ class Changeaddr extends Controller ]); return $o; - } - } diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 8cd0994cf..1c41364fb 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -10,7 +10,6 @@ use Zotlabs\Lib\LDSignatures; use Zotlabs\Lib\Crypto; use Zotlabs\Lib\PConfig; use Zotlabs\Web\HTTPSig; - use App; use Zotlabs\Web\Controller; use Zotlabs\Lib\PermissionDescription; @@ -102,7 +101,6 @@ class Channel extends Controller // fork of Zap; which disables ActivityPub connectivity by default. if (ActivityStreams::is_as_request()) { - // Somebody may attempt an ActivityStreams fetch on one of our message permalinks // Make it do the right thing. @@ -134,12 +132,12 @@ class Channel extends Controller // handle zot6 channel discovery if (Libzot::is_zot_request()) { - $sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6'); if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) { $data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer']])); - $s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $s = q( + "select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($sigdata['signer']) ); @@ -168,7 +166,6 @@ class Channel extends Controller Libprofile::load($which, $profile); if (!$_REQUEST['mid']) { - App::$meta->set('og:title', $channel['channel_name']); App::$meta->set('og:image', $channel['xchan_photo_l']); App::$meta->set('og:type', 'webpage'); @@ -223,7 +220,6 @@ class Channel extends Controller if ($this->loading && !$mid) { - $_SESSION['loadtime_channel'] = datetime_convert(); if ($is_owner) { PConfig::Set(local_channel(), 'system', 'loadtime_channel', $_SESSION['loadtime_channel']); @@ -243,7 +239,6 @@ class Channel extends Controller if (!$this->updating) { - nav_set_selected('Channel Home'); $static = channel_manual_conv_update(App::$profile['profile_uid']); @@ -273,7 +268,6 @@ class Channel extends Controller if ($perms['post_wall']) { - $x = array( 'is_owner' => $is_owner, 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'], 'system', 'use_browser_location')))) ? true : false), @@ -310,8 +304,9 @@ class Channel extends Controller $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 "; - if (!$is_owner) + if (!$is_owner) { $item_normal .= "and item.item_delayed = 0 "; + } $item_normal_update = item_normal_update(); $sql_extra = item_permissions_sql(App::$profile['profile_uid']); @@ -330,7 +325,8 @@ class Channel extends Controller if (strpos($search, '#') === 0) { $sql_extra .= term_query('item', substr($search, 1), TERM_HASHTAG, TERM_COMMUNITYTAG); } else { - $sql_extra .= sprintf(" AND (item.body like '%s' OR item.title like '%s') ", + $sql_extra .= sprintf( + " AND (item.body like '%s' OR item.title like '%s') ", dbesc(protect_sprintf('%' . $search . '%')), dbesc(protect_sprintf('%' . $search . '%')) ); @@ -358,13 +354,15 @@ class Channel extends Controller if (($this->updating) && (!$this->loading)) { if ($mid) { - $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update + $r = q( + "SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update AND item_wall = 1 $simple_update $sql_extra limit 1", dbesc($mid . '%'), intval(App::$profile['profile_uid']) ); } else { - $r = q("SELECT parent AS item_id from item + $r = q( + "SELECT parent AS item_id from item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) WHERE uid = %d $item_normal_update AND item_wall = 1 $simple_update @@ -375,7 +373,6 @@ class Channel extends Controller ); } } else { - if (x($category)) { $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY)); } @@ -407,7 +404,8 @@ class Channel extends Controller if ($noscript_content || $this->loading) { if ($mid) { - $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal + $r = q( + "SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal AND item_wall = 1 $sql_extra limit 1", dbesc($mid . '%'), intval(App::$profile['profile_uid']) @@ -416,7 +414,8 @@ class Channel extends Controller notice(t('Permission denied.') . EOL); } } else { - $r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item + $r = q( + "SELECT DISTINCT item.parent AS item_id, $ordering FROM item left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids ) WHERE true and item.uid = %d $item_normal AND (abook.abook_blocked = 0 or abook.abook_flags is null) @@ -431,10 +430,10 @@ class Channel extends Controller } } if ($r) { - $parents_str = ids_to_querystr($r, 'item_id'); - $items = q("SELECT item.*, item.id AS item_id + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE item.uid = %d $item_normal AND item.parent IN ( %s ) @@ -452,19 +451,18 @@ class Channel extends Controller // to view the parent item (or the item itself if it is toplevel) notice(t('Permission denied.') . EOL); } - } else { $items = []; } if ((!$this->updating) && (!$this->loading)) { - // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. $maxheight = get_pconfig(App::$profile['profile_uid'], 'system', 'channel_divmore_height'); - if (!$maxheight) + if (!$maxheight) { $maxheight = 400; + } $o .= '
' . "\r\n"; $o .= "\n"; if (argc() == 3) { - $contact_id = intval(argv(1)); if (!$contact_id) { return; @@ -363,7 +366,8 @@ class Connedit extends Controller $cmd = argv(2); - $orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash + $orig_record = q( + "SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_id = %d AND abook_channel = %d AND abook_self = 0 LIMIT 1", intval($contact_id), intval(local_channel()) @@ -406,7 +410,8 @@ class Connedit extends Controller if ($cmd === 'resetphoto') { - q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'", + q( + "update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'", dbesc($orig_record['xchan_hash']) ); $cmd = 'refresh'; @@ -444,7 +449,8 @@ class Connedit extends Controller 'block_type' => BLOCKTYPE_CHANNEL, 'block_comment' => t('Added by Connedit') ]); - $z = q("insert into xign ( uid, xchan ) values ( %d , '%s' ) ", + $z = q( + "insert into xign ( uid, xchan ) values ( %d , '%s' ) ", intval(local_channel()), dbesc($orig_record['abook_xchan']) ); @@ -505,14 +511,14 @@ class Connedit extends Controller } if (App::$poi) { - $abook_prev = 0; $abook_next = 0; $contact_id = App::$poi['abook_id']; $contact = App::$poi; - $cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name", + $cn = q( + "SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name", intval(local_channel()) ); @@ -645,14 +651,14 @@ class Connedit extends Controller $vctmp = (($vc) ? Reader::read($vc) : null); $vcard = (($vctmp) ? get_vcard_array($vctmp, $contact['abook_id']) : []); - if (!$vcard) + if (!$vcard) { $vcard['fn'] = $contact['xchan_name']; + } $tpl = get_markup_template("abook_edit.tpl"); if (Apps::system_app_installed(local_channel(), 'Friend Zoom')) { - $sections['affinity'] = [ 'label' => t('Friend Zoom'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=affinity', @@ -693,7 +699,8 @@ class Connedit extends Controller $rating_val = 0; $rating_text = ''; - $xl = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", + $xl = q( + "select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", dbesc($channel['channel_hash']), dbesc($contact['xchan_hash']) ); @@ -726,22 +733,26 @@ class Connedit extends Controller $multiprofs = ((feature_enabled(local_channel(), 'multi_profiles')) ? true : false); - if ($slide && !$multiprofs) + if ($slide && !$multiprofs) { $affinity = t('Set Friend Zoom'); + } - if (!$slide && $multiprofs) + if (!$slide && $multiprofs) { $affinity = t('Set Profile'); + } - if ($slide && $multiprofs) + if ($slide && $multiprofs) { $affinity = t('Set Friend Zoom & Profile'); + } $theirs = get_abconfig(local_channel(), $contact['abook_xchan'], 'system', 'their_perms', EMPTY_STR); $their_perms = Permissions::FilledPerms(explode(',', $theirs)); foreach ($global_perms as $k => $v) { - if (!array_key_exists($k, $their_perms)) + if (!array_key_exists($k, $their_perms)) { $their_perms[$k] = 1; + } } $my_perms = explode(',', get_abconfig(local_channel(), $contact['abook_xchan'], 'system', 'my_perms', EMPTY_STR)); @@ -753,8 +764,9 @@ class Connedit extends Controller // For auto permissions (when $self is true) we don't want to look at existing // permissions because they are enabled for the channel owner - if ((!$self) && ($existing[$k])) + if ((!$self) && ($existing[$k])) { $thisperm = "1"; + } $perms[] = array('perms_' . $k, $v, ((array_key_exists($k, $their_perms)) ? intval($their_perms[$k]) : ''), $thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); } @@ -769,8 +781,9 @@ class Connedit extends Controller } $locstr = locations_by_netid($contact['xchan_hash']); - if (!$locstr) + if (!$locstr) { $locstr = unpunify($contact['xchan_url']); + } $clone_warn = ''; $clonable = (in_array($contact['xchan_network'], ['zot6', 'zot', 'rss']) ? true : false); @@ -784,8 +797,9 @@ class Connedit extends Controller } - if (intval($contact['abook_not_here']) && $unclonable) + if (intval($contact['abook_not_here']) && $unclonable) { $not_here = t('This connection is unreachable from this location. Location independence is not supported by their network.'); + } $o .= replace_macros($tpl, [ '$header' => (($self) ? t('Connection Default Permissions') : sprintf(t('Connection: %s'), $contact['xchan_name']) . (($contact['abook_alias']) ? ' <' . $contact['abook_alias'] . '>' : '')), @@ -879,7 +893,6 @@ class Connedit extends Controller call_hooks('contact_edit', $arr); return $arr['output']; - } } } diff --git a/Zotlabs/Module/Contactgroup.php b/Zotlabs/Module/Contactgroup.php index b6fd42cd0..50100be78 100644 --- a/Zotlabs/Module/Contactgroup.php +++ b/Zotlabs/Module/Contactgroup.php @@ -1,4 +1,5 @@ 1) && (intval(argv(1)))) { - $group = AccessList::by_id(local_channel(), argv(1)); if (!$group) { diff --git a/Zotlabs/Module/Content_filter.php b/Zotlabs/Module/Content_filter.php index 8da4a26a1..a6a3e6915 100644 --- a/Zotlabs/Module/Content_filter.php +++ b/Zotlabs/Module/Content_filter.php @@ -17,7 +17,6 @@ class Content_filter extends Controller } if ($_POST['content_filter-submit']) { - $incl = ((x($_POST['message_filter_incl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_incl']), ENT_QUOTES) : ''); $excl = ((x($_POST['message_filter_excl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_excl']), ENT_QUOTES) : ''); @@ -25,11 +24,9 @@ class Content_filter extends Controller set_pconfig(local_channel(), 'system', 'message_filter_excl', $excl); info(t('Content Filter settings updated.') . EOL); - } Libsync::build_sync_packet(); - } @@ -72,6 +69,4 @@ class Content_filter extends Controller return $s; } - - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Conversation.php b/Zotlabs/Module/Conversation.php index d7395693b..03f664a0d 100644 --- a/Zotlabs/Module/Conversation.php +++ b/Zotlabs/Module/Conversation.php @@ -1,4 +1,5 @@ 0 order by imgscale asc LIMIT 1", + $r = q( + "SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale > 0 order by imgscale asc LIMIT 1", dbesc($image_id), intval(local_channel()) ); if ($r) { - $max_thumb = intval(get_config('system', 'max_thumbnail', 1600)); $iscaled = false; if (intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) { $imagick_path = get_config('system', 'imagick_convert_path'); if ($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) { - $fname = dbunescbin($r[0]['content']); $tmp_name = $fname . '-001'; $newsize = photo_calculate_scale(array_merge(getimagesize($fname), ['max' => $max_thumb])); $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $fname) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); - // logger('imagick thumbnail command: ' . $cmd); + // logger('imagick thumbnail command: ' . $cmd); for ($x = 0; $x < 4; $x++) { exec($cmd); if (file_exists($tmp_name)) { @@ -128,14 +128,14 @@ class Cover_photo extends Controller $im = photo_factory($base_image['content'], $base_image['mimetype']); if ($im && $im->is_valid()) { - // We are scaling and cropping the relative pixel locations to the original photo instead of the // scaled photo we operated on. // First load the scaled photo to check its size. (Should probably pass this in the post form and save // a query.) - $g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3", + $g = q( + "select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3", dbesc($image_id), intval(local_channel()) ); @@ -151,7 +151,8 @@ class Cover_photo extends Controller // unset all other cover photos - q("update photo set photo_usage = %d where photo_usage = %d and uid = %d", + q( + "update photo set photo_usage = %d where photo_usage = %d and uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_COVER), intval(local_channel()) @@ -196,7 +197,8 @@ class Cover_photo extends Controller if ($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice(t('Image resize failed.') . EOL); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ", + $x = q( + "delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ", dbesc($base_image['resource_id']), local_channel() ); @@ -205,14 +207,12 @@ class Cover_photo extends Controller $channel = App::get_channel(); $this->send_cover_photo_activity($channel, $base_image, $profile); - - - } else + } else { notice(t('Unable to process image') . EOL); + } } goaway(z_root() . '/channel/' . $channel['channel_address']); - } @@ -264,7 +264,6 @@ class Cover_photo extends Controller logger('attach_store: ' . print_r($res, true), LOGGER_DEBUG); json_return_and_die(['message' => $hash]); - } public function send_cover_photo_activity($channel, $photo, $profile) @@ -319,8 +318,6 @@ class Cover_photo extends Controller $arr['author_xchan'] = $channel['channel_hash']; post_activity_item($arr); - - } @@ -344,8 +341,9 @@ class Cover_photo extends Controller $newuser = false; - if (argc() == 2 && argv(1) === 'new') + if (argc() == 2 && argv(1) === 'new') { $newuser = true; + } if (argv(1) === 'use') { if (argc() < 3) { @@ -353,11 +351,12 @@ class Cover_photo extends Controller return; } - // check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); + // check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); $resource_id = argv(2); - $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC", + $r = q( + "SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC", intval(local_channel()), dbesc($resource_id) ); @@ -372,10 +371,10 @@ class Cover_photo extends Controller } } - $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q( + "SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel()) - ); if (!$r) { notice(t('Photo not available.') . EOL); @@ -392,7 +391,8 @@ class Cover_photo extends Controller $smallest = 0; if ($ph && $ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0", + $i = q( + "select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0", dbesc($r[0]['resource_id']), intval(local_channel()) ); @@ -410,7 +410,6 @@ class Cover_photo extends Controller if (!array_key_exists('imagecrop', App::$data)) { - $o .= replace_macros(get_markup_template('cover_photo.tpl'), [ '$user' => App::$channel['channel_address'], '$info' => t('Your cover photo may be visible to anybody on the internet'), @@ -487,6 +486,4 @@ class Cover_photo extends Controller App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []); return; } - - } diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index e406bc3dd..d98b4680c 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { Libprofile::load(argv(1), 0); + } $auth = new BasicAuth(); -// $auth->observer = get_observer_hash(); +// $auth->observer = get_observer_hash(); $auth->setRealm(ucfirst(System::get_platform_name()) . ' ' . 'WebDAV'); @@ -140,5 +143,4 @@ class Dav extends Controller killme(); } - } diff --git a/Zotlabs/Module/Defperms.php b/Zotlabs/Module/Defperms.php index 95b9b406c..ec714b10e 100644 --- a/Zotlabs/Module/Defperms.php +++ b/Zotlabs/Module/Defperms.php @@ -1,4 +1,5 @@ \n"; if (App::$poi) { - $sections = []; $self = false; @@ -267,7 +270,6 @@ class Defperms extends Controller call_hooks('contact_edit', $arr); return $arr['output']; - } } } diff --git a/Zotlabs/Module/Dircensor.php b/Zotlabs/Module/Dircensor.php index ac1e71096..a4348b862 100644 --- a/Zotlabs/Module/Dircensor.php +++ b/Zotlabs/Module/Dircensor.php @@ -5,7 +5,6 @@ namespace Zotlabs\Module; use App; use Zotlabs\Web\Controller; - class Dircensor extends Controller { @@ -26,7 +25,8 @@ class Dircensor extends Controller return; } - $r = q("select * from xchan where xchan_hash = '%s'", + $r = q( + "select * from xchan where xchan_hash = '%s'", dbesc($xchan) ); @@ -36,7 +36,8 @@ class Dircensor extends Controller $val = (($r[0]['xchan_censored']) ? 0 : 1); - q("update xchan set xchan_censored = $val where xchan_hash = '%s'", + q( + "update xchan set xchan_censored = $val where xchan_hash = '%s'", dbesc($xchan) ); @@ -47,7 +48,5 @@ class Dircensor extends Controller } goaway(z_root() . '/directory'); - } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index 426f2f6e7..091e1099c 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -12,7 +12,7 @@ require_once('include/socgraph.php'); require_once('include/bbcode.php'); require_once('include/html2plain.php'); -define( 'DIRECTORY_PAGESIZE', 60); +define('DIRECTORY_PAGESIZE', 60); class Directory extends Controller { @@ -22,7 +22,8 @@ class Directory extends Controller App::set_pager_itemspage(DIRECTORY_PAGESIZE); if (x($_GET, 'ignore') && local_channel()) { - q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ", + q( + "insert into xign ( uid, xchan ) values ( %d, '%s' ) ", intval(local_channel()), dbesc($_GET['ignore']) ); @@ -86,7 +87,6 @@ class Directory extends Controller set_xconfig($observer, 'directory', 'activedir', $active); } } - } public function get() @@ -136,7 +136,6 @@ class Directory extends Controller $suggest = (local_channel() && x($_REQUEST, 'suggest')) ? $_REQUEST['suggest'] : ''; if ($suggest) { - // the directory options have no effect in suggestion mode $globaldir = 1; @@ -177,7 +176,6 @@ class Directory extends Controller } // Remove last space in the advanced query $advanced = rtrim($advanced); - } $tpl = get_markup_template('directory_header.tpl'); @@ -194,7 +192,8 @@ class Directory extends Controller $contacts = []; if (local_channel()) { - $x = q("select abook_xchan from abook where abook_channel = %d", + $x = q( + "select abook_xchan from abook where abook_channel = %d", intval(local_channel()) ); if ($x) { @@ -205,7 +204,6 @@ class Directory extends Controller } if ($url) { - $numtags = get_config('system', 'directorytags'); $kw = ((intval($numtags) > 0) ? intval($numtags) : 50); @@ -270,9 +268,7 @@ class Directory extends Controller $t = 0; $j = json_decode($x['body'], true); if ($j) { - if ($j['results']) { - $results = $j['results']; if ($suggest) { // change order to "number of common friends descending" @@ -284,7 +280,6 @@ class Directory extends Controller $photo = 'thumb'; foreach ($results as $rr) { - $profile_link = chanlink_url($rr['url']); $pdesc = (($rr['description']) ? $rr['description'] . '
' : ''); @@ -328,12 +323,12 @@ class Directory extends Controller $profile = $rr; - $gender = ((x($profile, 'gender') == 1) ? t('Gender: ') . $profile['gender'] : False); - $marital = ((x($profile, 'marital') == 1) ? t('Status: ') . $profile['marital'] : False); - $homepage = ((x($profile, 'homepage') == 1) ? t('Homepage: ') : False); + $gender = ((x($profile, 'gender') == 1) ? t('Gender: ') . $profile['gender'] : false); + $marital = ((x($profile, 'marital') == 1) ? t('Status: ') . $profile['marital'] : false); + $homepage = ((x($profile, 'homepage') == 1) ? t('Homepage: ') : false); $homepageurl = ((x($profile, 'homepage') == 1) ? html2plain($profile['homepage']) : ''); - $hometown = ((x($profile, 'hometown') == 1) ? html2plain($profile['hometown']) : False); - $about = ((x($profile, 'about') == 1) ? zidify_links(bbcode($profile['about'])) : False); + $hometown = ((x($profile, 'hometown') == 1) ? html2plain($profile['hometown']) : false); + $about = ((x($profile, 'about') == 1) ? zidify_links(bbcode($profile['about'])) : false); $keywords = ((x($profile, 'keywords')) ? $profile['keywords'] : ''); @@ -346,7 +341,8 @@ class Directory extends Controller if ($karr) { if (local_channel()) { - $pk = q("select keywords from profile where uid = %d and is_default = 1 limit 1", + $pk = q( + "select keywords from profile where uid = %d and is_default = 1 limit 1", intval(local_channel()) ); if ($pk) { @@ -505,7 +501,8 @@ class Directory extends Controller } elseif (strpos($search, 'http') === 0) { goaway(z_root() . '/chanview/?f=&url=' . $search); } else { - $r = q("select xchan_hash from xchan where xchan_name = '%s' limit 1", + $r = q( + "select xchan_hash from xchan where xchan_name = '%s' limit 1", dbesc($search) ); if ($r) { @@ -539,5 +536,4 @@ class Directory extends Controller } return $out; } - } diff --git a/Zotlabs/Module/Dirsearch.php b/Zotlabs/Module/Dirsearch.php index 8f6cae2e3..4bbdffa29 100644 --- a/Zotlabs/Module/Dirsearch.php +++ b/Zotlabs/Module/Dirsearch.php @@ -45,14 +45,15 @@ class Dirsearch extends Controller if ($advanced) { foreach ($advanced as $adv) { if (in_array($adv['field'], $tables)) { - if ($adv['field'] === 'name') + if ($adv['field'] === 'name') { $sql_extra .= $this->dir_query_build($adv['logic'], 'xchan_name', $adv['value']); - elseif ($adv['field'] === 'address') + } elseif ($adv['field'] === 'address') { $sql_extra .= $this->dir_query_build($adv['logic'], 'xchan_addr', $adv['value']); - elseif ($adv['field'] === 'xhash') + } elseif ($adv['field'] === 'xhash') { $sql_extra .= $this->dir_query_build($adv['logic'], 'xchan_hash', $adv['value']); - else + } else { $sql_extra .= $this->dir_query_build($adv['logic'], 'xprof_' . $adv['field'], $adv['value']); + } } } } @@ -78,8 +79,9 @@ class Dirsearch extends Controller $type = ((array_key_exists('type', $_REQUEST)) ? intval($_REQUEST['type']) : 0); // allow a site to disable the directory's keyword list - if (get_config('system', 'disable_directory_keywords')) + if (get_config('system', 'disable_directory_keywords')) { $kw = 0; + } // by default use a safe search $safe = ((x($_REQUEST, 'safe'))); @@ -91,12 +93,14 @@ class Dirsearch extends Controller // of records that have changed since the sync datetime. if (array_key_exists('sync', $_REQUEST)) { - if ($_REQUEST['sync']) + if ($_REQUEST['sync']) { $sync = datetime_convert('UTC', 'UTC', $_REQUEST['sync']); - else + } else { $sync = datetime_convert('UTC', 'UTC', '2010-01-01 01:01:00'); - } else + } + } else { $sync = false; + } if (($dirmode == DIRECTORY_MODE_STANDALONE) && (!$hub)) { $hub = App::get_hostname(); @@ -109,7 +113,8 @@ class Dirsearch extends Controller } if ($url) { - $r = q("select xchan_name from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_url = '%s' or hubloc_id_url = '%s'", + $r = q( + "select xchan_name from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_url = '%s' or hubloc_id_url = '%s'", dbesc($url), dbesc($url) ); @@ -127,8 +132,9 @@ class Dirsearch extends Controller $joiner = ' OR '; - if ($_REQUEST['and']) + if ($_REQUEST['and']) { $joiner = ' AND '; + } if ($name) { $sql_extra .= $this->dir_query_build($joiner, 'xchan_name', $name); @@ -236,26 +242,25 @@ class Dirsearch extends Controller // punctuation un-searchable in this mode $safesql .= " and ascii(substring(xchan_name FROM 1 FOR 1)) > 64 "; - } elseif ($sort_order == 'reverse') + } elseif ($sort_order == 'reverse') { $order = " order by xchan_name desc "; - elseif ($sort_order == 'reversedate') + } elseif ($sort_order == 'reversedate') { $order = " order by xchan_name_date asc "; - else + } else { $order = " order by xchan_name_date desc "; + } // normal directory query $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where ( $logic $sql_extra ) $hub_query $network and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 - $safesql $activesql $order $qlimit " - ); + $safesql $activesql $order $qlimit "); $ret['page'] = $page + 1; $ret['records'] = count($r); if ($r) { - $entries = []; $dups = []; $isdup = EMPTY_STR; @@ -282,7 +287,6 @@ class Dirsearch extends Controller } foreach ($r as $rr) { - // If it's an activitypub record and the channel also has a zot6 address, don't return it. if (array_key_exists($rr['xchan_url'], $dups)) { @@ -326,7 +330,6 @@ class Dirsearch extends Controller $entry['keywords'] = $rr['xprof_keywords']; $entries[] = $entry; - } $ret['results'] = $entries; @@ -346,8 +349,9 @@ class Dirsearch extends Controller public function dir_query_build($joiner, $field, $s) { $ret = ''; - if (trim($s)) + if (trim($s)) { $ret .= dbesc($joiner) . " " . dbesc($field) . " like '" . protect_sprintf('%' . dbesc($s) . '%') . "' "; + } return $ret; } @@ -381,8 +385,9 @@ class Dirsearch extends Controller continue; } if (strpos($q, '=')) { - if (!isset($curr['logic'])) + if (!isset($curr['logic'])) { $curr['logic'] = 'or'; + } $curr['field'] = trim(substr($q, 0, strpos($q, '='))); $curr['value'] = trim(substr($q, strpos($q, '=') + 1)); if ($curr['value'][0] == '"' && $curr['value'][strlen($curr['value']) - 1] != '"') { @@ -406,8 +411,9 @@ class Dirsearch extends Controller $ret[] = $curr; $curr = []; $quoted_string = false; - } else + } else { $curr['value'] .= ' ' . trim($q); + } } } } @@ -422,7 +428,8 @@ class Dirsearch extends Controller $rand = db_getfunc('rand'); $realm = get_directory_realm(); - $r = q("select * from site where site_type = %d and site_dead = 0", + $r = q( + "select * from site where site_type = %d and site_dead = 0", intval(SITE_TYPE_ZOT) ); @@ -433,28 +440,27 @@ class Dirsearch extends Controller $ret['sites'] = []; foreach ($r as $rr) { - - if ($rr['site_access'] == ACCESS_FREE) + if ($rr['site_access'] == ACCESS_FREE) { $access = 'free'; - elseif ($rr['site_access'] == ACCESS_PAID) + } elseif ($rr['site_access'] == ACCESS_PAID) { $access = 'paid'; - elseif ($rr['site_access'] == ACCESS_TIERED) + } elseif ($rr['site_access'] == ACCESS_TIERED) { $access = 'tiered'; - else + } else { $access = 'private'; + } - if ($rr['site_register'] == REGISTER_OPEN) + if ($rr['site_register'] == REGISTER_OPEN) { $register = 'open'; - elseif ($rr['site_register'] == REGISTER_APPROVE) + } elseif ($rr['site_register'] == REGISTER_APPROVE) { $register = 'approve'; - else + } else { $register = 'closed'; + } $ret['sites'][] = array('url' => $rr['site_url'], 'access' => $access, 'register' => $register, 'sellpage' => $rr['site_sellpage'], 'location' => $rr['site_location'], 'project' => $rr['site_project'], 'version' => $rr['site_version']); - } } return $ret; } - } diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 819f0f945..a18712805 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module; - use App; use Zotlabs\Lib\PermissionDescription; use Zotlabs\Lib\System; @@ -35,12 +34,14 @@ class Display extends Controller if (argc() > 1) { $module_format = substr(argv(1), strrpos(argv(1), '.') + 1); - if (!in_array($module_format, ['atom', 'zot', 'json'])) + if (!in_array($module_format, ['atom', 'zot', 'json'])) { $module_format = 'html'; + } } - if ($this->loading) + if ($this->loading) { $_SESSION['loadtime_display'] = datetime_convert(); + } if (observer_prohibited()) { notice(t('Public access denied.') . EOL); @@ -54,8 +55,9 @@ class Display extends Controller } } - if ($_REQUEST['mid']) + if ($_REQUEST['mid']) { $item_hash = $_REQUEST['mid']; + } if (!$item_hash) { App::$error = 404; @@ -67,7 +69,6 @@ class Display extends Controller $updateable = false; if (local_channel() && (!$this->updating)) { - $channel = App::get_channel(); $channel_acl = array( @@ -115,7 +116,8 @@ class Display extends Controller $item_hash = unpack_link_id($item_hash); - $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1", + $r = q( + "select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1", dbesc($item_hash . '%') ); @@ -123,12 +125,13 @@ class Display extends Controller $target_item = $r[0]; } - $x = q("select * from xchan where xchan_hash = '%s' limit 1", + $x = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($target_item['author_xchan']) ); if ($x) { // not yet ready for prime time -// \App::$poi = $x[0]; +// \App::$poi = $x[0]; } // if the item is to be moderated redirect to /moderate @@ -139,10 +142,12 @@ class Display extends Controller $r = null; if ($target_item['item_type'] == ITEM_TYPE_WEBPAGE) { - $x = q("select * from channel where channel_id = %d limit 1", + $x = q( + "select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q( + "select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -155,10 +160,12 @@ class Display extends Controller } } if ($target_item['item_type'] == ITEM_TYPE_ARTICLE) { - $x = q("select * from channel where channel_id = %d limit 1", + $x = q( + "select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q( + "select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -171,10 +178,12 @@ class Display extends Controller } } if ($target_item['item_type'] == ITEM_TYPE_CARD) { - $x = q("select * from channel where channel_id = %d limit 1", + $x = q( + "select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q( + "select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -198,16 +207,18 @@ class Display extends Controller $simple_update = (($this->updating) ? " AND item_unseen = 1 " : ''); - if ($this->updating && $_SESSION['loadtime_display']) + if ($this->updating && $_SESSION['loadtime_display']) { $simple_update = " AND item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime_display']) . "' "; - if ($this->loading) + } + if ($this->loading) { $simple_update = ''; + } - if ($static && $simple_update) + if ($static && $simple_update) { $simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' "; + } if ((!$this->updating) && (!$this->loading)) { - $static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1); // if the target item is not a post (eg a like) we want to address its thread parent @@ -261,7 +272,6 @@ class Display extends Controller 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string), 'title' => 'oembed' ]); - } $observer_hash = get_observer_hash(); @@ -271,7 +281,6 @@ class Display extends Controller $sql_extra = ((local_channel()) ? EMPTY_STR : item_permissions_sql(0, $observer_hash)); if ($noscript_content || $this->loading) { - $r = null; require_once('include/channel.php'); @@ -279,7 +288,8 @@ class Display extends Controller $sysid = $sys['channel_id']; if (local_channel()) { - $r = q("SELECT item.id as item_id from item WHERE uid = %d and mid = '%s' $item_normal limit 1", + $r = q( + "SELECT item.id as item_id from item WHERE uid = %d and mid = '%s' $item_normal limit 1", intval(local_channel()), dbesc($target_item['parent_mid']) ); @@ -289,7 +299,8 @@ class Display extends Controller } if (!(is_array($r) && count($r))) { - $r = q("SELECT item.id as item_id from item WHERE mid = '%s' $sql_extra $item_normal limit 1", + $r = q( + "SELECT item.id as item_id from item WHERE mid = '%s' $sql_extra $item_normal limit 1", dbesc($target_item['parent_mid']) ); } @@ -301,7 +312,8 @@ class Display extends Controller $sysid = $sys['channel_id']; if (local_channel()) { - $r = q("SELECT item.parent AS item_id from item WHERE uid = %d and parent_mid = '%s' $item_normal_update $simple_update limit 1", + $r = q( + "SELECT item.parent AS item_id from item WHERE uid = %d and parent_mid = '%s' $item_normal_update $simple_update limit 1", intval(local_channel()), dbesc($target_item['parent_mid']) ); @@ -311,7 +323,8 @@ class Display extends Controller } if (!$r) { - $r = q("SELECT item.parent AS item_id from item WHERE parent_mid = '%s' $sql_extra $item_normal_update $simple_update limit 1", + $r = q( + "SELECT item.parent AS item_id from item WHERE parent_mid = '%s' $sql_extra $item_normal_update $simple_update limit 1", dbesc($target_item['parent_mid']) ); } @@ -322,7 +335,8 @@ class Display extends Controller if ($r) { $parents_str = ids_to_querystr($r, 'item_id'); if ($parents_str) { - $items = q("SELECT item.*, item.id AS item_id + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE parent in ( %s ) $item_normal $sql_extra ", dbesc($parents_str) @@ -343,12 +357,10 @@ class Display extends Controller foreach ($items as $item) { if ($item['mid'] === $item_hash) { - - if (preg_match("/\[[zi]mg(.*?)\]([^\[]+)/is", $items[0]['body'], $matches)) { $ogimage = $matches[2]; - // Will we use og:image:type someday? We keep this just in case - // $ogimagetype = guess_image_type($ogimage); + // Will we use og:image:type someday? We keep this just in case + // $ogimagetype = guess_image_type($ogimage); } // some work on post content to generate a description @@ -365,8 +377,9 @@ class Display extends Controller // shorten description $ogdesc = substr($ogdesc, 0, 300); $ogdesc = str_replace("\n", " ", $ogdesc); - while (strpos($ogdesc, " ") !== false) + while (strpos($ogdesc, " ") !== false) { $ogdesc = str_replace(" ", " ", $ogdesc); + } $ogdesc = (strlen($ogdesc) < 298 ? $ogdesc : rtrim(substr($ogdesc, 0, strrpos($ogdesc, " ")), "?.,:;!-") . "..."); $ogsite = (System::get_site_name()) ? escape_tags(System::get_site_name()) : System::get_platform_name(); @@ -413,9 +426,7 @@ class Display extends Controller } switch ($module_format) { - case 'html': - if ($this->updating) { $o .= conversation($items, 'display', $this->updating, 'client'); } else { @@ -435,7 +446,6 @@ class Display extends Controller break; case 'atom': - $atom = replace_macros(get_markup_template('atom_feed.tpl'), array( '$version' => xmlify(System::get_project_version()), '$generator' => xmlify(System::get_platform_name()), @@ -460,8 +470,9 @@ class Display extends Controller if ($items) { $type = 'html'; foreach ($items as $item) { - if ($item['item_private']) + if ($item['item_private']) { continue; + } $atom .= atom_entry($item, $type, null, '', true, '', false); } } @@ -473,23 +484,21 @@ class Display extends Controller header('Content-type: application/atom+xml'); echo $atom; killme(); - } if ($updateable) { - $x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ", + $x = q( + "UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ", intval(local_channel()), intval($r[0]['item_id']) ); - - } $o .= '
'; if ((($this->updating && $this->loading) || $noscript_content) && (!$items)) { - - $r = q("SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1", + $r = q( + "SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1", dbesc($item_hash) ); @@ -502,11 +511,8 @@ class Display extends Controller } else { notice(t('Item not found.') . EOL); } - } return $o; - } - } diff --git a/Zotlabs/Module/Drafts.php b/Zotlabs/Module/Drafts.php index 35ca8802b..722a1139e 100644 --- a/Zotlabs/Module/Drafts.php +++ b/Zotlabs/Module/Drafts.php @@ -27,6 +27,5 @@ class Drafts extends Controller if (!(local_channel() && Apps::system_app_installed(local_channel(), 'Drafts'))) { return $text; } - } } diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index 7d1e3b27f..ebe25016e 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -1,4 +1,5 @@ $b['gravity']) ? 1 : (-1)); } - } diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 198bd30ab..b54ebc7c1 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } public function get() @@ -61,7 +62,8 @@ class Editblock extends Controller if (!$owner) { // Figure out who the page owner is. - $r = q("select channel_id from channel where channel_address = '%s'", + $r = q( + "select channel_id from channel where channel_address = '%s'", dbesc($which) ); if ($r) { @@ -88,16 +90,19 @@ class Editblock extends Controller return; } - $itm = q("SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1", + $itm = q( + "SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1", intval($post_id), intval($owner) ); if ($itm) { - $item_id = q("select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1", + $item_id = q( + "select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1", intval($itm[0]['id']) ); - if ($item_id) + if ($item_id) { $block_title = $item_id[0]['v']; + } } else { notice(t('Item not found') . EOL); return; @@ -106,8 +111,9 @@ class Editblock extends Controller $mimetype = $itm[0]['mimetype']; $content = $itm[0]['body']; - if ($itm[0]['mimetype'] === 'text/markdown') + if ($itm[0]['mimetype'] === 'text/markdown') { $content = MarkdownSoap::unescape($itm[0]['body']); + } $rp = 'blocks/' . $channel['channel_address']; @@ -150,7 +156,5 @@ class Editblock extends Controller )); return $o; - } - } diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index 7bcb3ab47..5eca164da 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } public function get() @@ -60,7 +61,8 @@ class Editlayout extends Controller if (!$owner) { // Figure out who the page owner is. - $r = q("select channel_id from channel where channel_address = '%s'", + $r = q( + "select channel_id from channel where channel_address = '%s'", dbesc($which) ); if ($r) { @@ -98,16 +100,19 @@ class Editlayout extends Controller return; } - $itm = q("SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1", + $itm = q( + "SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1", intval($post_id), intval($owner) ); - $item_id = q("select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1", + $item_id = q( + "select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1", intval($itm[0]['id']) ); - if ($item_id) + if ($item_id) { $layout_title = $item_id[0]['v']; + } $rp = 'layouts/' . $which; @@ -149,7 +154,5 @@ class Editlayout extends Controller )); return $o; - } - } diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 801770ca4..f8eacf6f7 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -1,4 +1,5 @@ t('Edit post'), '$cancel' => t('Cancel'), '$editor' => $editor]); + $output .= replace_macros( + get_markup_template('edpost_head.tpl'), + ['$title' => t('Edit post'), '$cancel' => t('Cancel'), '$editor' => $editor] + ); return $output; - } - } diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 9e7a86bab..8c5af58fd 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } public function get() @@ -63,7 +64,8 @@ class Editwebpage extends Controller if (!$owner) { // Figure out who the page owner is. - $r = q("select channel_id from channel where channel_address = '%s'", + $r = q( + "select channel_id from channel where channel_address = '%s'", dbesc($which) ); if ($r) { @@ -104,7 +106,8 @@ class Editwebpage extends Controller $sql_extra = item_permissions_sql($owner); - $itm = q("SELECT * FROM item WHERE id = %d and uid = %s $sql_extra LIMIT 1", + $itm = q( + "SELECT * FROM item WHERE id = %d and uid = %s $sql_extra LIMIT 1", intval($post_id), intval($owner) ); @@ -117,11 +120,13 @@ class Editwebpage extends Controller return; } - $item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1", + $item_id = q( + "select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1", intval($itm[0]['id']) ); - if ($item_id) + if ($item_id) { $page_title = urldecode($item_id[0]['v']); + } $mimetype = $itm[0]['mimetype']; @@ -135,8 +140,9 @@ class Editwebpage extends Controller $layout = $itm[0]['layout_mid']; $content = $itm[0]['body']; - if ($itm[0]['mimetype'] === 'text/markdown') + if ($itm[0]['mimetype'] === 'text/markdown') { $content = MarkdownSoap::unescape($itm[0]['body']); + } $rp = 'webpages/' . $which; @@ -180,7 +186,5 @@ class Editwebpage extends Controller )); return $o; - } - } diff --git a/Zotlabs/Module/Email_resend.php b/Zotlabs/Module/Email_resend.php index ce00a7cd5..2a5e199fd 100644 --- a/Zotlabs/Module/Email_resend.php +++ b/Zotlabs/Module/Email_resend.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module; - use Zotlabs\Web\Controller; class Email_resend extends Controller @@ -16,7 +15,6 @@ class Email_resend extends Controller notice(t('Token verification failed.')); } } - } @@ -38,13 +36,9 @@ class Email_resend extends Controller } goaway(z_root() . '/email_validation/' . bin2hex($email)); - } // @todo - one can provide a form here to resend the mail // after directing to here if a succesful login was attempted from an unverified address. - - } - } diff --git a/Zotlabs/Module/Email_validation.php b/Zotlabs/Module/Email_validation.php index c6e686f4c..90f68cbca 100644 --- a/Zotlabs/Module/Email_validation.php +++ b/Zotlabs/Module/Email_validation.php @@ -2,7 +2,6 @@ namespace Zotlabs\Module; - use Zotlabs\Web\Controller; class Email_validation extends Controller @@ -47,7 +46,5 @@ class Email_validation extends Controller ]); return $o; - } - -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php index 52e207470..1a26532d9 100644 --- a/Zotlabs/Module/Embedphotos.php +++ b/Zotlabs/Module/Embedphotos.php @@ -55,7 +55,6 @@ class Embedphotos extends Controller json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id)); } json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); - } } @@ -71,7 +70,8 @@ class Embedphotos extends Controller $output = EMPTY_STR; if ($channel) { $resolution = ((feature_enabled($channel['channel_id'], 'large_photos')) ? 1 : 2); - $r = q("select mimetype, height, width, title from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1", + $r = q( + "select mimetype, height, width, title from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1", dbesc($resource), intval($resolution), intval($channel['channel_id']) @@ -92,7 +92,8 @@ class Embedphotos extends Controller $alt = $r[0]['title']; if (!$alt) { - $a = q("select filename from attach where hash = '%s' and uid = %d limit 1", + $a = q( + "select filename from attach where hash = '%s' and uid = %d limit 1", dbesc($resource), intval($channel['channel_id']) ); @@ -138,8 +139,9 @@ class Embedphotos extends Controller require_once('include/security.php'); $sql_extra = permissions_sql($channel_id); - if (!perm_is_allowed($channel_id, get_observer_hash(), 'view_storage')) + if (!perm_is_allowed($channel_id, get_observer_hash(), 'view_storage')) { return ''; + } if ($args['album']) { $album = (($args['album'] === '/') ? '' : $args['album']); @@ -154,7 +156,8 @@ class Embedphotos extends Controller * It is a limitation of the photo table using a name for a photo album instead of a folder hash */ if ($album) { - $x = q("select hash from attach where filename = '%s' and uid = %d limit 1", + $x = q( + "select hash from attach where filename = '%s' and uid = %d limit 1", dbesc($album), intval($owner_uid) ); @@ -168,7 +171,8 @@ class Embedphotos extends Controller $order = 'DESC'; - $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN + $r = q( + "SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale) @@ -237,5 +241,4 @@ class Embedphotos extends Controller return null; } } - } diff --git a/Zotlabs/Module/Event.php b/Zotlabs/Module/Event.php index 06ec8a4ce..abfec6fc7 100644 --- a/Zotlabs/Module/Event.php +++ b/Zotlabs/Module/Event.php @@ -1,4 +1,5 @@ ' - && $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '') { + if ( + $x[0]['allow_cid'] === '<' . $channel['channel_hash'] . '>' + && $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '' + ) { $share = false; } else { $share = true; @@ -237,19 +246,22 @@ class Events extends Controller $event = event_store_event($datarray); - if ($post_tags) + if ($post_tags) { $datarray['term'] = $post_tags; + } $item_id = event_store_item($datarray, $event); if ($item_id) { - $r = q("select * from item where id = %d", + $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", + $z = q( + "select * from event where event_hash = '%s' and uid = %d limit 1", dbesc($r[0]['resource_id']), intval($channel['channel_id']) ); @@ -259,9 +271,9 @@ class Events extends Controller } } - if ($share) + if ($share) { Run::Summon(['Notifier', 'event', $item_id]); - + } } @@ -274,7 +286,8 @@ class Events extends Controller require_once('include/security.php'); $sql_extra = permissions_sql(local_channel()); - $r = q("select * from event where event_hash = '%s' $sql_extra limit 1", + $r = q( + "select * from event where event_hash = '%s' $sql_extra limit 1", dbesc($event_id) ); if ($r) { @@ -298,14 +311,16 @@ class Events extends Controller nav_set_selected('Events'); if ((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { - $r = q("update event set dismissed = 1 where id = %d and uid = %d", + $r = q( + "update event set dismissed = 1 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } if ((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { - $r = q("update event set dismissed = 0 where id = %d and uid = %d", + $r = q( + "update event set dismissed = 0 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); @@ -359,22 +374,24 @@ class Events extends Controller } if ($mode == 'view') { - /* edit/create form */ if ($event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); - if (count($r)) + if (count($r)) { $orig_event = $r[0]; + } } $channel = App::get_channel(); // Passed parameters overrides anything found in the DB - if (!x($orig_event)) + if (!x($orig_event)) { $orig_event = []; + } // In case of an error the browser is redirected back here, with these parameters filled in with the previous values /* @@ -404,16 +421,18 @@ class Events extends Controller $sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (!$orig_event['allow_cid'])) && (!$orig_event['allow_gid']) && (!$orig_event['deny_cid']) && (!$orig_event['deny_gid'])) ? '' : ' checked="checked" '); } - if ($orig_event['event_xchan']) + if ($orig_event['event_xchan']) { $sh_checked .= ' disabled="disabled" '; + } $sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now'); $fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour'); $tz = date_default_timezone_get(); - if (x($orig_event)) + if (x($orig_event)) { $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC'); + } $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); $smonth = datetime_convert('UTC', $tz, $sdt, 'm'); @@ -436,15 +455,17 @@ class Events extends Controller $type = ((x($orig_event)) ? $orig_event['etype'] : 'event'); $f = get_config('system', 'event_input_format'); - if (!$f) + if (!$f) { $f = 'ymd'; + } $catsenabled = Apps::system_app_installed(local_channel(), 'Categories'); $category = ''; if ($catsenabled && x($orig_event)) { - $itm = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d limit 1", + $itm = q( + "select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d limit 1", dbesc($orig_event['event_hash']), intval(local_channel()) ); @@ -452,8 +473,9 @@ class Events extends Controller if ($itm) { $cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY); foreach ($cats as $cat) { - if (strlen($category)) + if (strlen($category)) { $category .= ', '; + } $category .= $cat['term']; } } @@ -531,22 +553,27 @@ class Events extends Controller $thisyear = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); $thismonth = datetime_convert('UTC', date_default_timezone_get(), 'now', 'm'); - if (!$y) + if (!$y) { $y = intval($thisyear); - if (!$m) + } + if (!$m) { $m = intval($thismonth); + } $export = false; - if (argc() === 4 && argv(3) === 'export') + if (argc() === 4 && argv(3) === 'export') { $export = true; + } // Put some limits on dates. The PHP date functions don't seem to do so well before 1900. // An upper limit was chosen to keep search engines from exploring links millions of years in the future. - if ($y < 1901) + if ($y < 1901) { $y = 1900; - if ($y > 2099) + } + if ($y > 2099) { $y = 2100; + } $nextyear = $y; $nextmonth = $m + 1; @@ -556,9 +583,9 @@ class Events extends Controller } $prevyear = $y; - if ($m > 1) + if ($m > 1) { $prevmonth = $m - 1; - else { + } else { $prevmonth = 12; $prevyear--; } @@ -569,8 +596,12 @@ class Events extends Controller if (argv(1) === 'json') { - if (x($_GET, 'start')) $start = $_GET['start']; - if (x($_GET, 'end')) $finish = $_GET['end']; + if (x($_GET, 'start')) { + $start = $_GET['start']; + } + if (x($_GET, 'end')) { + $finish = $_GET['end']; + } } $start = datetime_convert('UTC', 'UTC', $start); @@ -580,13 +611,15 @@ class Events extends Controller $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); if (x($_GET, 'id')) { - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1", intval(local_channel()), intval($_GET['id']) ); } elseif ($export) { - $r = q("SELECT * from event where uid = %d + $r = q( + "SELECT * from event where uid = %d AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ", intval(local_channel()), @@ -601,7 +634,8 @@ class Events extends Controller // Noting this for now - it will need to be fixed here and in Friendica. // Ultimately the finish date shouldn't be involved in the query. - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + $r = q( + "SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on event_hash = resource_id where resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) @@ -626,8 +660,9 @@ class Events extends Controller if ($r) { foreach ($r as $rr) { $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'j') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'j')); - if (!x($links, $j)) + if (!x($links, $j)) { $links[$j] = z_root() . '/' . App::$cmd . '#link-' . $j; + } } } @@ -637,9 +672,7 @@ class Events extends Controller $fmt = t('l, F j'); if ($r) { - foreach ($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'j') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'j')); $d = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], $fmt) : datetime_convert('UTC', 'UTC', $rr['dtstart'], $fmt)); $d = day_translate($d); @@ -653,8 +686,9 @@ class Events extends Controller // give a fake end to birthdays so they get crammed into a // single day on the calendar - if ($rr['etype'] === 'birthday') + if ($rr['etype'] === 'birthday') { $end = null; + } } @@ -692,8 +726,6 @@ class Events extends Controller 'html' => $html, 'plink' => array($rr['plink'], t('Link to Source'), '', ''), ); - - } } @@ -744,7 +776,8 @@ class Events extends Controller } if ($mode === 'drop' && $event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); @@ -752,18 +785,19 @@ class Events extends Controller $sync_event = $r[0]; if ($r) { - $r = q("delete from event where event_hash = '%s' and uid = %d", + $r = q( + "delete from event where event_hash = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); if ($r) { - $i = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d", + $i = q( + "select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); if ($i) { - $can_delete = false; $local_delete = true; @@ -778,12 +812,12 @@ class Events extends Controller if (is_site_admin()) { $local_delete = true; - if (intval($i[0]['item_origin'])) + if (intval($i[0]['item_origin'])) { $can_delete = true; + } } if ($can_delete || $local_delete) { - // if this is a different page type or it's just a local delete // but not by the item author or owner, do a simple deletion @@ -797,7 +831,8 @@ class Events extends Controller $complex = true; } - $ii = q("select * from item where id = %d", + $ii = q( + "select * from item where id = %d", intval($i[0]['id']) ); if ($ii) { @@ -812,7 +847,8 @@ class Events extends Controller } } - $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", + $r = q( + "update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); @@ -826,7 +862,5 @@ class Events extends Controller goaway(z_root() . '/events'); } } - } - } diff --git a/Zotlabs/Module/Expire.php b/Zotlabs/Module/Expire.php index c5b2ab1f5..1123d3f63 100644 --- a/Zotlabs/Module/Expire.php +++ b/Zotlabs/Module/Expire.php @@ -48,8 +48,5 @@ class Expire extends Controller '$addon' => array('expire', t('Automatic Expiration Settings'), '', t('Submit')), '$content' => $setting_fields ]); - } - - } diff --git a/Zotlabs/Module/Fastping.php b/Zotlabs/Module/Fastping.php index d1938a1dc..63fc2e739 100644 --- a/Zotlabs/Module/Fastping.php +++ b/Zotlabs/Module/Fastping.php @@ -68,7 +68,5 @@ class Fastping extends Controller } json_return_and_die($result); - } - } diff --git a/Zotlabs/Module/Fbrowser.php b/Zotlabs/Module/Fbrowser.php index d5c15b293..396e63fce 100644 --- a/Zotlabs/Module/Fbrowser.php +++ b/Zotlabs/Module/Fbrowser.php @@ -1,12 +1,14 @@ + * @package Friendica\modules + * @subpackage FileBrowser + * @author Fabio Comuni */ require_once('include/photo_factory.php'); @@ -18,11 +20,13 @@ class Fbrowser extends Controller public function get() { - if (!local_channel()) + if (!local_channel()) { killme(); + } - if (App::$argc == 1) + if (App::$argc == 1) { killme(); + } //echo "
"; var_dump(\App::$argv); killme();
 
@@ -34,12 +38,12 @@ class Fbrowser extends Controller
                 $sql_extra2 = " ORDER BY created DESC LIMIT 0, 10";
 
                 if (App::$argc == 2) {
-                    $albums = q("SELECT distinct(album) AS album FROM photo WHERE uid = %d ",
+                    $albums = q(
+                        "SELECT distinct(album) AS album FROM photo WHERE uid = %d ",
                         intval(local_channel())
                     );
                     // anon functions only from 5.3.0... meglio tardi che mai..
                     $albums = array_map("self::folder1", $albums);
-
                 }
 
                 $album = "";
@@ -50,7 +54,8 @@ class Fbrowser extends Controller
                     $path[] = array(z_root() . "/fbrowser/image/" . App::$argv[2] . "/", $album);
                 }
 
-                $r = q("SELECT resource_id, id, filename, type, min(imgscale) AS hiq,max(imgscale) AS loq, description  
+                $r = q(
+                    "SELECT resource_id, id, filename, type, min(imgscale) AS hiq,max(imgscale) AS loq, description  
 						FROM photo WHERE uid = %d $sql_extra
 						GROUP BY resource_id $sql_extra2",
                     intval(local_channel())
@@ -72,7 +77,8 @@ class Fbrowser extends Controller
                 break;
             case "file":
                 if (App::$argc == 2) {
-                    $files = q("SELECT id, filename, filetype FROM attach WHERE uid = %d ",
+                    $files = q(
+                        "SELECT id, filename, filetype FROM attach WHERE uid = %d ",
                         intval(local_channel())
                     );
 
@@ -89,7 +95,6 @@ class Fbrowser extends Controller
                         '$files' => $files,
                         '$cancel' => t('Cancel'),
                     ));
-
                 }
 
                 break;
@@ -97,7 +102,6 @@ class Fbrowser extends Controller
 
 
         killme();
-
     }
 
     private static function folder1($el)
@@ -135,6 +139,4 @@ class Fbrowser extends Controller
 
         return array(z_root() . '/attach/' . $rr['id'], $filename_e, z_root() . '/images/icons/16/' . $filetype . '.png');
     }
-
-
 }
diff --git a/Zotlabs/Module/Fedi_id.php b/Zotlabs/Module/Fedi_id.php
index f69455b6d..cb4328070 100644
--- a/Zotlabs/Module/Fedi_id.php
+++ b/Zotlabs/Module/Fedi_id.php
@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
 
 use Zotlabs\Web\Controller;
 
-
 class Fedi_id extends Controller
 {
 
@@ -17,7 +16,8 @@ class Fedi_id extends Controller
         if ($_REQUEST['address']) {
             $x = discover_by_webbie(trim($_REQUEST['address']));
             if ($x) {
-                $ab = q("select * from abook where abook_xchan = '%s' and abook_channel = %d",
+                $ab = q(
+                    "select * from abook where abook_xchan = '%s' and abook_channel = %d",
                     dbesc($x),
                     intval($channel['channel_id'])
                 );
@@ -25,7 +25,8 @@ class Fedi_id extends Controller
                     notice(t('You are already connected with this channel.'));
                     goaway(channel_url($channel));
                 }
-                $r = q("select * from xchan where xchan_hash = '%s'",
+                $r = q(
+                    "select * from xchan where xchan_hash = '%s'",
                     dbesc($x)
                 );
                 if ($r && $r[0]['xchan_follow']) {
@@ -41,7 +42,8 @@ class Fedi_id extends Controller
     public function get()
     {
 
-        return replace_macros(get_markup_template('fedi_id.tpl'),
+        return replace_macros(
+            get_markup_template('fedi_id.tpl'),
             [
                 '$title' => t('Home instance'),
                 '$address' => ['address', t('Enter your channel address or fediverse ID (e.g. channel@example.com)'), '', t('If you do not have a fediverse ID, please use your browser \'back\' button to return to the previous page')],
@@ -50,7 +52,5 @@ class Fedi_id extends Controller
                 '$submit' => t('Connect')
             ]
         );
-
     }
-
-}
\ No newline at end of file
+}
diff --git a/Zotlabs/Module/Feed.php b/Zotlabs/Module/Feed.php
index 8966ff598..69347ba69 100644
--- a/Zotlabs/Module/Feed.php
+++ b/Zotlabs/Module/Feed.php
@@ -1,4 +1,5 @@
  1) {
-
             if (observer_prohibited(true)) {
                 killme();
             }
@@ -45,7 +45,5 @@ class Feed extends Controller
 
             killme();
         }
-
     }
-
 }
diff --git a/Zotlabs/Module/File_upload.php b/Zotlabs/Module/File_upload.php
index a9d92e648..7e10c9c52 100644
--- a/Zotlabs/Module/File_upload.php
+++ b/Zotlabs/Module/File_upload.php
@@ -1,4 +1,5 @@
  array($sync)));
                 }
                 goaway(z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']);
-
             }
         } else {
-
             $matches = [];
             $partial = false;
 
@@ -97,13 +96,11 @@ class File_upload extends Controller
             $r = attach_store($channel, get_observer_hash(), '', $_REQUEST);
             if ($r['success']) {
                 $sync = attach_export_data($channel, $r['data']['hash']);
-                if ($sync)
+                if ($sync) {
                     Libsync::build_sync_packet($channel['channel_id'], array('file' => array($sync)));
-
+                }
             }
         }
         goaway(z_root() . '/' . $_REQUEST['return_url']);
-
     }
-
 }
diff --git a/Zotlabs/Module/Filer.php b/Zotlabs/Module/Filer.php
index 7ab4a0fb2..6596dcd8a 100644
--- a/Zotlabs/Module/Filer.php
+++ b/Zotlabs/Module/Filer.php
@@ -1,4 +1,5 @@
  1) ? intval(App::$argv[1]) : 0);
 
         logger('filerm: tag ' . $term . ' item ' . $item_id);
 
         if ($item_id && strlen($term)) {
-            $r = q("delete from term where uid = %d and ttype = %d and oid = %d and term = '%s'",
+            $r = q(
+                "delete from term where uid = %d and ttype = %d and oid = %d and term = '%s'",
                 intval(local_channel()),
                 intval(($category) ? TERM_CATEGORY : TERM_FILE),
                 intval($item_id),
@@ -35,10 +37,10 @@ class Filerm extends Controller
             );
         }
 
-        if (x($_SESSION, 'return_url'))
+        if (x($_SESSION, 'return_url')) {
             goaway(z_root() . '/' . $_SESSION['return_url']);
+        }
 
         killme();
     }
-
 }
diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php
index 21efd1452..2acef08c3 100644
--- a/Zotlabs/Module/Filestorage.php
+++ b/Zotlabs/Module/Filestorage.php
@@ -1,6 +1,6 @@
  array($sync)));
         }
 
-//		file_activity($channel_id, $object, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], 'post', $notify);
+//      file_activity($channel_id, $object, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], 'post', $notify);
 
         goaway(dirname($url));
     }
@@ -114,7 +114,6 @@ class Filestorage extends Controller
 
 
         if (argc() > 3 && argv(3) === 'delete') {
-
             if (argc() > 4 && argv(4) === 'json') {
                 $json_return = true;
             }
@@ -134,7 +133,8 @@ class Filestorage extends Controller
             }
 
             $file = intval(argv(2));
-            $r = q("SELECT hash, creator FROM attach WHERE id = %d AND uid = %d LIMIT 1",
+            $r = q(
+                "SELECT hash, creator FROM attach WHERE id = %d AND uid = %d LIMIT 1",
                 dbesc($file),
                 intval($owner)
             );
@@ -199,7 +199,8 @@ class Filestorage extends Controller
 
             $file = intval(argv(2));
 
-            $r = q("select id, uid, folder, filename, revision, flags, is_dir, os_storage, hash, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and uid = %d limit 1",
+            $r = q(
+                "select id, uid, folder, filename, revision, flags, is_dir, os_storage, hash, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and uid = %d limit 1",
                 intval($file),
                 intval($owner)
             );
diff --git a/Zotlabs/Module/Finger.php b/Zotlabs/Module/Finger.php
index 44665ea67..bdfeff2cb 100644
--- a/Zotlabs/Module/Finger.php
+++ b/Zotlabs/Module/Finger.php
@@ -25,7 +25,6 @@ class Finger extends Controller
         ]);
 
         if ($_GET['resource']) {
-
             $resource = trim(escape_tags($_GET['resource']));
 
             $result = Webfinger::exec($resource);
@@ -34,5 +33,4 @@ class Finger extends Controller
         }
         return $o;
     }
-
 }
diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php
index 65feca08c..a97d50b92 100644
--- a/Zotlabs/Module/Follow.php
+++ b/Zotlabs/Module/Follow.php
@@ -1,4 +1,5 @@
 = 2) {
             $abook_id = intval(argv(1));
-            if (!$abook_id)
+            if (!$abook_id) {
                 return;
+            }
 
-            $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d",
+            $r = q(
+                "select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d",
                 intval($abook_id)
             );
             if (!$r) {
@@ -56,7 +59,6 @@ class Follow extends Controller
                 'actor' => $actor,
                 'object' => $r[0]['xchan_url']
             ], $chan);
-
         }
 
 
@@ -77,8 +79,10 @@ class Follow extends Controller
             if ($n && isset($n['type']) && !ActivityStreams::is_an_actor($n['type'])) {
                 // set client flag to convert objects to implied activities
                 $a = new ActivityStreams($n, null, true);
-                if ($a->type === 'Announce' && is_array($a->obj)
-                    && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) {
+                if (
+                    $a->type === 'Announce' && is_array($a->obj)
+                    && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)
+                ) {
                     // This is a relayed/forwarded Activity (as opposed to a shared/boosted object)
                     // Reparse the encapsulated Activity and use that instead
                     logger('relayed activity', LOGGER_DEBUG);
@@ -86,7 +90,6 @@ class Follow extends Controller
                 }
 
                 if ($a->is_valid()) {
-
                     if (is_array($a->actor) && array_key_exists('id', $a->actor)) {
                         Activity::actor_store($a->actor['id'], $a->actor);
                     }
@@ -97,7 +100,8 @@ class Follow extends Controller
                     if ($item) {
                         Activity::store($channel, get_observer_hash(), $a, $item, true);
 
-                        $r = q("select * from item where mid = '%s' and uid = %d",
+                        $r = q(
+                            "select * from item where mid = '%s' and uid = %d",
                             dbesc($item['mid']),
                             intval($uid)
                         );
@@ -118,7 +122,6 @@ class Follow extends Controller
         $result = Connect::connect($channel, $url);
 
         if ($result['success'] == false) {
-
             if ($result['message']) {
                 notice($result['message']);
             }
@@ -160,7 +163,6 @@ class Follow extends Controller
         } else {
             json_return_and_die(['success' => true]);
         }
-
     }
 
     public function get()
diff --git a/Zotlabs/Module/Followers.php b/Zotlabs/Module/Followers.php
index 378ef4de8..19485452d 100644
--- a/Zotlabs/Module/Followers.php
+++ b/Zotlabs/Module/Followers.php
@@ -30,9 +30,9 @@ class Followers extends Controller
             http_status_exit(404, 'Not found');
         }
 
-//		if (intval($channel['channel_system'])) {
-//			http_status_exit(403,'Permission denied');
-//		}
+//      if (intval($channel['channel_system'])) {
+//          http_status_exit(403,'Permission denied');
+//      }
 
         Libprofile::load(argv(1));
 
@@ -46,7 +46,8 @@ class Followers extends Controller
             http_status_exit(403, 'Forbidden');
         }
 
-        $t = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 ",
+        $t = q(
+            "select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 ",
             intval($channel['channel_id']),
             intval($channel['channel_id']),
             dbesc($channel['channel_hash'])
@@ -61,7 +62,8 @@ class Followers extends Controller
         } else {
             $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
 
-            $r = q("select * from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 $pager_sql",
+            $r = q(
+                "select * from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 $pager_sql",
                 intval($channel['channel_id']),
                 intval($channel['channel_id']),
                 dbesc($channel['channel_hash'])
@@ -73,7 +75,5 @@ class Followers extends Controller
         if (ActivityStreams::is_as_request()) {
             as_return_and_die($ret, $channel);
         }
-
     }
-
 }
diff --git a/Zotlabs/Module/Following.php b/Zotlabs/Module/Following.php
index 1de7a269e..ec6171add 100644
--- a/Zotlabs/Module/Following.php
+++ b/Zotlabs/Module/Following.php
@@ -1,4 +1,5 @@
 ' . $desc . '';
 
         return $text;
-
     }
-
 }
diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php
index a2be961c0..a2cd7c40f 100644
--- a/Zotlabs/Module/Getfile.php
+++ b/Zotlabs/Module/Getfile.php
@@ -1,4 +1,5 @@
  0) {
-            $r = q("select * from photo where resource_id = '%s' and uid = %d and imgscale = %d limit 1",
+            $r = q(
+                "select * from photo where resource_id = '%s' and uid = %d and imgscale = %d limit 1",
                 dbesc($resource),
                 intval($channel['channel_id']),
                 intval($resolution)
@@ -97,10 +98,11 @@ class Getfile extends Controller
 
                 if (intval($r[0]['os_storage'])) {
                     $fname = dbunescbin($r[0]['content']);
-                    if (strpos($fname, 'store') !== false)
+                    if (strpos($fname, 'store') !== false) {
                         $istream = fopen($fname, 'rb');
-                    else
+                    } else {
                         $istream = fopen('store/' . $channel['channel_address'] . '/' . $fname, 'rb');
+                    }
                     $ostream = fopen('php://output', 'wb');
                     if ($istream && $ostream) {
                         pipe_streams($istream, $ostream);
@@ -126,10 +128,11 @@ class Getfile extends Controller
         header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"');
         if (intval($r['data']['os_storage'])) {
             $fname = dbunescbin($r['data']['content']);
-            if (strpos($fname, 'store') !== false)
+            if (strpos($fname, 'store') !== false) {
                 $istream = fopen($fname, 'rb');
-            else
+            } else {
                 $istream = fopen('store/' . $channel['channel_address'] . '/' . $fname, 'rb');
+            }
             $ostream = fopen('php://output', 'wb');
             if ($istream && $ostream) {
                 pipe_streams($istream, $ostream);
diff --git a/Zotlabs/Module/Hashtags.php b/Zotlabs/Module/Hashtags.php
index ccf7d76ec..9b8ee35f4 100644
--- a/Zotlabs/Module/Hashtags.php
+++ b/Zotlabs/Module/Hashtags.php
@@ -17,10 +17,12 @@ class Hashtags extends Controller
         $result = [];
 
         $t = escape_tags($_REQUEST['t']);
-        if (!$t)
+        if (!$t) {
             json_return_and_die($result);
+        }
 
-        $r = q("select distinct(term) from term where term like '%s' and ttype = %d order by term",
+        $r = q(
+            "select distinct(term) from term where term like '%s' and ttype = %d order by term",
             dbesc($t . '%'),
             intval(TERM_HASHTAG)
         );
@@ -32,4 +34,4 @@ class Hashtags extends Controller
 
         json_return_and_die($result);
     }
-}
\ No newline at end of file
+}
diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php
index fab97a6a3..14f078021 100644
--- a/Zotlabs/Module/Hcard.php
+++ b/Zotlabs/Module/Hcard.php
@@ -1,4 +1,5 @@
  1)
+        if (argc() > 1) {
             $which = argv(1);
-        else {
+        } else {
             notice(t('Requested profile is not available.') . EOL);
             App::$error = 404;
             return;
@@ -27,12 +28,14 @@ class Hcard extends Controller
         if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
             $which = $channel['channel_address'];
             $profile = argv(1);
-            $r = q("select profile_guid from profile where id = %d and uid = %d limit 1",
+            $r = q(
+                "select profile_guid from profile where id = %d and uid = %d limit 1",
                 intval($profile),
                 intval(local_channel())
             );
-            if (!$r)
+            if (!$r) {
                 $profile = '';
+            }
             $profile = $r[0]['profile_guid'];
         }
 
@@ -52,7 +55,8 @@ class Hcard extends Controller
 
 
         if (!$profile) {
-            $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
+            $x = q(
+                "select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
                 dbesc(argv(1))
             );
             if ($x) {
@@ -61,8 +65,6 @@ class Hcard extends Controller
         }
 
         Libprofile::load($which, $profile);
-
-
     }
 
 
@@ -71,8 +73,5 @@ class Hcard extends Controller
 
         $x = new \Zotlabs\Widget\Profile();
         return $x->widget([]);
-
     }
-
-
 }
diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php
index d761b4c36..151d70c64 100644
--- a/Zotlabs/Module/Help.php
+++ b/Zotlabs/Module/Help.php
@@ -1,4 +1,5 @@
  2 && argv(argc() - 2) === 'assets') {
             $path = '';
             for ($x = 1; $x < argc(); $x++) {
-                if (strlen($path))
+                if (strlen($path)) {
                     $path .= '/';
+                }
                 $path .= argv($x);
             }
             $realpath = 'doc/' . $path;
@@ -137,6 +139,4 @@ class Help extends Controller
         closedir($handle);
         return $results;
     }
-
-
 }
diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php
index 51c25cd89..69305efcb 100644
--- a/Zotlabs/Module/Home.php
+++ b/Zotlabs/Module/Home.php
@@ -1,4 +1,5 @@
  $channel['channel_hash'], 'target_url' => $sigdata['signer']]));
-                $s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
+                $s = q(
+                    "select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
                     dbesc($sigdata['signer'])
                 );
 
@@ -94,7 +95,8 @@ class Home extends Controller
         }
 
         if (remote_channel() && (!$splash) && $_SESSION['atoken']) {
-            $r = q("select * from atoken where atoken_id = %d",
+            $r = q(
+                "select * from atoken where atoken_id = %d",
                 intval($_SESSION['atoken'])
             );
             if ($r) {
@@ -109,7 +111,6 @@ class Home extends Controller
         if (get_account_id() && !$splash) {
             goaway(z_root() . '/new_channel');
         }
-
     }
 
 
diff --git a/Zotlabs/Module/Hostxrd.php b/Zotlabs/Module/Hostxrd.php
index ea6740d47..2aa569c64 100644
--- a/Zotlabs/Module/Hostxrd.php
+++ b/Zotlabs/Module/Hostxrd.php
@@ -1,6 +1,6 @@
 loading)
+        if ($this->loading) {
             $_SESSION['loadtime_hq'] = datetime_convert();
+        }
 
         if (argc() > 1 && argv(1) !== 'load') {
             $item_hash = argv(1);
         }
 
-        if ($_REQUEST['mid'])
+        if ($_REQUEST['mid']) {
             $item_hash = $_REQUEST['mid'];
+        }
 
         $item_normal = item_normal();
         $item_normal_update = item_normal_update();
 
         if (!$item_hash) {
-            $r = q("SELECT mid FROM item 
+            $r = q(
+                "SELECT mid FROM item 
 				WHERE uid = %d $item_normal
 				AND mid = parent_mid 
 				ORDER BY created DESC LIMIT 1",
@@ -80,12 +87,12 @@ class Hq extends Controller
         }
 
         if ($item_hash) {
-
             $item_hash = unpack_link_id($item_hash);
 
             $target_item = null;
 
-            $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
+            $r = q(
+                "select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
                 dbesc($item_hash . '%')
             );
 
@@ -102,17 +109,18 @@ class Hq extends Controller
 
             $simple_update = (($this->updating) ? " AND item_unseen = 1 " : '');
 
-            if ($this->updating && $_SESSION['loadtime_hq'])
+            if ($this->updating && $_SESSION['loadtime_hq']) {
                 $simple_update = " AND item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime_hq']) . "' ";
+            }
 
-            if ($static && $simple_update)
+            if ($static && $simple_update) {
                 $simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
+            }
 
             $sys = get_sys_channel();
             $sql_extra = item_permissions_sql($sys['channel_id']);
 
             $sys_item = false;
-
         }
 
         if (!$this->updating) {
@@ -145,18 +153,17 @@ class Hq extends Controller
                 'reset' => t('Reset form')
             ];
 
-            $o = replace_macros(get_markup_template("hq.tpl"),
+            $o = replace_macros(
+                get_markup_template("hq.tpl"),
                 [
                     '$no_messages' => (($target_item) ? false : true),
                     '$no_messages_label' => [t('Welcome to $Projectname!'), t('You have got no unseen posts...')],
                     '$editor' => status_editor($x)
                 ]
             );
-
         }
 
         if (!$this->updating && !$this->loading) {
-
             nav_set_selected('HQ');
 
             $static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1);
@@ -214,7 +221,8 @@ class Hq extends Controller
         if ($this->loading && $target_item) {
             $r = null;
 
-            $r = q("SELECT item.id AS item_id FROM item
+            $r = q(
+                "SELECT item.id AS item_id FROM item
 				WHERE uid = %d
 				AND mid = '%s'
 				$item_normal
@@ -230,7 +238,8 @@ class Hq extends Controller
             if (!$r) {
                 $sys_item = true;
 
-                $r = q("SELECT item.id AS item_id FROM item
+                $r = q(
+                    "SELECT item.id AS item_id FROM item
 					LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
 					WHERE mid = '%s' AND item.uid = %d $item_normal
 					AND (abook.abook_blocked = 0 or abook.abook_flags is null)
@@ -242,7 +251,8 @@ class Hq extends Controller
         } elseif ($this->updating && $target_item) {
             $r = null;
 
-            $r = q("SELECT item.parent AS item_id FROM item
+            $r = q(
+                "SELECT item.parent AS item_id FROM item
 				WHERE uid = %d
 				AND parent_mid = '%s'
 				$item_normal_update
@@ -259,7 +269,8 @@ class Hq extends Controller
             if (!$r) {
                 $sys_item = true;
 
-                $r = q("SELECT item.parent AS item_id FROM item
+                $r = q(
+                    "SELECT item.parent AS item_id FROM item
 					LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
 					WHERE mid = '%s' AND item.uid = %d $item_normal_update $simple_update
 					AND (abook.abook_blocked = 0 or abook.abook_flags is null)
@@ -275,7 +286,8 @@ class Hq extends Controller
         }
 
         if ($r) {
-            $items = q("SELECT item.*, item.id AS item_id 
+            $items = q(
+                "SELECT item.*, item.id AS item_id 
 				FROM item
 				WHERE parent = '%s' $item_normal ",
                 dbesc($r[0]['item_id'])
@@ -291,7 +303,8 @@ class Hq extends Controller
         $o .= conversation($items, 'hq', $this->updating, 'client');
 
         if ($updateable) {
-            $x = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d AND parent = %d ",
+            $x = q(
+                "UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d AND parent = %d ",
                 intval(local_channel()),
                 intval($r[0]['item_id'])
             );
@@ -300,7 +313,5 @@ class Hq extends Controller
         $o .= '
'; return $o; - } - } diff --git a/Zotlabs/Module/Id.php b/Zotlabs/Module/Id.php index 283327ce0..53b126fe3 100644 --- a/Zotlabs/Module/Id.php +++ b/Zotlabs/Module/Id.php @@ -7,8 +7,8 @@ namespace Zotlabs\Module; * Controller for responding to x-zot: protocol requests * x-zot:_jkfRG85nJ-714zn-LW_VbTFW8jSjGAhAydOcJzHxqHkvEHWG2E0RbA_pbch-h4R63RG1YJZifaNzgccoLa3MQ/453c1678-1a79-4af7-ab65-6b012f6cab77 - * - */ + * + */ use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Activity; @@ -34,7 +34,6 @@ class Id extends Controller { if (Libzot::is_zot_request()) { - $conversation = false; $request_portable_id = argv(1); @@ -69,13 +68,14 @@ class Id extends Controller $sql_extra = item_permissions_sql(0); - $r = q("select * from item where uuid = '%s' $item_normal $sql_extra and uid = %d limit 1", + $r = q( + "select * from item where uuid = '%s' $item_normal $sql_extra and uid = %d limit 1", dbesc($item_id), intval($channel_id) ); if (!$r) { - - $r = q("select * from item where uuid = '%s' $item_normal and uid = %d limit 1", + $r = q( + "select * from item where uuid = '%s' $item_normal and uid = %d limit 1", dbesc($item_id), intval($channel_id) ); @@ -85,16 +85,18 @@ class Id extends Controller http_status_exit(404, 'Not found'); } - if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) + if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) { http_status_exit(403, 'Forbidden'); + } xchan_query($r, true); $items = fetch_post_tags($r, true); $i = Activity::encode_item($items[0], (get_config('system', 'activitypub', ACTIVITYPUB_ENABLED) ? true : false)); - if (!$i) + if (!$i) { http_status_exit(404, 'Not found'); + } $x = array_merge(['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, @@ -111,11 +113,6 @@ class Id extends Controller HTTPSig::set_headers($h); echo $ret; killme(); - } - } - } - - diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php index 0a2c248d0..4e2cd2524 100644 --- a/Zotlabs/Module/Impel.php +++ b/Zotlabs/Module/Impel.php @@ -1,5 +1,8 @@ false); - if (!local_channel()) + if (!local_channel()) { json_return_and_die($ret); + } logger('impel: ' . print_r($_REQUEST, true), LOGGER_DATA); $elm = $_REQUEST['element']; $x = base64url_decode($elm); - if (!$x) + if (!$x) { json_return_and_die($ret); + } $j = json_decode($x, true); - if (!$j) + if (!$j) { json_return_and_die($ret); + } // logger('element: ' . print_r($j,true)); @@ -76,18 +82,21 @@ class Impel extends Controller $m['menu_channel_id'] = local_channel(); $m['menu_name'] = $j['pagetitle']; $m['menu_desc'] = $j['desc']; - if ($j['created']) + if ($j['created']) { $m['menu_created'] = datetime_convert($j['created']); - if ($j['edited']) + } + if ($j['edited']) { $m['menu_edited'] = datetime_convert($j['edited']); + } $m['menu_flags'] = 0; if ($j['flags']) { - if (in_array('bookmark', $j['flags'])) + if (in_array('bookmark', $j['flags'])) { $m['menu_flags'] |= MENU_BOOKMARK; - if (in_array('system', $j['flags'])) + } + if (in_array('system', $j['flags'])) { $m['menu_flags'] |= MENU_SYSTEM; - + } } $menu_id = menu_create($m); @@ -106,17 +115,21 @@ class Impel extends Controller $mitem['mitem_order'] = intval($it['order']); if (is_array($it['flags'])) { $mitem['mitem_flags'] = 0; - if (in_array('zid', $it['flags'])) + if (in_array('zid', $it['flags'])) { $mitem['mitem_flags'] |= MENU_ITEM_ZID; - if (in_array('new-window', $it['flags'])) + } + if (in_array('new-window', $it['flags'])) { $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN; - if (in_array('chatroom', $it['flags'])) + } + if (in_array('chatroom', $it['flags'])) { $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM; + } } menu_add_item($menu_id, local_channel(), $mitem); } if ($j['edited']) { - $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", + $x = q( + "update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", dbesc(datetime_convert('UTC', 'UTC', $j['edited'])), intval($menu_id), intval(local_channel()) @@ -156,7 +169,8 @@ class Impel extends Controller $execflag = ((intval($channel['channel_id']) == intval(local_channel()) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false); - $i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", + $i = q( + "select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", dbesc($arr['mid']), intval(local_channel()) ); @@ -166,17 +180,20 @@ class Impel extends Controller if ($i) { $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original - if ($arr['edited'] > $i[0]['edited']) + if ($arr['edited'] > $i[0]['edited']) { $x = item_store_update($arr, $execflag); + } } else { if (($i) && (intval($i[0]['item_deleted']))) { // was partially deleted already, finish it off - q("delete from item where mid = '%s' and uid = %d", + q( + "delete from item where mid = '%s' and uid = %d", dbesc($arr['mid']), intval(local_channel()) ); - } else + } else { $x = item_store($arr, $execflag); + } } if ($x && $x['success']) { @@ -194,7 +211,5 @@ class Impel extends Controller //??? should perhaps return ret? json_return_and_die(true); - } - } diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 9040c0f96..5e006bba4 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -9,10 +9,8 @@ use Zotlabs\Web\HTTPSig; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Connect; use Zotlabs\Daemon\Run; - use Zotlabs\Import\Friendica; - require_once('include/import.php'); require_once('include/photo_factory.php'); @@ -53,7 +51,6 @@ class Import extends Controller // import channel from file if ($src) { - // This is OS specific and could also fail if your tmpdir isn't very // large mostly used for Diaspora which exports gzipped files. @@ -123,7 +120,6 @@ class Import extends Controller // handle Friendica export if (array_path_exists('user/parent-uid', $data)) { - $settings = ['account_id' => $account_id, 'sieze' => 1, 'newname' => $newname]; $f = new Friendica($data, $settings); @@ -153,11 +149,11 @@ class Import extends Controller $relocate = ((array_key_exists('relocate', $data)) ? $data['relocate'] : null); if (array_key_exists('channel', $data)) { - $max_identities = account_service_class_fetch($account_id, 'total_identities'); if ($max_identities !== false) { - $r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 ", + $r = q( + "select channel_id from channel where channel_account_id = %d and channel_removed = 0 ", intval($account_id) ); if ($r && count($r) > $max_identities) { @@ -215,10 +211,10 @@ class Import extends Controller // This *must* be done before importing hublocs if (array_key_exists('channel', $data) && $seize) { - // replace any existing xchan we may have on this site if we're seizing control - $r = q("delete from xchan where xchan_hash = '%s'", + $r = q( + "delete from xchan where xchan_hash = '%s'", dbesc($channel['channel_hash']) ); @@ -250,7 +246,6 @@ class Import extends Controller $xchans = $data['xchan']; if ($xchans) { foreach ($xchans as $xchan) { - // Provide backward compatibility for zot11 based projects if ($xchan['xchan_network'] === 'nomad' && version_compare(ZOT_REVISION, '10.0') <= 0) { @@ -264,7 +259,8 @@ class Import extends Controller continue; } - $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($xchan['xchan_hash']) ); if ($r) { @@ -274,7 +270,8 @@ class Import extends Controller if ($xchan['xchan_hash'] === $channel['channel_hash']) { - $r = q("update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'", + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']), dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']), @@ -290,7 +287,8 @@ class Import extends Controller $photodate = $xchan['xchan_photo_date']; } - $r = q("update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'", + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), @@ -341,7 +339,8 @@ class Import extends Controller // reset the original primary hubloc if it is being seized if ($seize) { - $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", + $r = q( + "update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", dbesc($channel['channel_hash']), dbesc(z_root()) ); @@ -356,7 +355,6 @@ class Import extends Controller $abooks = $data['abook']; if ($abooks) { foreach ($abooks as $abook) { - $abook_copy = $abook; $abconfig = null; @@ -393,7 +391,8 @@ class Import extends Controller $ctype = 1; } if ($ctype) { - q("update xchan set xchan_type = %d where xchan_hash = '%s' ", + q( + "update xchan set xchan_type = %d where xchan_hash = '%s' ", intval($ctype), dbesc($abook['abook_xchan']) ); @@ -407,7 +406,8 @@ class Import extends Controller } } - $r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + $r = q( + "select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($abook['abook_xchan']), intval($channel['channel_id']) ); @@ -418,7 +418,8 @@ class Import extends Controller if (!in_array($k, $columns)) { continue; } - $r = q("UPDATE abook SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE abook_xchan = '%s' AND abook_channel = %d", + $r = q( + "UPDATE abook SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE abook_xchan = '%s' AND abook_channel = %d", dbesc($k), dbesc($v), dbesc($abook['abook_xchan']), @@ -462,7 +463,8 @@ class Import extends Controller create_table_from_array('pgrp', $group); } - $r = q("select * from pgrp where uid = %d", + $r = q( + "select * from pgrp where uid = %d", intval($channel['channel_id']) ); if ($r) { @@ -514,27 +516,27 @@ class Import extends Controller if (is_array($data['chatroom'])) { import_chatrooms($channel, $data['chatroom']); } -// if (is_array($data['conv'])) { -// import_conv($channel,$data['conv']); -// } -// if (is_array($data['mail'])) { -// import_mail($channel,$data['mail']); -// } +// if (is_array($data['conv'])) { +// import_conv($channel,$data['conv']); +// } +// if (is_array($data['mail'])) { +// import_mail($channel,$data['mail']); +// } if (is_array($data['event'])) { import_events($channel, $data['event']); } if (is_array($data['event_item'])) { import_items($channel, $data['event_item'], false, $relocate); } -// if (is_array($data['menu'])) { -// import_menus($channel,$data['menu']); -// } -// if (is_array($data['wiki'])) { -// import_items($channel,$data['wiki'],false,$relocate); -// } -// if (is_array($data['webpages'])) { -// import_items($channel,$data['webpages'],false,$relocate); -// } +// if (is_array($data['menu'])) { +// import_menus($channel,$data['menu']); +// } +// if (is_array($data['wiki'])) { +// import_items($channel,$data['wiki'],false,$relocate); +// } +// if (is_array($data['webpages'])) { +// import_items($channel,$data['webpages'],false,$relocate); +// } $addon = array('channel' => $channel, 'data' => $data); call_hooks('import_channel', $addon); @@ -544,7 +546,6 @@ class Import extends Controller } if ($api_path && $import_posts) { // we are importing from a server and not a file - $m = parse_url($api_path); $hz_server = $m['scheme'] . '://' . $m['host']; @@ -630,7 +631,6 @@ class Import extends Controller } notice(t('Files and Posts imported.') . EOL); - } notifications_on($channel['channel_id'], $saved_notification_flags); @@ -703,5 +703,4 @@ class Import extends Controller '$submit' => t('Submit') ]); } - } diff --git a/Zotlabs/Module/Import_items.php b/Zotlabs/Module/Import_items.php index 87be5cb8f..e489f9fe9 100644 --- a/Zotlabs/Module/Import_items.php +++ b/Zotlabs/Module/Import_items.php @@ -1,4 +1,5 @@ $email . ':' . $password); $url = $scheme . $servername . $api_path; $ret = z_fetch_url($url, $binary, $redirects, $opts); - if (!$ret['success']) + if (!$ret['success']) { $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts); - if ($ret['success']) + } + if ($ret['success']) { $data = $ret['body']; - else + } else { notice(t('Unable to download data from old server') . EOL); + } } if (!$data) { @@ -88,17 +91,18 @@ class Import_items extends Controller //logger('import: data: ' . print_r($data,true)); //print_r($data); - if (!is_array($data)) + if (!is_array($data)) { return; + } -// if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { -// $v1 = substr($data['compatibility']['database'],-4); -// $v2 = substr(DB_UPDATE_VERSION,-4); -// if($v2 > $v1) { -// $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); -// notice($t . EOL); -// } -// } +// if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { +// $v1 = substr($data['compatibility']['database'],-4); +// $v2 = substr(DB_UPDATE_VERSION,-4); +// if($v2 > $v1) { +// $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); +// notice($t . EOL); +// } +// } $codebase = 'zap'; @@ -140,5 +144,4 @@ class Import_items extends Controller return $o; } - } diff --git a/Zotlabs/Module/Inbox.php b/Zotlabs/Module/Inbox.php index 953443ae0..3a5e70782 100644 --- a/Zotlabs/Module/Inbox.php +++ b/Zotlabs/Module/Inbox.php @@ -1,4 +1,5 @@ is_valid() && $AS->type === 'Announce' && is_array($AS->obj) - && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) { + if ( + $AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) + && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj) + ) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); @@ -113,7 +118,6 @@ class Inbox extends Controller // AND the signature is valid AND the signer is the actor. if ($hsig['header_valid'] && $hsig['content_valid'] && $hsig['portable_id']) { - // if the sender has the ability to send messages over zot/nomad, ignore messages sent via activitypub // as observer aware features and client side markup will be unavailable @@ -142,14 +146,12 @@ class Inbox extends Controller // The activity signature isn't valid. return; } - } if ($v) { // The sender has been validated and stored $observer_hash = $hsig['portable_id']; } - } if (!$observer_hash) { @@ -165,7 +167,8 @@ class Inbox extends Controller http_status_exit(403, 'Permission denied'); } // this site obviously isn't dead because they are trying to communicate with us. - $test = q("update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", + $test = q( + "update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", dbesc($m['scheme'] . '://' . $m['host']) ); } @@ -175,7 +178,8 @@ class Inbox extends Controller // update the hubloc_connected timestamp, ignore failures - $test = q("update hubloc set hubloc_connected = '%s' where hubloc_hash = '%s' and hubloc_network = 'activitypub'", + $test = q( + "update hubloc set hubloc_connected = '%s' where hubloc_hash = '%s' and hubloc_network = 'activitypub'", dbesc(datetime_convert()), dbesc($observer_hash) ); @@ -184,15 +188,16 @@ class Inbox extends Controller // Now figure out who the recipients are if ($is_public) { - if (in_array($AS->type, ['Follow', 'Join']) && is_array($AS->obj) && ActivityStreams::is_an_actor($AS->obj['type'])) { - $channels = q("SELECT * from channel where channel_address = '%s' and channel_removed = 0 ", + $channels = q( + "SELECT * from channel where channel_address = '%s' and channel_removed = 0 ", dbesc(basename($AS->obj['id'])) ); } else { // deliver to anybody following $AS->actor - $channels = q("SELECT * from channel where channel_id in ( SELECT abook_channel from abook left join xchan on abook_xchan = xchan_hash WHERE xchan_network = 'activitypub' and xchan_hash = '%s' ) and channel_removed = 0 ", + $channels = q( + "SELECT * from channel where channel_id in ( SELECT abook_channel from abook left join xchan on abook_xchan = xchan_hash WHERE xchan_network = 'activitypub' and xchan_hash = '%s' ) and channel_removed = 0 ", dbesc($observer_hash) ); if (!$channels) { @@ -202,7 +207,8 @@ class Inbox extends Controller $parent = $AS->parent_id; if ($parent) { // this is a comment - deliver to everybody who owns the parent - $owners = q("SELECT * from channel where channel_id in ( SELECT uid from item where mid = '%s' ) ", + $owners = q( + "SELECT * from channel where channel_id in ( SELECT uid from item where mid = '%s' ) ", dbesc($parent) ); if ($owners) { @@ -216,7 +222,6 @@ class Inbox extends Controller } if (in_array(ACTIVITY_PUBLIC_INBOX, $AS->recips) || in_array('Public', $AS->recips) || in_array('as:Public', $AS->recips)) { - // look for channels with send_stream = PERMS_PUBLIC (accept posts from anybody on the internet) $r = q("select * from channel where channel_id in (select uid from pconfig where cat = 'perm_limits' and k = 'send_stream' and v = '1' ) and channel_removed = 0 "); @@ -235,9 +240,7 @@ class Inbox extends Controller if (!$sys_disabled) { $channels[] = get_sys_channel(); } - } - } // $channels represents all "potential" recipients. If they are not in this array, they will not receive the activity. @@ -260,7 +263,6 @@ class Inbox extends Controller foreach ($channels as $channel) { - // Even though activitypub may be enabled for the site, check if the channel has specifically disabled it if (!PConfig::Get($channel['channel_id'], 'system', 'activitypub', Config::Get('system', 'activitypub', ACTIVITYPUB_ENABLED))) { continue; @@ -298,10 +300,8 @@ class Inbox extends Controller break; case 'Reject': - default: break; - } // These activities require permissions @@ -367,15 +367,16 @@ class Inbox extends Controller break; case 'Move': - if ($observer_hash && $observer_hash === $AS->actor + if ( + $observer_hash && $observer_hash === $AS->actor && is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStream::is_an_actor($AS->obj['type']) - && is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type'])) { + && is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type']) + ) { ActivityPub::move($AS->obj, $AS->tgt); } break; case 'Add': case 'Remove': - // for writeable collections as target, it's best to provide an array and include both the type and the id in the target element. // If it's just a string id, we'll try to fetch the collection when we receive it and that's wasteful since we don't actually need // the contents. @@ -386,14 +387,12 @@ class Inbox extends Controller } default: break; - } if ($item) { logger('parsed_item: ' . print_r($item, true), LOGGER_DATA); Activity::store($channel, $observer_hash, $AS, $item); } - } http_status_exit(200, 'OK'); @@ -401,10 +400,5 @@ class Inbox extends Controller public function get() { - } - } - - - diff --git a/Zotlabs/Module/Inspect.php b/Zotlabs/Module/Inspect.php index 6ccb5066b..dfa8d02fa 100644 --- a/Zotlabs/Module/Inspect.php +++ b/Zotlabs/Module/Inspect.php @@ -35,7 +35,8 @@ class Inspect extends Controller } if ($item_type === 'item') { - $r = q("select * from item where uuid = '%s' or id = %d ", + $r = q( + "select * from item where uuid = '%s' or id = %d ", dbesc($item_id), intval($item_id) ); @@ -65,13 +66,12 @@ class Inspect extends Controller $output .= '
' . escape_tags(json_encode(Activity::encode_activity($item, true), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) . '
' . EOL . EOL; $output .= '
' . escape_tags(json_encode(json_decode(get_iconfig($item['id'], 'activitypub', 'rawmsg'), true), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) . '
' . EOL . EOL; - } - } if ($item_type === 'xchan') { - $items = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_hash = '%s' or hubloc_addr = '%s' ", + $items = q( + "select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_hash = '%s' or hubloc_addr = '%s' ", dbesc($item_id), dbesc($item_id) ); @@ -88,6 +88,4 @@ class Inspect extends Controller return $output; } - - } diff --git a/Zotlabs/Module/Invite.php b/Zotlabs/Module/Invite.php index 4a1b0b193..f400e1ebd 100644 --- a/Zotlabs/Module/Invite.php +++ b/Zotlabs/Module/Invite.php @@ -1,4 +1,5 @@ = 0) + if ($x >= 0) { set_pconfig(local_channel(), 'system', 'invites_remaining', $x); - else + } else { return; + } } } $ob = App::get_observer(); - if (!$ob) + if (!$ob) { return $o; + } $channel = App::get_channel(); @@ -165,5 +170,4 @@ class Invite extends Controller return $o; } - } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index eeea9fde5..f4f096bc3 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -8,16 +8,16 @@ namespace Zotlabs\Module; * acts as a permalink for local content. * * Otherwise this is the POST destination for most all locally posted - * text stuff. This function handles status, wall-to-wall status, - * local comments, and remote coments that are posted on this site + * text stuff. This function handles status, wall-to-wall status, + * local comments, and remote coments that are posted on this site * (as opposed to being delivered in a feed). - * Also processed here are posts and comments coming through the API. - * All of these become an "item" which is our basic unit of + * Also processed here are posts and comments coming through the API. + * All of these become an "item" which is our basic unit of * information. - * Posts that originate externally or do not fall into the above - * posting categories go through item_store() instead of this function. + * Posts that originate externally or do not fall into the above + * posting categories go through item_store() instead of this function. * - */ + */ use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Activity; @@ -69,7 +69,8 @@ class Item extends Controller // do we have the item (at all)? // add preferential bias to item owners (item_wall = 1) - $r = q("select * from item where (mid = '%s' or uuid = '%s') $item_normal order by item_wall desc limit 1", + $r = q( + "select * from item where (mid = '%s' or uuid = '%s') $item_normal order by item_wall desc limit 1", dbesc(z_root() . '/item/' . $item_uuid), dbesc($item_uuid) ); @@ -92,7 +93,8 @@ class Item extends Controller } observer_auth($portable_id); - $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", + $i = q( + "select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", dbesc($r[0]['parent_mid']), dbesc($portable_id) ); @@ -106,7 +108,8 @@ class Item extends Controller $sql_extra = item_permissions_sql(0); if (!$i) { - $i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", + $i = q( + "select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", dbesc($r[0]['parent_mid']) ); } @@ -115,11 +118,13 @@ class Item extends Controller if ($bear) { logger('bear: ' . $bear, LOGGER_DEBUG); if (!$i) { - $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", + $t = q( + "select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", dbesc($bear) ); if ($t) { - $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", + $i = q( + "select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", dbesc($item_uuid), intval($t[0]['iid']) ); @@ -154,7 +159,8 @@ class Item extends Controller if ($portable_id && (!intval($items[0]['item_private']))) { - $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + $c = q( + "select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", intval($items[0]['uid']), dbesc($portable_id) ); @@ -167,7 +173,6 @@ class Item extends Controller } if (Libzot::is_zot_request()) { - $item_uuid = argv(1); if (!$item_uuid) { @@ -182,7 +187,8 @@ class Item extends Controller // do we have the item (at all)? - $r = q("select * from item where (mid = '%s' or uuid = '%s') $item_normal limit 1", + $r = q( + "select * from item where (mid = '%s' or uuid = '%s') $item_normal limit 1", dbesc(z_root() . '/item/' . $item_uuid), dbesc($item_uuid) ); @@ -204,7 +210,8 @@ class Item extends Controller } observer_auth($portable_id); - $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", + $i = q( + "select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", dbesc($r[0]['parent_mid']), dbesc($portable_id) ); @@ -218,7 +225,8 @@ class Item extends Controller $sql_extra = item_permissions_sql(0); if (!$i) { - $i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", + $i = q( + "select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", dbesc($r[0]['parent_mid']) ); } @@ -227,11 +235,13 @@ class Item extends Controller if ($bear) { logger('bear: ' . $bear, LOGGER_DEBUG); if (!$i) { - $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", + $t = q( + "select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", dbesc($bear) ); if ($t) { - $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", + $i = q( + "select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", dbesc($item_uuid), intval($t[0]['iid']) ); @@ -245,7 +255,8 @@ class Item extends Controller $parents_str = ids_to_querystr($i, 'item_id'); - $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal order by item.id asc", + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal order by item.id asc", dbesc($parents_str) ); @@ -293,7 +304,6 @@ class Item extends Controller HTTPSig::set_headers($h); echo $ret; killme(); - } // if it isn't a drop command and isn't a post method and wasn't handled already, @@ -301,7 +311,8 @@ class Item extends Controller // the text/html page of the item. if (argc() > 1 && argv(1) !== 'drop') { - $x = q("select uid, item_wall, llink, mid from item where mid = '%s' or mid = '%s' or uuid = '%s'", + $x = q( + "select uid, item_wall, llink, mid from item where mid = '%s' or mid = '%s' or uuid = '%s'", dbesc(z_root() . '/item/' . argv(1)), dbesc(z_root() . '/activity/' . argv(1)), dbesc(argv(1)) @@ -478,10 +489,12 @@ class Item extends Controller $ret = $this->item_check_service_class($uid, (($_REQUEST['webpage'] == ITEM_TYPE_WEBPAGE) ? true : false)); if (!$ret['success']) { notice(t($ret['message']) . EOL); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'service class exception']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } } @@ -504,7 +517,6 @@ class Item extends Controller // If this is a comment, find the parent and preset some stuff if ($parent || $parent_mid) { - if (!x($_REQUEST, 'type')) { $_REQUEST['type'] = 'net-comment'; } @@ -515,12 +527,14 @@ class Item extends Controller // fetch the parent item if ($parent) { - $r = q("SELECT * FROM item WHERE id = %d LIMIT 1", + $r = q( + "SELECT * FROM item WHERE id = %d LIMIT 1", intval($parent) ); } elseif ($parent_mid && $uid) { // This is coming from an API source, and we are logged in - $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($parent_mid), intval($uid) ); @@ -531,7 +545,8 @@ class Item extends Controller $parid = $r[0]['parent']; $parent_mid = $r[0]['mid']; if ($r[0]['id'] != $r[0]['parent']) { - $r = q("SELECT * FROM item WHERE id = parent AND parent = %d LIMIT 1", + $r = q( + "SELECT * FROM item WHERE id = parent AND parent = %d LIMIT 1", intval($parid) ); } @@ -572,7 +587,6 @@ class Item extends Controller $thr_parent = $parent_mid; $route = $parent_item['route']; - } if ($parent_item && isset($parent_item['replyto']) && $parent_item['replyto']) { @@ -617,20 +631,24 @@ class Item extends Controller if (!$can_comment) { notice(t('Permission denied.') . EOL); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'permission denied']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } } else { // fixme - $webpage could also be a wiki page or article and require a different permission to be checked. if (!perm_is_allowed($profile_uid, $observer['xchan_hash'], ($webpage) ? 'write_pages' : 'post_wall')) { notice(t('Permission denied.') . EOL); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'permission denied']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } } @@ -653,25 +671,30 @@ class Item extends Controller if ($namespace && $remote_id) { // It wasn't an internally generated post - see if we've got an item matching this remote service id - $i = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1", + $i = q( + "select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1", dbesc($namespace), dbesc($remote_id) ); - if ($i) + if ($i) { $post_id = $i[0]['iid']; + } } $iconfig = null; if ($post_id) { - $i = q("SELECT * FROM item WHERE uid = %d AND id = %d LIMIT 1", + $i = q( + "SELECT * FROM item WHERE uid = %d AND id = %d LIMIT 1", intval($profile_uid), intval($post_id) ); - if (!count($i)) + if (!count($i)) { killme(); + } $orig_post = $i[0]; - $iconfig = q("select * from iconfig where iid = %d", + $iconfig = q( + "select * from iconfig where iid = %d", intval($post_id) ); } @@ -682,45 +705,53 @@ class Item extends Controller $channel = App::get_channel(); } else { // posting as yourself but not necessarily to a channel you control - $r = q("select * from channel left join account on channel_account_id = account_id where channel_id = %d LIMIT 1", + $r = q( + "select * from channel left join account on channel_account_id = account_id where channel_id = %d LIMIT 1", intval($profile_uid) ); - if ($r) + if ($r) { $channel = $r[0]; + } } } if (!$channel) { logger("mod_item: no channel."); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'no channel']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } $owner_xchan = null; - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($channel['channel_hash']) ); if ($r && count($r)) { $owner_xchan = $r[0]; } else { logger("mod_item: no owner."); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'no owner']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } $walltowall = false; $walltowall_comment = false; - if ($remote_xchan && !$moderated) + if ($remote_xchan && !$moderated) { $observer = $remote_observer; + } if ($observer) { logger('mod_item: post accepted from ' . $observer['xchan_name'] . ' for ' . $owner_xchan['xchan_name'], LOGGER_DEBUG); @@ -755,13 +786,14 @@ class Item extends Controller $comment_policy = ((isset($_REQUEST['comments_from']) && intval($_REQUEST['comments_from'])) ? intval($_REQUEST['comments_from']) : PermissionLimits::Get($channel['channel_id'], 'post_comments')); $public_policy = ((x($_REQUEST, 'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($view_policy, true)); - if ($webpage) + if ($webpage) { $public_policy = ''; - if ($public_policy) + } + if ($public_policy) { $private = 1; + } if ($orig_post) { - $private = 0; // webpages and unpublished drafts are allowed to change ACLs after the fact. Normal conversation items aren't. if ($webpage || intval($orig_post['item_unpublished'])) { @@ -814,16 +846,16 @@ class Item extends Controller $mid = $orig_post['mid']; $parent_mid = $orig_post['parent_mid']; $plink = $orig_post['plink']; - } else { if (!$walltowall) { - if ((array_key_exists('contact_allow', $_REQUEST)) + if ( + (array_key_exists('contact_allow', $_REQUEST)) || (array_key_exists('group_allow', $_REQUEST)) || (array_key_exists('contact_deny', $_REQUEST)) - || (array_key_exists('group_deny', $_REQUEST))) { + || (array_key_exists('group_deny', $_REQUEST)) + ) { $acl->set_from_array($_REQUEST); } elseif (!$api_source) { - // if no ACL has been defined and we aren't using the API, the form // didn't send us any parameters. This means there's no ACL or it has // been reset to the default audience. @@ -863,13 +895,16 @@ class Item extends Controller } if ((!$allow_empty) && (!strlen($body))) { - if ($preview) + if ($preview) { killme(); + } info(t('Empty post discarded.') . EOL); - if ($api_source) + if ($api_source) { return (['success' => false, 'message' => 'no content']); - if (x($_REQUEST, 'return')) + } + if (x($_REQUEST, 'return')) { goaway(z_root() . "/" . $return_path); + } killme(); } } @@ -878,15 +913,17 @@ class Item extends Controller if (Apps::system_app_installed($profile_uid, 'Expire Posts')) { if (x($_REQUEST, 'expire')) { $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['expire']); - if ($expires <= datetime_convert()) + if ($expires <= datetime_convert()) { $expires = NULL_DATE; + } } } $mimetype = notags(trim($_REQUEST['mimetype'])); - if (!$mimetype) + if (!$mimetype) { $mimetype = 'text/bbcode'; + } $execflag = ((intval($uid) == intval($profile_uid) @@ -968,7 +1005,6 @@ class Item extends Controller if ($mimetype === 'text/bbcode') { - // BBCODE alert: the following functions assume bbcode input // and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.) // we may need virtual or template classes to implement the possible alternatives @@ -992,9 +1028,7 @@ class Item extends Controller $comment_tags = linkify_tags($hidden_mentions, ($uid) ? $uid : $profile_uid); foreach ([$summary_tags, $body_tags, $comment_tags] as $results) { - if ($results) { - // Set permissions based on tag replacements set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $parent_item, $private); @@ -1004,7 +1038,6 @@ class Item extends Controller foreach ($results as $result) { $success = $result['success']; if ($success['replaced']) { - // suppress duplicate mentions/tags $already_tagged = false; foreach ($post_tags as $pt) { @@ -1030,7 +1063,8 @@ class Item extends Controller // this is checked inside tag_deliver() to create a second delivery chain if ($success['termtype'] === TERM_HASHTAG) { - $r = q("select xchan_url from channel left join xchan on xchan_hash = channel_hash where channel_address = '%s' and channel_parent = '%s' and channel_removed = 0", + $r = q( + "select xchan_url from channel left join xchan on xchan_hash = channel_hash where channel_address = '%s' and channel_parent = '%s' and channel_removed = 0", dbesc($success['term']), dbesc(get_observer_hash()) ); @@ -1056,7 +1090,8 @@ class Item extends Controller if (array_key_exists('collections', $_REQUEST) && is_array($_REQUEST['collections']) && count($_REQUEST['collections'])) { foreach ($_REQUEST['collections'] as $clct) { - $r = q("select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", + $r = q( + "select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1", dbesc($clct) ); if ($r) { @@ -1080,7 +1115,6 @@ class Item extends Controller } if ($private) { - // for edited posts, re-use any existing OCAP token (if found). // Otherwise generate a new one. @@ -1157,7 +1191,6 @@ class Item extends Controller $i++; } } - } // BBCODE end alert @@ -1169,7 +1202,6 @@ class Item extends Controller $cats = explode(',', $categories); foreach ($cats as $cat) { - if ($webpage == ITEM_TYPE_CARD) { $catlink = z_root() . '/cards/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat)); } elseif ($webpage == ITEM_TYPE_ARTICLE) { @@ -1190,7 +1222,8 @@ class Item extends Controller if ($orig_post) { // preserve original tags - $t = q("select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )", + $t = q( + "select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )", intval($orig_post['id']), intval(TERM_OBJ_POST), intval($profile_uid), @@ -1233,12 +1266,14 @@ class Item extends Controller } - if ($moderated) + if ($moderated) { $item_blocked = ITEM_MODERATED; + } - if (!strlen($verb)) + if (!strlen($verb)) { $verb = ACTIVITY_POST; + } $notify_type = (($parent) ? 'comment-new' : 'wall-new'); @@ -1283,14 +1318,16 @@ class Item extends Controller $parent_mid = $mid; } - if ($parent_item) + if ($parent_item) { $parent_mid = $parent_item['mid']; + } // Fallback so that we alway have a thr_parent - if (!$thr_parent) + if (!$thr_parent) { $thr_parent = $mid; + } $item_thread_top = ((!$parent) ? 1 : 0); @@ -1302,7 +1339,8 @@ class Item extends Controller $plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid); } if (($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_CARD)) { - $r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.iid = %d limit 1", + $r = q( + "select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.iid = %d limit 1", intval($parent_item['id']) ); if ($r) { @@ -1314,7 +1352,8 @@ class Item extends Controller $plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid); } if (($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_ARTICLE)) { - $r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1", + $r = q( + "select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1", intval($parent_item['id']) ); if ($r) { @@ -1395,8 +1434,9 @@ class Item extends Controller // A specific ACL over-rides public_policy completely - if (!empty_acl($datarray)) + if (!empty_acl($datarray)) { $datarray['public_policy'] = ''; + } if ($iconfig) { $datarray['iconfig'] = $iconfig; @@ -1431,7 +1471,7 @@ class Item extends Controller $datarray['author'] = $observer; $datarray['attach'] = json_encode($datarray['attach']); $o = conversation(array($datarray), 'search', false, 'preview'); - // logger('preview: ' . $o, LOGGER_DEBUG); + // logger('preview: ' . $o, LOGGER_DEBUG); echo json_encode(array('preview' => $o)); killme(); } @@ -1448,8 +1488,8 @@ class Item extends Controller // some attribute besides the content, such as title or categories. if (PConfig::Get($profile_uid, 'system', 'suppress_duplicates', true) && (!$orig_post)) { - - $z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1", + $z = q( + "select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1", intval($profile_uid), db_utcnow(), db_quoteinterval('2 MINUTE'), @@ -1482,15 +1522,26 @@ class Item extends Controller } - if (mb_strlen($datarray['title']) > 191) + if (mb_strlen($datarray['title']) > 191) { $datarray['title'] = mb_substr($datarray['title'], 0, 191); + } if ($webpage) { - IConfig::Set($datarray, 'system', webpage_to_namespace($webpage), - (($pagetitle) ? $pagetitle : basename($datarray['mid'])), true); + IConfig::Set( + $datarray, + 'system', + webpage_to_namespace($webpage), + (($pagetitle) ? $pagetitle : basename($datarray['mid'])), + true + ); } elseif ($namespace) { - IConfig::Set($datarray, 'system', $namespace, - (($remote_id) ? $remote_id : basename($datarray['mid'])), true); + IConfig::Set( + $datarray, + 'system', + $namespace, + (($remote_id) ? $remote_id : basename($datarray['mid'])), + true + ); } if (intval($datarray['item_unpublished'])) { @@ -1502,7 +1553,8 @@ class Item extends Controller $x = item_store_update($datarray, $execflag); if (!$parent) { - $r = q("select * from item where id = %d", + $r = q( + "select * from item where id = %d", intval($post_id) ); if ($r) { @@ -1530,8 +1582,9 @@ class Item extends Controller goaway(z_root() . "/" . $return_path); } killme(); - } else + } else { $post_id = 0; + } $post = item_store($datarray, $execflag); @@ -1547,11 +1600,11 @@ class Item extends Controller logger('mod_item: saved item ' . $post_id); if ($parent) { - // prevent conversations which you are involved from being expired - if (local_channel()) + if (local_channel()) { retain_item($parent); + } // only send comment notification if this is a wall-to-wall comment and not a DM, // otherwise it will happen during delivery @@ -1568,7 +1621,6 @@ class Item extends Controller 'parent' => $parent, 'parent_mid' => $parent_item['mid'] )); - } } else { $parent = $post_id; @@ -1586,7 +1638,8 @@ class Item extends Controller } if ($uid && $uid == $profile_uid && (is_item_normal($datarray))) { - q("update channel set channel_lastpost = '%s' where channel_id = %d", + q( + "update channel set channel_lastpost = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($uid) ); @@ -1598,17 +1651,20 @@ class Item extends Controller // They will show up as people comment on them. if (intval($parent_item['item_hidden'])) { - $r = q("UPDATE item SET item_hidden = 0 WHERE id = %d", + $r = q( + "UPDATE item SET item_hidden = 0 WHERE id = %d", intval($parent_item['id']) ); } } else { logger('mod_item: unable to retrieve post that was just stored.'); notice(t('System error. Post not saved.') . EOL); - if ($return_path) + if ($return_path) { goaway(z_root() . "/" . $return_path); - if ($api_source) + } + if ($api_source) { return (['success' => false, 'message' => 'system error']); + } killme(); } @@ -1618,7 +1674,8 @@ class Item extends Controller //$ditem['author'] = $observer; //store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); } else { - $r = q("select * from item where id = %d", + $r = q( + "select * from item where id = %d", intval($post_id) ); if ($r) { @@ -1648,8 +1705,9 @@ class Item extends Controller // figure out how to return, depending on from whence we came - if ($api_source) + if ($api_source) { return $post; + } if (intval($datarray['item_unpublished'])) { info($draft_msg); @@ -1660,8 +1718,9 @@ class Item extends Controller } $json = array('success' => 1); - if (x($_REQUEST, 'jsreload') && strlen($_REQUEST['jsreload'])) + if (x($_REQUEST, 'jsreload') && strlen($_REQUEST['jsreload'])) { $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; + } logger('post_json: ' . print_r($json, true), LOGGER_DEBUG); @@ -1680,8 +1739,9 @@ class Item extends Controller return; } - if ((!local_channel()) && (!remote_channel())) + if ((!local_channel()) && (!remote_channel())) { return; + } // allow pinned items to be dropped. 'pin-' was prepended to the id of these // items so that they would have a unique html id even if the pinned item @@ -1690,8 +1750,8 @@ class Item extends Controller $drop_id = str_replace('pin-', '', argv(2)); if ((argc() == 3) && (argv(1) === 'drop') && intval($drop_id)) { - - $i = q("select * from item where id = %d limit 1", + $i = q( + "select * from item where id = %d limit 1", intval($drop_id) ); @@ -1716,8 +1776,9 @@ class Item extends Controller if (is_site_admin()) { $local_delete = true; - if (intval($i[0]['item_origin'])) + if (intval($i[0]['item_origin'])) { $can_delete = true; + } } @@ -1728,13 +1789,15 @@ class Item extends Controller if ($i[0]['resource_type'] === 'event') { // delete and sync the event separately - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($i[0]['resource_id']), intval($i[0]['uid']) ); if ($r && $regular_delete) { $sync_event = $r[0]; - q("delete from event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + q( + "delete from event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($i[0]['resource_id']), intval($i[0]['uid']) ); @@ -1768,7 +1831,8 @@ class Item extends Controller $complex = true; } - $r = q("select * from item where id = %d", + $r = q( + "select * from item where id = %d", intval($i[0]['id']) ); if ($r) { @@ -1790,14 +1854,16 @@ class Item extends Controller $ret = array('success' => false, 'message' => ''); if ($iswebpage) { - $r = q("select count(i.id) as total from item i + $r = q( + "select count(i.id) as total from item i right join channel c on (i.author_xchan=c.channel_hash and i.uid=c.channel_id ) and i.parent=i.id and i.item_type = %d and i.item_deleted = 0 and i.uid= %d ", intval(ITEM_TYPE_WEBPAGE), intval($channel_id) ); } else { - $r = q("select count(id) as total from item where parent = id and item_wall = 1 and uid = %d " . item_normal(), + $r = q( + "select count(id) as total from item where parent = id and item_wall = 1 and uid = %d " . item_normal(), intval($channel_id) ); } @@ -1880,7 +1946,6 @@ class Item extends Controller } return $obj; - } public function extract_poll_data($poll, $item) @@ -1898,8 +1963,9 @@ class Item extends Controller $obj['content'] = bbcode($question); foreach ($answers as $answer) { - if (trim($answer)) + if (trim($answer)) { $ptr[] = ['name' => escape_tags($answer), 'type' => 'Note', 'replies' => ['type' => 'Collection', 'totalItems' => 0]]; + } } if ($multiple) { @@ -1917,7 +1983,5 @@ class Item extends Controller } return $obj; - } - } diff --git a/Zotlabs/Module/Jwks.php b/Zotlabs/Module/Jwks.php index 8bb6de47b..3e0dd544f 100644 --- a/Zotlabs/Module/Jwks.php +++ b/Zotlabs/Module/Jwks.php @@ -58,6 +58,5 @@ class Jwks extends Controller } json_return_and_die($ret, 'application/jwk-set+json'); - } -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Lang.php b/Zotlabs/Module/Lang.php index 46034a5ff..53f7081af 100644 --- a/Zotlabs/Module/Lang.php +++ b/Zotlabs/Module/Lang.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } public function get() @@ -64,7 +63,8 @@ class Layouts extends Controller if (!$owner) { // Figure out who the page owner is. - $r = q("select channel_id from channel where channel_address = '%s'", + $r = q( + "select channel_id from channel where channel_address = '%s'", dbesc($which) ); if ($r) { @@ -104,7 +104,8 @@ class Layouts extends Controller // Use the buildin share/install feature instead. if ((argc() > 3) && (argv(2) === 'share') && (argv(3))) { - $r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig + $r = q( + "select iconfig.v, iconfig.k, mimetype, title, body from iconfig left join item on item.id = iconfig.iid where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc", intval($owner), @@ -143,16 +144,20 @@ class Layouts extends Controller 'bbco_autocomplete' => 'comanche' ); - if ($_REQUEST['title']) + if ($_REQUEST['title']) { $x['title'] = $_REQUEST['title']; - if ($_REQUEST['body']) + } + if ($_REQUEST['body']) { $x['body'] = $_REQUEST['body']; - if ($_REQUEST['pagetitle']) + } + if ($_REQUEST['pagetitle']) { $x['pagetitle'] = $_REQUEST['pagetitle']; + } $editor = status_editor($x); - $r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig + $r = q( + "select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig left join item on iconfig.iid = item.id where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc", intval($owner), @@ -208,7 +213,5 @@ class Layouts extends Controller )); return $o; - } - } diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 5954040b3..df0758568 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -1,4 +1,5 @@ 1 && $test[0] === 'Undo') { - $undo = true; - $activity = $test[1]; - } + $activity = ((array_key_exists('verb', $_GET)) ? notags(trim($_GET['verb'])) : EMPTY_STR); - if (! in_array($activity, [ 'Like', 'Dislike', 'Accept', 'Reject', 'TentativeAccept' ])) { - killme(); - } + if (! $activity) { + return EMPTY_STR; + } - $is_rsvp = in_array($activity, [ 'Accept', 'Reject', 'TentativeAccept' ]); + // Check for negative (undo) condition + // eg: 'Undo/Like' results in $undo conditional and $activity set to 'Like' - // Check for when target is something besides messages, where argv(1) is the type of thing - // and argv(2) is an identifier of things of that type - // We currently only recognise 'profile' but other types could be handled - - - if (! $observer) { - killme(); - } + $test = explode('/', $activity); + if (count($test) > 1 && $test[0] === 'Undo') { + $undo = true; + $activity = $test[1]; + } - // this is used to like an item or comment - - $item_id = ((argc() == 2) ? notags(trim(argv(1))) : 0); + if (! in_array($activity, [ 'Like', 'Dislike', 'Accept', 'Reject', 'TentativeAccept' ])) { + killme(); + } - logger('like: undo: ' . (($undo) ? 'true' : 'false')); - logger('like: verb ' . $activity . ' item ' . $item_id, LOGGER_DEBUG); - - // get the item. Allow linked photos (which are normally hidden) to be liked + $is_rsvp = in_array($activity, [ 'Accept', 'Reject', 'TentativeAccept' ]); - $r = q("SELECT * FROM item WHERE id = %d + // Check for when target is something besides messages, where argv(1) is the type of thing + // and argv(2) is an identifier of things of that type + // We currently only recognise 'profile' but other types could be handled + + + if (! $observer) { + killme(); + } + + // this is used to like an item or comment + + $item_id = ((argc() == 2) ? notags(trim(argv(1))) : 0); + + logger('like: undo: ' . (($undo) ? 'true' : 'false')); + logger('like: verb ' . $activity . ' item ' . $item_id, LOGGER_DEBUG); + + // get the item. Allow linked photos (which are normally hidden) to be liked + + $r = q( + "SELECT * FROM item WHERE id = %d and item_type in (0,6,7) and item_deleted = 0 and item_unpublished = 0 and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1", - intval($item_id) - ); + intval($item_id) + ); - // if interacting with a pubstream item, - // create a copy of the parent in your stream. + // if interacting with a pubstream item, + // create a copy of the parent in your stream. - if ($r) { - if (local_channel() && (! is_sys_channel(local_channel()))) { - $r = [ copy_of_pubitem(App::get_channel(), $r[0]['mid']) ]; - } - } + if ($r) { + if (local_channel() && (! is_sys_channel(local_channel()))) { + $r = [ copy_of_pubitem(App::get_channel(), $r[0]['mid']) ]; + } + } - if(! $item_id || (! $r)) { - logger('like: no item ' . $item_id); - killme(); - } + if (! $item_id || (! $r)) { + logger('like: no item ' . $item_id); + killme(); + } - xchan_query($r,true); + xchan_query($r, true); - $item = array_shift($r); + $item = array_shift($r); - $owner_uid = $item['uid']; - $owner_aid = $item['aid']; + $owner_uid = $item['uid']; + $owner_aid = $item['aid']; $can_comment = false; - if ((array_key_exists('owner',$item)) && intval($item['owner']['abook_self'])) { - $can_comment = perm_is_allowed($item['uid'],$observer['xchan_hash'],'post_comments'); - } - else { - $can_comment = can_comment_on_post($observer['xchan_hash'],$item); - } + if ((array_key_exists('owner', $item)) && intval($item['owner']['abook_self'])) { + $can_comment = perm_is_allowed($item['uid'], $observer['xchan_hash'], 'post_comments'); + } else { + $can_comment = can_comment_on_post($observer['xchan_hash'], $item); + } - if (! $can_comment) { - notice( t('Permission denied') . EOL); - killme(); - } + if (! $can_comment) { + notice(t('Permission denied') . EOL); + killme(); + } - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($item['owner_xchan']) - ); + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['owner_xchan']) + ); - if ($r) { - $thread_owner = array_shift($r); - } - else { - killme(); - } - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($item['author_xchan']) - ); - if ($r) { - $item_author = array_shift($r); - } - else { - killme(); - } + if ($r) { + $thread_owner = array_shift($r); + } else { + killme(); + } + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['author_xchan']) + ); + if ($r) { + $item_author = array_shift($r); + } else { + killme(); + } - if ($undo) { - $r = q("select * from item where thr_parent = '%s' and verb = '%s' and author_xchan = '%s' and uid = %d and item_deleted = 0 limit 1", - dbesc($item['thr_parent']), - dbesc($activity), - dbesc($observer['xchan_hash']), - intval($owner_uid) - ); + if ($undo) { + $r = q( + "select * from item where thr_parent = '%s' and verb = '%s' and author_xchan = '%s' and uid = %d and item_deleted = 0 limit 1", + dbesc($item['thr_parent']), + dbesc($activity), + dbesc($observer['xchan_hash']), + intval($owner_uid) + ); - xchan_query($r,true); - $r = fetch_post_tags($r,true); - $r[0]['obj'] = json_decode($r[0]['obj'],true); - $object = Activity::encode_activity($r[0],true); - - // do not do either a federated or hard delete on the original reaction - // as we are going to send an Undo to perform this task - // just set item_deleted to update the local conversation + xchan_query($r, true); + $r = fetch_post_tags($r, true); + $r[0]['obj'] = json_decode($r[0]['obj'], true); + $object = Activity::encode_activity($r[0], true); - $retval = q("update item set item_deleted = 1 where id = %d", - intval($r[0]['id']) - ); + // do not do either a federated or hard delete on the original reaction + // as we are going to send an Undo to perform this task + // just set item_deleted to update the local conversation - } - else { - $object = Activity::fetch_item( [ 'id' => $item['mid'] ]); - } + $retval = q( + "update item set item_deleted = 1 where id = %d", + intval($r[0]['id']) + ); + } else { + $object = Activity::fetch_item([ 'id' => $item['mid'] ]); + } - if (! $object) { - killme(); - } + if (! $object) { + killme(); + } - $uuid = new_uuid(); + $uuid = new_uuid(); - // we have everything we need - start building our new item + // we have everything we need - start building our new item - $arr = []; + $arr = []; - $arr['uuid'] = $uuid; + $arr['uuid'] = $uuid; $arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/' ) . $uuid; - $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); - if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) { - $post_type = t('event'); - } - - $objtype = $item['obj_type']; + $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); + if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) { + $post_type = t('event'); + } - $body = $item['body']; - - - if (! intval($item['item_thread_top'])) { - $post_type = 'comment'; - } - - $arr['item_origin'] = 1; - $arr['item_notshown'] = 1; - $arr['item_type'] = $item['item_type']; - - if (intval($item['item_wall'])) { - $arr['item_wall'] = 1; - } - - // if this was a linked photo and was hidden, unhide it and distribute it. - - if (intval($item['item_hidden'])) { - $r = q("update item set item_hidden = 0 where id = %d", - intval($item['id']) - ); + $objtype = $item['obj_type']; - $r = q("select * from item where id = %d", - intval($item['id']) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); - } - - Run::Summon( [ 'Notifier','wall-new',$item['id'] ] ); - } + $body = $item['body']; - if ($undo) { - $arr['body'] = t('Undo a previous action'); - $arr['item_notshown'] = 1; - } - else { - if ($activity === 'Like') { - $bodyverb = t('%1$s likes %2$s\'s %3$s'); - } - if ($activity === 'Dislike') { - $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - } - if ($activity === 'Accept') { - $bodyverb = t('%1$s is attending %2$s\'s %3$s'); - } - if ($activity === 'Reject') { - $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); - } - if ($activity === 'TentativeAccept') { - $bodyverb = t('%1$s may attend %2$s\'s %3$s'); - } - - if (! isset($bodyverb)) { - killme(); - } + if (! intval($item['item_thread_top'])) { + $post_type = 'comment'; + } - $ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]'; - $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; - $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]'; + $arr['item_origin'] = 1; + $arr['item_notshown'] = 1; + $arr['item_type'] = $item['item_type']; - $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); + if (intval($item['item_wall'])) { + $arr['item_wall'] = 1; + } - } + // if this was a linked photo and was hidden, unhide it and distribute it. + + if (intval($item['item_hidden'])) { + $r = q( + "update item set item_hidden = 0 where id = %d", + intval($item['id']) + ); + + $r = q( + "select * from item where id = %d", + intval($item['id']) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); + } + + Run::Summon([ 'Notifier','wall-new',$item['id'] ]); + } - if (local_channel() && $activity === 'Accept') { - event_addtocal($item['id'],$channel['channel_id']); - } - - $arr['parent'] = $item['id']; - $arr['thr_parent'] = $item['mid']; - $allow_cid = $item['allow_cid']; - $allow_gid = $item['allow_gid']; - $deny_cid = $item['deny_cid']; - $deny_gid = $item['deny_gid']; - $private = $item['private']; - - $arr['aid'] = $owner_aid; - $arr['uid'] = $owner_uid; + if ($undo) { + $arr['body'] = t('Undo a previous action'); + $arr['item_notshown'] = 1; + } else { + if ($activity === 'Like') { + $bodyverb = t('%1$s likes %2$s\'s %3$s'); + } + if ($activity === 'Dislike') { + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); + } + if ($activity === 'Accept') { + $bodyverb = t('%1$s is attending %2$s\'s %3$s'); + } + if ($activity === 'Reject') { + $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); + } + if ($activity === 'TentativeAccept') { + $bodyverb = t('%1$s may attend %2$s\'s %3$s'); + } - $arr['item_flags'] = $item['item_flags']; - $arr['item_wall'] = $item['item_wall']; - $arr['parent_mid'] = $item['mid']; - $arr['owner_xchan'] = $thread_owner['xchan_hash']; - $arr['author_xchan'] = $observer['xchan_hash']; - - - - $arr['verb'] = (($undo) ? 'Undo' : $activity); - $arr['obj_type'] = (($undo) ? $activity : $objtype); - $arr['obj'] = $object; - - if ($target) { - $arr['tgt_type'] = $tgttype; - $arr['target'] = $target; - } - - $arr['allow_cid'] = $allow_cid; - $arr['allow_gid'] = $allow_gid; - $arr['deny_cid'] = $deny_cid; - $arr['deny_gid'] = $deny_gid; - $arr['item_private'] = $private; - - call_hooks('post_local',$arr); - - $post = item_store($arr); - $post_id = $post['item_id']; + if (! isset($bodyverb)) { + killme(); + } - // save the conversation from expiration + $ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]'; - if (local_channel() && array_key_exists('item',$post) && (intval($post['item']['id']) != intval($post['item']['parent']))) { - retain_item($post['item']['parent']); - } - - $arr['id'] = $post_id; - - call_hooks('post_local_end', $arr); - - $r = q("select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); - } + $arr['body'] = sprintf($bodyverb, $alink, $ulink, $plink); + } - Run::Summon( [ 'Notifier', 'like', $post_id ] ); - - killme(); - } - - - + + if (local_channel() && $activity === 'Accept') { + event_addtocal($item['id'], $channel['channel_id']); + } + + $arr['parent'] = $item['id']; + $arr['thr_parent'] = $item['mid']; + $allow_cid = $item['allow_cid']; + $allow_gid = $item['allow_gid']; + $deny_cid = $item['deny_cid']; + $deny_gid = $item['deny_gid']; + $private = $item['private']; + + $arr['aid'] = $owner_aid; + $arr['uid'] = $owner_uid; + + $arr['item_flags'] = $item['item_flags']; + $arr['item_wall'] = $item['item_wall']; + $arr['parent_mid'] = $item['mid']; + $arr['owner_xchan'] = $thread_owner['xchan_hash']; + $arr['author_xchan'] = $observer['xchan_hash']; + + + + $arr['verb'] = (($undo) ? 'Undo' : $activity); + $arr['obj_type'] = (($undo) ? $activity : $objtype); + $arr['obj'] = $object; + + if ($target) { + $arr['tgt_type'] = $tgttype; + $arr['target'] = $target; + } + + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; + + call_hooks('post_local', $arr); + + $post = item_store($arr); + $post_id = $post['item_id']; + + // save the conversation from expiration + + if (local_channel() && array_key_exists('item', $post) && (intval($post['item']['id']) != intval($post['item']['parent']))) { + retain_item($post['item']['parent']); + } + + $arr['id'] = $post_id; + + call_hooks('post_local_end', $arr); + + $r = q( + "select * from item where id = %d", + intval($post_id) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); + } + + Run::Summon([ 'Notifier', 'like', $post_id ]); + + killme(); + } } diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php index 1eb537089..9df5300f0 100644 --- a/Zotlabs/Module/Linkinfo.php +++ b/Zotlabs/Module/Linkinfo.php @@ -1,4 +1,5 @@ is_valid() && $y->type === 'Announce' && is_array($y->obj) - && array_key_exists('object', $y->obj) && array_key_exists('actor', $y->obj)) { + if ( + $y->is_valid() && $y->type === 'Announce' && is_array($y->obj) + && array_key_exists('object', $y->obj) && array_key_exists('actor', $y->obj) + ) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); @@ -223,7 +235,8 @@ class Linkinfo extends Controller if ($y && $y->is_valid()) { $z = Activity::decode_note($y); - $r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_hash = '%s' OR hubloc_id_url = '%s'", + $r = q( + "select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_hash = '%s' OR hubloc_id_url = '%s'", dbesc(is_array($y->actor) ? $y->actor['id'] : $y->actor), dbesc(is_array($y->actor) ? $y->actor['id'] : $y->actor) ); @@ -236,7 +249,6 @@ class Linkinfo extends Controller } if ($z) { - // do not allow somebody to embed a post that was blocked by the site admin // We *will* let them over-rule any blocks they created themselves @@ -252,7 +264,6 @@ class Linkinfo extends Controller if ($url && $title && $text) { - $text = $br . '[quote]' . trim($text) . '[/quote]' . $br; $title = str_replace(array("\r", "\n"), array('', ''), $title); @@ -269,8 +280,9 @@ class Linkinfo extends Controller // If the site uses this platform, use zrl rather than url so they get zids sent to them by default - if (is_matrix_url($url)) + if (is_matrix_url($url)) { $template = str_replace('url', 'zrl', $template); + } if ($siteinfo["title"] == "") { echo sprintf($template, $url, $url, '') . $str_tags; @@ -287,10 +299,11 @@ class Linkinfo extends Controller $total_images = 0; $max_images = get_config('system', 'max_bookmark_images'); - if ($max_images === false) + if ($max_images === false) { $max_images = 2; - else + } else { $max_images = intval($max_images); + } foreach ($siteinfo["images"] as $imagedata) { if ($url) { @@ -302,8 +315,9 @@ class Linkinfo extends Controller } $image .= "\n"; $total_images++; - if ($max_images && $max_images >= $total_images) + if ($max_images && $max_images >= $total_images) { break; + } } } @@ -322,7 +336,6 @@ class Linkinfo extends Controller echo trim($result); killme(); - } @@ -330,34 +343,40 @@ class Linkinfo extends Controller { $xpath = new DomXPath($doc); $list = $xpath->query("//" . $node); - foreach ($list as $child) + foreach ($list as $child) { $child->parentNode->removeChild($child); + } } public static function completeurl($url, $scheme) { $urlarr = parse_url($url); - if (isset($urlarr["scheme"])) + if (isset($urlarr["scheme"])) { return ($url); + } $schemearr = parse_url($scheme); $complete = $schemearr["scheme"] . "://" . $schemearr["host"]; - if ($schemearr["port"] != "") + if ($schemearr["port"] != "") { $complete .= ":" . $schemearr["port"]; + } - if (strpos($urlarr['path'], '/') !== 0) + if (strpos($urlarr['path'], '/') !== 0) { $complete .= '/'; + } $complete .= $urlarr["path"]; - if ($urlarr["query"] != "") + if ($urlarr["query"] != "") { $complete .= "?" . $urlarr["query"]; + } - if ($urlarr["fragment"] != "") + if ($urlarr["fragment"] != "") { $complete .= "#" . $urlarr["fragment"]; + } return ($complete); } @@ -381,10 +400,10 @@ class Linkinfo extends Controller $u = channelx_by_nick($nick); if ($u && $p) { - $sql_extra = permissions_sql(intval($u['channel_id'])); - $r = q("select hash, content from attach where display_path = '%s' and uid = %d and os_storage = 1 $sql_extra limit 1", + $r = q( + "select hash, content from attach where display_path = '%s' and uid = %d and os_storage = 1 $sql_extra limit 1", dbesc($p), intval($u['channel_id']) ); @@ -405,16 +424,18 @@ class Linkinfo extends Controller $result = z_fetch_url($url, false, 0, array('novalidate' => true)); - if (!$result['success']) + if (!$result['success']) { return $siteinfo; + } $header = $result['header']; $body = $result['body']; // Check codepage in HTTP headers or HTML if not exist $cp = (preg_match('/Content-Type: text\/html; charset=(.+)\r\n/i', $header, $o) ? $o[1] : ''); - if (empty($cp)) + if (empty($cp)) { $cp = (preg_match('/meta.+content=["|\']text\/html; charset=([^"|\']+)/i', $body, $o) ? $o[1] : 'AUTO'); + } $body = mb_convert_encoding($body, 'UTF-8', $cp); $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); @@ -438,16 +459,19 @@ class Linkinfo extends Controller //$list = $xpath->query("head/title"); $list = $xpath->query("//title"); - foreach ($list as $node) + foreach ($list as $node) { $siteinfo["title"] = html_entity_decode($node->nodeValue, ENT_QUOTES, "UTF-8"); + } //$list = $xpath->query("head/meta[@name]"); $list = $xpath->query("//meta[@name]"); foreach ($list as $node) { $attr = []; - if ($node->attributes->length) - foreach ($node->attributes as $attribute) + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { $attr[$attribute->name] = $attribute->value; + } + } $attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"); @@ -497,9 +521,11 @@ class Linkinfo extends Controller $list = $xpath->query("//meta[@property]"); foreach ($list as $node) { $attr = []; - if ($node->attributes->length) - foreach ($node->attributes as $attribute) + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { $attr[$attribute->name] = $attribute->value; + } + } $attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"); @@ -520,9 +546,11 @@ class Linkinfo extends Controller $list = $xpath->query("//img[@src]"); foreach ($list as $node) { $attr = []; - if ($node->attributes->length) - foreach ($node->attributes as $attribute) + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { $attr[$attribute->name] = $attribute->value; + } + } $src = self::completeurl($attr["src"], $url); $photodata = @getimagesize($src); @@ -540,7 +568,6 @@ class Linkinfo extends Controller "width" => $photodata[0], "height" => $photodata[1]); } - } } else { $src = self::completeurl($siteinfo["image"], $url); @@ -549,40 +576,48 @@ class Linkinfo extends Controller $photodata = @getimagesize($src); - if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10)) + if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10)) { $siteinfo["images"][] = array("src" => $src, "width" => $photodata[0], "height" => $photodata[1]); + } } if ($siteinfo["text"] == "") { $text = ""; $list = $xpath->query("//div[@class='article']"); - foreach ($list as $node) - if (strlen($node->nodeValue) > 40) + foreach ($list as $node) { + if (strlen($node->nodeValue) > 40) { $text .= " " . trim($node->nodeValue); + } + } if ($text == "") { $list = $xpath->query("//div[@class='content']"); - foreach ($list as $node) - if (strlen($node->nodeValue) > 40) + foreach ($list as $node) { + if (strlen($node->nodeValue) > 40) { $text .= " " . trim($node->nodeValue); + } + } } // If none text was found then take the paragraph content if ($text == "") { $list = $xpath->query("//p"); - foreach ($list as $node) - if (strlen($node->nodeValue) > 40) + foreach ($list as $node) { + if (strlen($node->nodeValue) > 40) { $text .= " " . trim($node->nodeValue); + } + } } if ($text != "") { $text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text)); - while (strpos($text, " ")) + while (strpos($text, " ")) { $text = trim(str_replace(" ", " ", $text)); + } $siteinfo["text"] = html_entity_decode(substr($text, 0, 350), ENT_QUOTES, "UTF-8") . '...'; } @@ -598,5 +633,4 @@ class Linkinfo extends Controller $item = '#' . $item; } } - } diff --git a/Zotlabs/Module/Lists.php b/Zotlabs/Module/Lists.php index 1b5210087..a71373b50 100644 --- a/Zotlabs/Module/Lists.php +++ b/Zotlabs/Module/Lists.php @@ -1,4 +1,5 @@ 2 && argv(1) === 'view') { $grp = argv(2); if ($grp) { - $r = q("select * from pgrp where hash = '%s' and deleted = 0", + $r = q( + "select * from pgrp where hash = '%s' and deleted = 0", dbesc($grp) ); if ($r) { @@ -206,10 +209,10 @@ class Lists extends Controller $switchtotext = get_pconfig(local_channel(), 'system', 'listedit_image_limit', get_config('system', 'listedit_image_limit', 1000)); if ((argc() == 1) || ((argc() == 2) && (argv(1) === 'new'))) { - $new = (((argc() == 2) && (argv(1) === 'new')) ? true : false); - $groups = q("SELECT id, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + $groups = q( + "SELECT id, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval(local_channel()) ); @@ -241,7 +244,6 @@ class Lists extends Controller ]); return $o; - } $context = array('$submit' => t('Submit')); @@ -251,16 +253,19 @@ class Lists extends Controller check_form_security_token_redirectOnErr('/lists', 'group_drop', 't'); if (intval(argv(2))) { - $r = q("SELECT gname FROM pgrp WHERE id = %d AND uid = %d LIMIT 1", + $r = q( + "SELECT gname FROM pgrp WHERE id = %d AND uid = %d LIMIT 1", intval(argv(2)), intval(local_channel()) ); - if ($r) + if ($r) { $result = AccessList::remove(local_channel(), $r[0]['gname']); - if ($result) + } + if ($result) { info(t('Access list removed.') . EOL); - else + } else { notice(t('Unable to remove access list.') . EOL); + } } goaway(z_root() . '/lists'); // NOTREACHED @@ -268,38 +273,40 @@ class Lists extends Controller if ((argc() > 2) && intval(argv(1)) && argv(2)) { - check_form_security_token_ForbiddenOnErr('group_member_change', 't'); - $r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1", + $r = q( + "SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1", dbesc(base64url_decode(argv(2))), intval(local_channel()) ); - if (count($r)) + if (count($r)) { $change = base64url_decode(argv(2)); - + } } if (argc() > 1) { - require_once('include/acl_selectors.php'); if (strlen(argv(1)) <= 11 && intval(argv(1))) { - $r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1", + $r = q( + "SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1", intval(argv(1)), intval(local_channel()) ); } else { - $r = q("SELECT * FROM pgrp WHERE hash = '%s' AND uid = %d AND deleted = 0 LIMIT 1", + $r = q( + "SELECT * FROM pgrp WHERE hash = '%s' AND uid = %d AND deleted = 0 LIMIT 1", dbesc(argv(1)), intval(local_channel()) ); } if (!$r) { - $r = q("SELECT * FROM pgrp WHERE id = %d AND deleted = 0 LIMIT 1", + $r = q( + "SELECT * FROM pgrp WHERE id = %d AND deleted = 0 LIMIT 1", intval(argv(1)), - ); + ); if ($r) { notice(t('Permission denied.') . EOL); } else { @@ -313,13 +320,14 @@ class Lists extends Controller $preselected = []; if (count($members)) { - foreach ($members as $member) - if (!in_array($member['xchan_hash'], $preselected)) + foreach ($members as $member) { + if (!in_array($member['xchan_hash'], $preselected)) { $preselected[] = $member['xchan_hash']; + } + } } if ($change) { - if (in_array($change, $preselected)) { AccessList::member_remove(local_channel(), $group['gname'], $change); } else { @@ -330,8 +338,9 @@ class Lists extends Controller $preselected = []; if (count($members)) { - foreach ($members as $member) + foreach ($members as $member) { $preselected[] = $member['xchan_hash']; + } } } @@ -346,11 +355,11 @@ class Lists extends Controller '$delete' => t('Delete access list'), '$form_security_token_drop' => get_form_security_token("group_drop"), ); - } - if (!isset($group)) + if (!isset($group)) { return; + } $groupeditor = array( 'label_members' => t('List members'), @@ -366,11 +375,13 @@ class Lists extends Controller $member['archived'] = (intval($member['abook_archived']) ? true : false); $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;'; $groupeditor['members'][] = micropro($member, true, 'mpgroup', $textmode); - } else + } else { AccessList::member_remove(local_channel(), $group['gname'], $member['xchan_hash']); + } } - $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", + $r = q( + "SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", intval(local_channel()) ); @@ -395,8 +406,5 @@ class Lists extends Controller } return replace_macros($tpl, $context); - } - - } diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php index 3e9056f94..6bb6bce31 100644 --- a/Zotlabs/Module/Lockview.php +++ b/Zotlabs/Module/Lockview.php @@ -1,4 +1,5 @@ 2) ? intval(argv(2)) : 0); } - if (!$item_id) + if (!$item_id) { killme(); + } - if (!in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom'))) + if (!in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom'))) { killme(); + } // we have different naming in in menu_item table and chatroom table switch ($type) { @@ -51,13 +55,15 @@ class Lockview extends Controller break; } - $r = q("SELECT * FROM %s WHERE $id = %d LIMIT 1", + $r = q( + "SELECT * FROM %s WHERE $id = %d LIMIT 1", dbesc($type), intval($item_id) ); - if (!$r) + if (!$r) { killme(); + } $item = $r[0]; @@ -102,9 +108,10 @@ class Lockview extends Controller } - if (intval($item['item_private']) && (!strlen($item['allow_cid'])) && (!strlen($item['allow_gid'])) - && (!strlen($item['deny_cid'])) && (!strlen($item['deny_gid']))) { - + if ( + intval($item['item_private']) && (!strlen($item['allow_cid'])) && (!strlen($item['allow_gid'])) + && (!strlen($item['deny_cid'])) && (!strlen($item['deny_gid'])) + ) { if ($item['mid'] === $item['parent_mid']) { echo ''; killme(); @@ -127,15 +134,19 @@ class Lockview extends Controller if (count($allowed_groups)) { $r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); - if ($r) - foreach ($r as $rr) + if ($r) { + foreach ($r as $rr) { $l[] = ''; + } + } } if (count($allowed_users)) { $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $allowed_users) . " )"); - if ($r) - foreach ($r as $rr) + if ($r) { + foreach ($r as $rr) { $l[] = ''; + } + } if ($atokens) { foreach ($atokens as $at) { if (in_array("'" . $at['xchan_hash'] . "'", $allowed_users)) { @@ -147,15 +158,19 @@ class Lockview extends Controller if (count($deny_groups)) { $r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); - if ($r) - foreach ($r as $rr) + if ($r) { + foreach ($r as $rr) { $l[] = ''; + } + } } if (count($deny_users)) { $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )"); - if ($r) - foreach ($r as $rr) + if ($r) { + foreach ($r as $rr) { $l[] = ''; + } + } if ($atokens) { foreach ($atokens as $at) { @@ -164,14 +179,9 @@ class Lockview extends Controller } } } - - } echo $o . implode($l); killme(); - - } - } diff --git a/Zotlabs/Module/Locs.php b/Zotlabs/Module/Locs.php index 23a2211f0..b95d8ad46 100644 --- a/Zotlabs/Module/Locs.php +++ b/Zotlabs/Module/Locs.php @@ -1,27 +1,28 @@ nuke(); } goaway(z_root()); - } } diff --git a/Zotlabs/Module/Lostpass.php b/Zotlabs/Module/Lostpass.php index 372a9a7a1..b274372e2 100644 --- a/Zotlabs/Module/Lostpass.php +++ b/Zotlabs/Module/Lostpass.php @@ -1,8 +1,7 @@ sprintf(t('Site Member (%s)'), $email), '$email' => $email, '$new_password' => $new_password, - '$uid' => $newuid) - ); + '$uid' => $newuid)); $res = z_mail( [ @@ -127,7 +131,6 @@ class Lostpass extends Controller return $o; } - } else { $tpl = get_markup_template('lostpass.tpl'); @@ -140,7 +143,5 @@ class Lostpass extends Controller return $o; } - } - } diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index 99d8a4ca7..6cc5e6e72 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -1,6 +1,6 @@ 2) { if (argv(2) === 'default') { - $r = q("select channel_id from channel where channel_id = %d and channel_account_id = %d limit 1", + $r = q( + "select channel_id from channel where channel_id = %d and channel_account_id = %d limit 1", intval($change_channel), intval(get_account_id()) ); if ($r) { - q("update account set account_default_channel = %d where account_id = %d", + q( + "update account set account_default_channel = %d where account_id = %d", intval($change_channel), intval(get_account_id()) ); @@ -41,12 +44,10 @@ class Manage extends Controller PConfig::set($change_channel, 'system', 'include_in_menu', 1 - $state); goaway(z_root() . '/manage'); } - } if ($change_channel) { - $r = change_channel($change_channel); if ((argc() > 2) && !(argv(2) === 'default')) { @@ -59,14 +60,14 @@ class Manage extends Controller $channels = null; - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", intval(get_account_id()) ); $account = App::get_account(); if ($r && count($r)) { - $channels = ((is_site_admin()) ? array_merge([get_sys_channel()], $r) : $r); for ($x = 0; $x < count($channels); $x++) { $channels[$x]['link'] = 'manage/' . intval($channels[$x]['channel_id']); @@ -76,7 +77,8 @@ class Manage extends Controller $channels[$x]['collections_label'] = t('Collection'); $channels[$x]['forum_label'] = t('Group'); - $c = q("SELECT id, item_wall FROM item + $c = q( + "SELECT id, item_wall FROM item WHERE item_unseen = 1 and uid = %d " . item_normal(), intval($channels[$x]['channel_id']) ); @@ -92,7 +94,8 @@ class Manage extends Controller } - $intr = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", + $intr = q( + "SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", intval($channels[$x]['channel_id']) ); @@ -100,7 +103,8 @@ class Manage extends Controller $channels[$x]['intros'] = intval($intr[0]['total']); } - $events = q("SELECT etype, dtstart, adjust FROM event + $events = q( + "SELECT etype, dtstart, adjust FROM event WHERE event.uid = %d AND dtstart < '%s' AND dtstart > '%s' and dismissed = 0 ORDER BY dtstart ASC ", intval($channels[$x]['channel_id']), @@ -133,10 +137,10 @@ class Manage extends Controller } } } - } - $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0", + $r = q( + "select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0", intval(get_account_id()) ); $limit = account_service_class_fetch(get_account_id(), 'total_identities'); @@ -152,7 +156,8 @@ class Manage extends Controller $delegates = null; if (local_channel()) { - $delegates = q("select * from abook left join xchan on abook_xchan = xchan_hash where + $delegates = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_xchan in ( select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s' )", intval(local_channel()), intval(local_channel()), @@ -168,7 +173,6 @@ class Manage extends Controller $delegates[$x]['delegate'] = 1; $delegates[$x]['collections_label'] = t('Collection'); $delegates[$x]['forum_label'] = t('Group'); - } } else { $delegates = null; @@ -192,5 +196,4 @@ class Manage extends Controller '$delegates' => $delegates ]); } - } diff --git a/Zotlabs/Module/Manifest.php b/Zotlabs/Module/Manifest.php index 67e271be1..ab3163196 100644 --- a/Zotlabs/Module/Manifest.php +++ b/Zotlabs/Module/Manifest.php @@ -1,11 +1,11 @@ ' . $desc . ''; return $text; - } - } diff --git a/Zotlabs/Module/Menu.php b/Zotlabs/Module/Menu.php index d810d1c8d..8879a448c 100644 --- a/Zotlabs/Module/Menu.php +++ b/Zotlabs/Module/Menu.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - } @@ -50,15 +51,18 @@ class Menu extends Controller App::$is_sys = true; } - if (!$uid) + if (!$uid) { return; + } $_REQUEST['menu_channel_id'] = $uid; - if ($_REQUEST['menu_bookmark']) + if ($_REQUEST['menu_bookmark']) { $_REQUEST['menu_flags'] |= MENU_BOOKMARK; - if ($_REQUEST['menu_system']) + } + if ($_REQUEST['menu_system']) { $_REQUEST['menu_flags'] |= MENU_SYSTEM; + } $menu_id = ((argc() > 1) ? intval(argv(1)) : 0); if ($menu_id) { @@ -68,8 +72,9 @@ class Menu extends Controller menu_sync_packet($uid, get_observer_hash(), $menu_id); //info( t('Menu updated.') . EOL); goaway(z_root() . '/mitem/' . $which . '/' . $menu_id . ((App::$is_sys) ? '?f=&sys=1' : '')); - } else + } else { notice(t('Unable to update menu.') . EOL); + } } else { $r = menu_create($_REQUEST); if ($r) { @@ -77,9 +82,9 @@ class Menu extends Controller //info( t('Menu created.') . EOL); goaway(z_root() . '/mitem/' . $which . '/' . $r . ((App::$is_sys) ? '?f=&sys=1' : '')); - } else + } else { notice(t('Unable to create menu.') . EOL); - + } } } @@ -143,7 +148,6 @@ class Menu extends Controller } if (argc() == 2) { - $channel = (($sys) ? $sys : channelx_by_n($owner)); // list menus @@ -151,8 +155,9 @@ class Menu extends Controller if ($x) { for ($y = 0; $y < count($x); $y++) { $m = menu_fetch($x[$y]['menu_name'], $owner, get_observer_hash()); - if ($m) + if ($m) { $x[$y]['element'] = '[element]' . base64url_encode(json_encode(menu_element($channel, $m))) . '[/element]'; + } $x[$y]['bookmark'] = (($x[$y]['menu_flags'] & MENU_BOOKMARK) ? true : false); } } @@ -188,17 +193,16 @@ class Menu extends Controller )); return $o; - } if (argc() > 2) { if (intval(argv(2))) { - if (argc() == 4 && argv(3) == 'drop') { menu_sync_packet($owner, get_observer_hash(), intval(argv(1)), true); $r = menu_delete_id(intval(argv(2)), $owner); - if (!$r) + if (!$r) { notice(t('Menu could not be deleted.') . EOL); + } goaway(z_root() . '/menu/' . $which . ((App::$is_sys) ? '?f=&sys=1' : '')); } @@ -226,13 +230,10 @@ class Menu extends Controller )); return $o; - } else { notice(t('Not found.') . EOL); return; } } - } - } diff --git a/Zotlabs/Module/Mitem.php b/Zotlabs/Module/Mitem.php index a9a34a160..e0df97a52 100644 --- a/Zotlabs/Module/Mitem.php +++ b/Zotlabs/Module/Mitem.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $which = argv(1); - else + } else { return; + } Libprofile::load($which); - if (argc() < 3) + if (argc() < 3) { return; + } $m = menu_fetch_id(intval(argv(2)), App::$profile['channel_id']); if (!$m) { @@ -39,7 +42,6 @@ class Mitem extends Controller return ''; } App::$data['menu'] = $m; - } public function post() @@ -60,12 +62,14 @@ class Mitem extends Controller App::$is_sys = true; } - if (!$uid) + if (!$uid) { return; + } - if (!App::$data['menu']) + if (!App::$data['menu']) { return; + } if (!$_REQUEST['mitem_desc'] || !$_REQUEST['mitem_link']) { notice(t('Unable to create element.') . EOL); @@ -76,10 +80,12 @@ class Mitem extends Controller $_REQUEST['menu_id'] = App::$data['menu']['menu_id']; $_REQUEST['mitem_flags'] = 0; - if ($_REQUEST['usezid']) + if ($_REQUEST['usezid']) { $_REQUEST['mitem_flags'] |= MENU_ITEM_ZID; - if ($_REQUEST['newwin']) + } + if ($_REQUEST['newwin']) { $_REQUEST['mitem_flags'] |= MENU_ITEM_NEWWIN; + } $mitem_id = ((argc() > 3) ? intval(argv(3)) : 0); @@ -90,9 +96,9 @@ class Mitem extends Controller menu_sync_packet($uid, get_observer_hash(), $_REQUEST['menu_id']); //info( t('Menu element updated.') . EOL); goaway(z_root() . '/mitem/' . $which . '/' . $_REQUEST['menu_id'] . ((App::$is_sys) ? '?f=&sys=1' : '')); - } else + } else { notice(t('Unable to update menu element.') . EOL); - + } } else { $r = menu_add_item($_REQUEST['menu_id'], $uid, $_REQUEST); if ($r) { @@ -104,11 +110,10 @@ class Mitem extends Controller if ($_REQUEST['submit-more']) { goaway(z_root() . '/mitem/' . $which . '/' . $_REQUEST['menu_id'] . '?f=&display=block' . ((App::$is_sys) ? '&sys=1' : '')); } - } else + } else { notice(t('Unable to add menu element.') . EOL); - + } } - } @@ -147,8 +152,9 @@ class Mitem extends Controller $menu_list = menu_list($owner); foreach ($menu_list as $menus) { - if ($menus['menu_name'] != $m['menu']['menu_name']) + if ($menus['menu_name'] != $m['menu']['menu_name']) { $menu_names[] = $menus['menu_name']; + } } $acl = new AccessControl($channel); @@ -156,7 +162,8 @@ class Mitem extends Controller $lockstate = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'); if (argc() == 3) { - $r = q("select * from menu_item where mitem_menu_id = %d and mitem_channel_id = %d order by mitem_order asc, mitem_desc asc", + $r = q( + "select * from menu_item where mitem_menu_id = %d and mitem_channel_id = %d order by mitem_order asc, mitem_desc asc", intval(App::$data['menu']['menu_id']), intval($owner) ); @@ -215,10 +222,9 @@ class Mitem extends Controller if (argc() > 3) { - if (intval(argv(3))) { - - $m = q("select * from menu_item where mitem_id = %d and mitem_channel_id = %d limit 1", + $m = q( + "select * from menu_item where mitem_id = %d and mitem_channel_id = %d limit 1", intval(argv(3)), intval($owner) ); @@ -236,10 +242,11 @@ class Mitem extends Controller menu_sync_packet($owner, get_observer_hash(), $mitem['mitem_menu_id']); $r = menu_del_item($mitem['mitem_menu_id'], $owner, intval(argv(3))); menu_sync_packet($owner, get_observer_hash(), $mitem['mitem_menu_id']); - if ($r) + if ($r) { info(t('Menu item deleted.') . EOL); - else + } else { notice(t('Menu item could not be deleted.') . EOL); + } goaway(z_root() . '/mitem/' . $which . '/' . $mitem['mitem_menu_id'] . ((App::$is_sys) ? '?f=&sys=1' : '')); } @@ -271,5 +278,4 @@ class Mitem extends Controller } } } - } diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php index ababeae17..3397991fe 100644 --- a/Zotlabs/Module/Moderate.php +++ b/Zotlabs/Module/Moderate.php @@ -26,21 +26,22 @@ class Moderate extends Controller //show all items if (argc() == 1) { - $r = q("select item.id as item_id, item.* from item where item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", + $r = q( + "select item.id as item_id, item.* from item where item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", intval(local_channel()), intval(ITEM_MODERATED) ); if (!$r) { info(t('No entries.') . EOL); } - } // show a single item if (argc() == 2) { $post_id = unpack_link_id(escape_tags(argv(1))); - $r = q("select item.id as item_id, item.* from item where item.mid = '%s' and item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", + $r = q( + "select item.id as item_id, item.* from item where item.mid = '%s' and item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", dbesc($post_id), intval(local_channel()), intval(ITEM_MODERATED) @@ -49,12 +50,14 @@ class Moderate extends Controller if (argc() > 2) { $post_id = intval(argv(1)); - if (!$post_id) + if (!$post_id) { goaway(z_root() . '/moderate'); + } $action = argv(2); - $r = q("select * from item where uid = %d and id = %d and item_blocked = %d limit 1", + $r = q( + "select * from item where uid = %d and id = %d and item_blocked = %d limit 1", intval(local_channel()), intval($post_id), intval(ITEM_MODERATED) @@ -64,7 +67,8 @@ class Moderate extends Controller $item = $r[0]; if ($action === 'approve') { - q("update item set item_blocked = 0 where uid = %d and id = %d", + q( + "update item set item_blocked = 0 where uid = %d and id = %d", intval(local_channel()), intval($post_id) ); @@ -81,7 +85,8 @@ class Moderate extends Controller // refetch the item after changes have been made - $r = q("select * from item where id = %d", + $r = q( + "select * from item where id = %d", intval($post_id) ); if ($r) { @@ -118,7 +123,5 @@ class Moderate extends Controller $o = conversation($items, 'moderate', false, 'traditional'); $o .= alt_pager(count($items)); return $o; - } - } diff --git a/Zotlabs/Module/Mood.php b/Zotlabs/Module/Mood.php index 407558a99..d3e170ecb 100644 --- a/Zotlabs/Module/Mood.php +++ b/Zotlabs/Module/Mood.php @@ -1,4 +1,5 @@ $v) - if ($v !== 'NOTRANSLATION') + foreach ($verbs as $k => $v) { + if ($v !== 'NOTRANSLATION') { $shortlist[] = array($k, $v); + } + } $tpl = get_markup_template('mood_content.tpl'); @@ -159,7 +167,5 @@ class Mood extends Controller )); return $o; - } - } diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 6547ff392..4d1f4007a 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -1,6 +1,6 @@ 64) + if ((!$x) || strlen($x) > 64) { $x = strtolower(URLify::transliterate($n)); + } $test = []; // first name - if (strpos($x, ' ')) + if (strpos($x, ' ')) { $test[] = legal_webbie(substr($x, 0, strpos($x, ' '))); + } if ($test[0]) { // first name plus first initial of last $test[] = ((strpos($x, ' ')) ? $test[0] . legal_webbie(trim(substr($x, strpos($x, ' '), 2))) : ''); @@ -64,15 +66,17 @@ class New_channel extends Controller $x = punify(mb_strtolower($n)); } - if ((!$x) || strlen($x) > 64) + if ((!$x) || strlen($x) > 64) { $x = strtolower(URLify::transliterate($n)); + } $test = []; // first name - if (strpos($x, ' ')) + if (strpos($x, ' ')) { $test[] = legal_webbie(substr($x, 0, strpos($x, ' '))); + } if ($test[0]) { // first name plus first initial of last $test[] = ((strpos($x, ' ')) ? $test[0] . legal_webbie(trim(substr($x, strpos($x, ' '), 2))) : ''); @@ -86,13 +90,12 @@ class New_channel extends Controller $test[] = $n . mt_rand(1000, 9999); } - for ($y = 0; $y < 100; $y++) + for ($y = 0; $y < 100; $y++) { $test[] = 'id' . mt_rand(1000, 9999); + } json_return_and_die(check_webbie($test)); } - - } public function post() @@ -133,7 +136,6 @@ class New_channel extends Controller $next_page = get_config('system', 'workflow_channel_next', 'profiles'); goaway(z_root() . '/' . $next_page); - } public function get() @@ -149,7 +151,8 @@ class New_channel extends Controller $default_role = ''; $aid = get_account_id(); if ($aid) { - $r = q("select count(channel_id) as total from channel where channel_account_id = %d", + $r = q( + "select count(channel_id) as total from channel where channel_account_id = %d", intval($aid) ); if ($r && (!intval($r[0]['total']))) { @@ -202,8 +205,5 @@ class New_channel extends Controller )); return $o; - } - - } diff --git a/Zotlabs/Module/Notes.php b/Zotlabs/Module/Notes.php index 8a82ee113..5040d4e3b 100644 --- a/Zotlabs/Module/Notes.php +++ b/Zotlabs/Module/Notes.php @@ -1,5 +1,8 @@ true); if (array_key_exists('note_text', $_REQUEST)) { @@ -24,8 +28,9 @@ class Notes extends Controller if (!$body) { $old_text = get_pconfig(local_channel(), 'notes', 'text'); - if ($old_text) + if ($old_text) { set_pconfig(local_channel(), 'notes', 'text.bak', $old_text); + } } set_pconfig(local_channel(), 'notes', 'text', $body); @@ -38,7 +43,6 @@ class Notes extends Controller logger('notes saved.', LOGGER_DEBUG); json_return_and_die($ret); - } } @@ -58,8 +62,5 @@ class Notes extends Controller $text = ''; return $text; - } - - } diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php index b107c4d20..5b9abde5c 100644 --- a/Zotlabs/Module/Notifications.php +++ b/Zotlabs/Module/Notifications.php @@ -1,4 +1,5 @@ 49) { - $r = q("select * from notify where uid = %d + $r = q( + "select * from notify where uid = %d and seen = 0 order by created desc limit 50", intval(local_channel()) ); } else { - $r1 = q("select * from notify where uid = %d + $r1 = q( + "select * from notify where uid = %d and seen = 0 order by created desc limit 50", intval(local_channel()) ); - $r2 = q("select * from notify where uid = %d + $r2 = q( + "select * from notify where uid = %d and seen = 1 order by created desc limit %d", intval(local_channel()), intval(50 - intval($n[0]['total'])) @@ -71,5 +76,4 @@ class Notifications extends Controller return $o; } - } diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php index 02d91da3c..3bafdfc6a 100644 --- a/Zotlabs/Module/Notify.php +++ b/Zotlabs/Module/Notify.php @@ -1,10 +1,10 @@ 2 && argv(1) === 'view' && intval(argv(2))) { - $r = q("select * from notify where id = %d and uid = %d limit 1", + $r = q( + "select * from notify where id = %d and uid = %d limit 1", intval(argv(2)), intval(local_channel()) ); @@ -28,7 +29,8 @@ class Notify extends Controller $x = ['channel_id' => local_channel(), 'update' => 'unset']; call_hooks('update_unseen', $x); if ((!$_SESSION['sudo']) && ($x['update'] === 'unset' || intval($x['update']))) { - q("update notify set seen = 1 where (( parent != '' and parent = '%s' and otype = '%s' ) or link = '%s' ) and uid = %d", + q( + "update notify set seen = 1 where (( parent != '' and parent = '%s' and otype = '%s' ) or link = '%s' ) and uid = %d", dbesc($r[0]['parent']), dbesc($r[0]['otype']), dbesc($r[0]['link']), @@ -40,8 +42,6 @@ class Notify extends Controller notice(sprintf(t('A notification with that id was not found for channel \'%s\''), $channel['channel_name'])); goaway(z_root()); } - - } @@ -55,7 +55,8 @@ class Notify extends Controller $not_tpl = get_markup_template('notify.tpl'); - $r = q("SELECT * from notify where uid = %d and seen = 0 order by created desc", + $r = q( + "SELECT * from notify where uid = %d and seen = 0 order by created desc", intval(local_channel()) ); @@ -79,6 +80,5 @@ class Notify extends Controller )); return $o; - } } diff --git a/Zotlabs/Module/Nullbox.php b/Zotlabs/Module/Nullbox.php index 1f3e0ad1c..02e90258e 100644 --- a/Zotlabs/Module/Nullbox.php +++ b/Zotlabs/Module/Nullbox.php @@ -11,6 +11,4 @@ class Nullbox extends Controller { http_status_exit(404, 'Permission Denied'); } - } - diff --git a/Zotlabs/Module/Oauthinfo.php b/Zotlabs/Module/Oauthinfo.php index d2205d4cf..7f67f6731 100644 --- a/Zotlabs/Module/Oauthinfo.php +++ b/Zotlabs/Module/Oauthinfo.php @@ -1,4 +1,5 @@ "; } } killme(); } - } diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index 918a81fea..10991860c 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -1,4 +1,5 @@ oep_album_reply($_REQUEST); - elseif (fnmatch('*/photos/*/image/*', $url)) + } elseif (fnmatch('*/photos/*/image/*', $url)) { $arr = $this->oep_photo_reply($_REQUEST); - elseif (fnmatch('*/photos*', $url)) + } elseif (fnmatch('*/photos*', $url)) { $arr = $this->oep_phototop_reply($_REQUEST); - elseif (fnmatch('*/display/*', $url)) + } elseif (fnmatch('*/display/*', $url)) { $arr = $this->oep_display_reply($_REQUEST); - elseif (fnmatch('*/channel/*mid=*', $url)) + } elseif (fnmatch('*/channel/*mid=*', $url)) { $arr = $this->oep_mid_reply($_REQUEST); - elseif (fnmatch('*/channel*', $url)) + } elseif (fnmatch('*/channel*', $url)) { $arr = $this->oep_profile_reply($_REQUEST); - elseif (fnmatch('*/profile/*', $url)) + } elseif (fnmatch('*/profile/*', $url)) { $arr = $this->oep_profile_reply($_REQUEST); - elseif (fnmatch('*/cards/*', $url)) + } elseif (fnmatch('*/cards/*', $url)) { $arr = $this->oep_cards_reply($_REQUEST); - elseif (fnmatch('*/articles/*', $url)) + } elseif (fnmatch('*/articles/*', $url)) { $arr = $this->oep_articles_reply($_REQUEST); + } if ($arr) { if ($html) { @@ -64,7 +68,6 @@ class Oep extends Controller } http_status_exit(404, 'Not found'); - } public function oep_display_reply($args) @@ -83,31 +86,37 @@ class Oep extends Controller $item_normal = item_normal(); - $p = q("select * from item where mid like '%s' limit 1", + $p = q( + "select * from item where mid like '%s' limit 1", dbesc($res . '%') ); - if (!$p) + if (!$p) { return; + } $c = channelx_by_n($p[0]['uid']); - if (!($c && $res)) + if (!($c && $res)) { return; + } - if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_stream')) + if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_stream')) { return; + } $sql_extra = item_permissions_sql($c['channel_id']); - $p = q("select * from item where mid like '%s' and uid = %d $sql_extra $item_normal limit 1", + $p = q( + "select * from item where mid like '%s' and uid = %d $sql_extra $item_normal limit 1", dbesc($res . '%'), intval($c['channel_id']) ); - if (!$p) + if (!$p) { return; + } xchan_query($p, true); $p = fetch_post_tags($p, true); @@ -129,8 +138,9 @@ class Oep extends Controller "' auth='" . (($p[0]['author']['network'] === 'zot6') ? 'true' : 'false') . "' posted='" . $p[0]['created'] . "' message_id='" . $p[0]['mid'] . "']"; - if ($p[0]['title']) + if ($p[0]['title']) { $o .= '[b]' . $p[0]['title'] . '[/b]' . "\r\n"; + } $o .= $x; $o .= "[/share]"; @@ -149,7 +159,6 @@ class Oep extends Controller $ret['height'] = $h; return $ret; - } @@ -165,21 +174,25 @@ class Oep extends Controller $nick = $matches[2]; $res = $matches[3]; } - if (!($nick && $res)) + if (!($nick && $res)) { return $ret; + } $channel = channelx_by_nick($nick); - if (!$channel) + if (!$channel) { return $ret; + } - if (!perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_pages')) + if (!perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_pages')) { return $ret; + } $sql_extra = item_permissions_sql($channel['channel_id'], get_observer_hash()); - $r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1", + $r = q( + "select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1", dbesc($res) ); if ($r) { @@ -188,7 +201,8 @@ class Oep extends Controller return $ret; } - $r = q("select * from item + $r = q( + "select * from item where item.uid = %d and item_type = %d $sql_extra order by item.created desc", intval($channel['channel_id']), @@ -215,8 +229,9 @@ class Oep extends Controller "' auth='" . (($p[0]['author']['network'] === 'zot6') ? 'true' : 'false') . "' posted='" . $p[0]['created'] . "' message_id='" . $p[0]['mid'] . "']"; - if ($p[0]['title']) + if ($p[0]['title']) { $o .= '[b]' . $p[0]['title'] . '[/b]' . "\r\n"; + } $o .= $x; $o .= "[/share]"; @@ -235,7 +250,6 @@ class Oep extends Controller $ret['height'] = $h; return $ret; - } public function oep_articles_reply($args) @@ -250,21 +264,25 @@ class Oep extends Controller $nick = $matches[2]; $res = $matches[3]; } - if (!($nick && $res)) + if (!($nick && $res)) { return $ret; + } $channel = channelx_by_nick($nick); - if (!$channel) + if (!$channel) { return $ret; + } - if (!perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_pages')) + if (!perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_pages')) { return $ret; + } $sql_extra = item_permissions_sql($channel['channel_id'], get_observer_hash()); - $r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1", + $r = q( + "select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1", dbesc($res) ); if ($r) { @@ -273,7 +291,8 @@ class Oep extends Controller return $ret; } - $r = q("select * from item + $r = q( + "select * from item where item.uid = %d and item_type = %d $sql_extra order by item.created desc", intval($channel['channel_id']), @@ -300,8 +319,9 @@ class Oep extends Controller "' auth='" . (($p[0]['author']['network'] === 'zot6') ? 'true' : 'false') . "' posted='" . $p[0]['created'] . "' message_id='" . $p[0]['mid'] . "']"; - if ($p[0]['title']) + if ($p[0]['title']) { $o .= '[b]' . $p[0]['title'] . '[/b]' . "\r\n"; + } $o .= $x; $o .= "[/share]"; @@ -320,7 +340,6 @@ class Oep extends Controller $ret['height'] = $h; return $ret; - } @@ -337,26 +356,32 @@ class Oep extends Controller $res = $matches[5]; } - if (!($chn && $res)) + if (!($chn && $res)) { return; - $c = q("select * from channel where channel_address = '%s' limit 1", + } + $c = q( + "select * from channel where channel_address = '%s' limit 1", dbesc($chn) ); - if (!$c) + if (!$c) { return; + } - if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_stream')) + if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_stream')) { return; + } $sql_extra = item_permissions_sql($c[0]['channel_id']); - $p = q("select * from item where mid = '%s' and uid = %d $sql_extra limit 1", + $p = q( + "select * from item where mid = '%s' and uid = %d $sql_extra limit 1", dbesc($res), intval($c[0]['channel_id']) ); - if (!$p) + if (!$p) { return; + } xchan_query($p, true); $p = fetch_post_tags($p, true); @@ -377,8 +402,9 @@ class Oep extends Controller "' auth='" . (($p[0]['author']['network'] === 'zot6') ? 'true' : 'false') . "' posted='" . $p[0]['created'] . "' message_id='" . $p[0]['mid'] . "']"; - if ($p[0]['title']) + if ($p[0]['title']) { $o .= '[b]' . $p[0]['title'] . '[/b]' . "\r\n"; + } $o .= $x; $o .= "[/share]"; $o = bbcode($o); @@ -396,7 +422,6 @@ class Oep extends Controller $ret['height'] = $h; return $ret; - } public function oep_profile_reply($args) @@ -411,13 +436,15 @@ class Oep extends Controller $chn = $matches[3]; } - if (!$chn) + if (!$chn) { return; + } $c = channelx_by_nick($chn); - if (!$c) + if (!$c) { return; + } $maxwidth = intval($args['maxwidth']); @@ -445,7 +472,6 @@ class Oep extends Controller $ret['html'] = get_zcard_embed($c, get_observer_hash(), array('width' => $width, 'height' => $height)); return $ret; - } public function oep_album_reply($args) @@ -461,30 +487,37 @@ class Oep extends Controller $res = basename($url); } - if (!($chn && $res)) + if (!($chn && $res)) { return; - $c = q("select * from channel where channel_address = '%s' limit 1", + } + $c = q( + "select * from channel where channel_address = '%s' limit 1", dbesc($chn) ); - if (!$c) + if (!$c) { return; + } - if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) + if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) { return; + } $sql_extra = permissions_sql($c[0]['channel_id']); - $p = q("select resource_id from photo where album = '%s' and uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", + $p = q( + "select resource_id from photo where album = '%s' and uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", dbesc($res), intval($c[0]['channel_id']) ); - if (!$p) + if (!$p) { return; + } $res = $p[0]['resource_id']; - $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", + $r = q( + "select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -492,10 +525,12 @@ class Oep extends Controller if ($r) { foreach ($r as $rr) { $foundres = false; - if ($maxheight && $rr['height'] > $maxheight) + if ($maxheight && $rr['height'] > $maxheight) { continue; - if ($maxwidth && $rr['width'] > $maxwidth) + } + if ($maxwidth && $rr['width'] > $maxwidth) { continue; + } $foundres = true; break; } @@ -506,11 +541,8 @@ class Oep extends Controller $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } - - } return $ret; - } @@ -526,29 +558,36 @@ class Oep extends Controller $chn = $matches[3]; } - if (!$chn) + if (!$chn) { return; - $c = q("select * from channel where channel_address = '%s' limit 1", + } + $c = q( + "select * from channel where channel_address = '%s' limit 1", dbesc($chn) ); - if (!$c) + if (!$c) { return; + } - if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) + if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) { return; + } $sql_extra = permissions_sql($c[0]['channel_id']); - $p = q("select resource_id from photo where uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", + $p = q( + "select resource_id from photo where uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", intval($c[0]['channel_id']) ); - if (!$p) + if (!$p) { return; + } $res = $p[0]['resource_id']; - $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", + $r = q( + "select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -556,10 +595,12 @@ class Oep extends Controller if ($r) { foreach ($r as $rr) { $foundres = false; - if ($maxheight && $rr['height'] > $maxheight) + if ($maxheight && $rr['height'] > $maxheight) { continue; - if ($maxwidth && $rr['width'] > $maxwidth) + } + if ($maxwidth && $rr['width'] > $maxwidth) { continue; + } $foundres = true; break; } @@ -570,11 +611,8 @@ class Oep extends Controller $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } - - } return $ret; - } @@ -591,22 +629,27 @@ class Oep extends Controller $res = basename($url); } - if (!($chn && $res)) + if (!($chn && $res)) { return; - $c = q("select * from channel where channel_address = '%s' limit 1", + } + $c = q( + "select * from channel where channel_address = '%s' limit 1", dbesc($chn) ); - if (!$c) + if (!$c) { return; + } - if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) + if (!perm_is_allowed($c[0]['channel_id'], get_observer_hash(), 'view_files')) { return; + } $sql_extra = permissions_sql($c[0]['channel_id']); - $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", + $r = q( + "select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -614,10 +657,12 @@ class Oep extends Controller if ($r) { foreach ($r as $rr) { $foundres = false; - if ($maxheight && $rr['height'] > $maxheight) + if ($maxheight && $rr['height'] > $maxheight) { continue; - if ($maxwidth && $rr['width'] > $maxwidth) + } + if ($maxwidth && $rr['width'] > $maxwidth) { continue; + } $foundres = true; break; } @@ -628,10 +673,7 @@ class Oep extends Controller $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } - - } return $ret; - } } diff --git a/Zotlabs/Module/Oexchange.php b/Zotlabs/Module/Oexchange.php index 69d290f5c..502878497 100644 --- a/Zotlabs/Module/Oexchange.php +++ b/Zotlabs/Module/Oexchange.php @@ -72,8 +72,5 @@ class Oexchange extends Controller $_REQUEST = $post; $mod = new Item(); $mod->post(); - } - - } diff --git a/Zotlabs/Module/Outbox.php b/Zotlabs/Module/Outbox.php index 68c5d9399..14d7270f8 100644 --- a/Zotlabs/Module/Outbox.php +++ b/Zotlabs/Module/Outbox.php @@ -71,39 +71,39 @@ class Outbox extends Controller logger('outbox_channel: ' . $channel['channel_address'], LOGGER_DEBUG); -// switch ($AS->type) { -// case 'Follow': -// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStreams::is_an_actor($AS->obj['type']) && isset($AS->obj['id'])) { -// // do follow activity -// Activity::follow($channel,$AS); -// } -// break; -// case 'Invite': -// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') { -// // do follow activity -// Activity::follow($channel,$AS); -// } -// break; -// case 'Join': -// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') { -// // do follow activity -// Activity::follow($channel,$AS); -// } -// break; -// case 'Accept': -// // Activitypub for wordpress sends lowercase 'follow' on accept. -// // https://github.com/pfefferle/wordpress-activitypub/issues/97 -// // Mobilizon sends Accept/"Member" (not in vocabulary) in response to Join/Group -// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && in_array($AS->obj['type'], ['Follow','follow', 'Member'])) { -// // do follow activity -// Activity::follow($channel,$AS); -// } -// break; -// case 'Reject': -// default: -// break; +// switch ($AS->type) { +// case 'Follow': +// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStreams::is_an_actor($AS->obj['type']) && isset($AS->obj['id'])) { +// // do follow activity +// Activity::follow($channel,$AS); +// } +// break; +// case 'Invite': +// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') { +// // do follow activity +// Activity::follow($channel,$AS); +// } +// break; +// case 'Join': +// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') { +// // do follow activity +// Activity::follow($channel,$AS); +// } +// break; +// case 'Accept': +// // Activitypub for wordpress sends lowercase 'follow' on accept. +// // https://github.com/pfefferle/wordpress-activitypub/issues/97 +// // Mobilizon sends Accept/"Member" (not in vocabulary) in response to Join/Group +// if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && in_array($AS->obj['type'], ['Follow','follow', 'Member'])) { +// // do follow activity +// Activity::follow($channel,$AS); +// } +// break; +// case 'Reject': +// default: +// break; // -// } +// } // These activities require permissions @@ -170,9 +170,11 @@ class Outbox extends Controller Activity::drop($channel, $observer_hash, $AS); break; case 'Move': - if ($observer_hash && $observer_hash === $AS->actor + if ( + $observer_hash && $observer_hash === $AS->actor && is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStream::is_an_actor($AS->obj['type']) - && is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type'])) { + && is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type']) + ) { ActivityPub::move($AS->obj, $AS->tgt); } break; @@ -180,7 +182,6 @@ class Outbox extends Controller case 'Remove': default: break; - } if ($item) { @@ -190,7 +191,6 @@ class Outbox extends Controller http_status_exit(200, 'OK'); return; - } @@ -210,9 +210,9 @@ class Outbox extends Controller killme(); } -// if (intval($channel['channel_system'])) { -// killme(); -// } +// if (intval($channel['channel_system'])) { +// killme(); +// } if (ActivityStreams::is_as_request()) { $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); @@ -255,7 +255,11 @@ class Outbox extends Controller 'top' => $params['top'], 'cat' => $params['cat'], 'compat' => $params['compat'] - ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module + ], + $channel, + $observer_hash, + CLIENT_MODE_NORMAL, + App::$module ); if ($total) { @@ -279,15 +283,19 @@ class Outbox extends Controller 'top' => $params['top'], 'cat' => $params['cat'], 'compat' => $params['compat'] - ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module + ], + $channel, + $observer_hash, + CLIENT_MODE_NORMAL, + App::$module ); if ($items && $observer_hash) { - // check to see if this observer is a connection. If not, register any items // belonging to this channel for notification of deletion/expiration - $x = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + $x = q( + "select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", intval($channel['channel_id']), dbesc($observer_hash) ); @@ -307,6 +315,3 @@ class Outbox extends Controller } } } - - - diff --git a/Zotlabs/Module/Owa.php b/Zotlabs/Module/Owa.php index c338be9e2..2cff083ac 100644 --- a/Zotlabs/Module/Owa.php +++ b/Zotlabs/Module/Owa.php @@ -11,9 +11,9 @@ use Zotlabs\Web\Controller; * See spec/OpenWebAuth/Home.md * Requests to this endpoint should be signed using HTTP Signatures * using the 'Authorization: Signature' authentication method - * If the signature verifies a token is returned. + * If the signature verifies a token is returned. * - * This token may be exchanged for an authenticated cookie. + * This token may be exchanged for an authenticated cookie. */ class Owa extends Controller { @@ -33,7 +33,8 @@ class Owa extends Controller if ($sigblock) { $keyId = $sigblock['keyId']; if ($keyId) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash + $r = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) and xchan_pubkey != '' ", dbesc(str_replace('acct:', '', $keyId)), dbesc($keyId) @@ -41,7 +42,8 @@ class Owa extends Controller if (!$r) { $found = discover_by_webbie(str_replace('acct:', '', $keyId)); if ($found) { - $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash + $r = q( + "select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) and xchan_pubkey != '' ", dbesc(str_replace('acct:', '', $keyId)), dbesc($keyId) diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index 20b582041..93d606fbb 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -1,6 +1,6 @@ parse($r[0]['body']); App::$pdl = $r[0]['body']; } elseif ($r[0]['layout_mid']) { - $l = q("select body from item where mid = '%s' and uid = %d limit 1", + $l = q( + "select body from item where mid = '%s' and uid = %d limit 1", dbesc($r[0]['layout_mid']), intval($u[0]['channel_id']) ); @@ -164,32 +173,30 @@ class Page extends Controller } App::$data['webpage'] = $r; - } public function get() { $r = App::$data['webpage']; - if (!$r) + if (!$r) { return; + } if ($r[0]['item_type'] == ITEM_TYPE_PDL) { $r[0]['body'] = t('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'); $r[0]['mimetype'] = 'text/plain'; $r[0]['title'] = ''; - } xchan_query($r); $r = fetch_post_tags($r, true); - if ($r[0]['mimetype'] === 'application/x-pdl') + if ($r[0]['mimetype'] === 'application/x-pdl') { App::$page['pdl_content'] = true; + } $o .= prepare_page($r[0]); return $o; - } - } diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php index ee048fefa..52da386ef 100644 --- a/Zotlabs/Module/Pconfig.php +++ b/Zotlabs/Module/Pconfig.php @@ -1,11 +1,11 @@ disallowed_pconfig())) { notice(t('This setting requires special processing and editing has been blocked.') . EOL); return $content; - } else + } else { $content .= $this->pconfig_form(escape_tags(argv(1)), escape_tags(argv(2))); + } } @@ -89,7 +89,6 @@ class Pconfig extends Controller } if (argc() == 1) { - $r = q("select * from pconfig where uid = " . local_channel()); if ($r) { foreach ($r as $rr) { @@ -98,7 +97,6 @@ class Pconfig extends Controller } } return $content; - } @@ -109,16 +107,17 @@ class Pconfig extends Controller $o .= ''; $v = get_pconfig(local_channel(), $cat, $k); - if (strpos($k, 'password') !== false) + if (strpos($k, 'password') !== false) { $v = unobscurify($v); + } $o .= ''; $o .= ''; - if (strpos($v, "\n")) + if (strpos($v, "\n")) { $o .= ''; - else { + } else { if (is_array($v)) { $o .= '
' . "\n" . print_array($v) . '
'; $o .= ''; @@ -131,7 +130,6 @@ class Pconfig extends Controller $o .= ''; return $o; - } @@ -141,5 +139,4 @@ class Pconfig extends Controller 'permissions_role' ); } - } diff --git a/Zotlabs/Module/Pdledit.php b/Zotlabs/Module/Pdledit.php index 6e58667aa..756601242 100644 --- a/Zotlabs/Module/Pdledit.php +++ b/Zotlabs/Module/Pdledit.php @@ -1,4 +1,5 @@ 1) + if (argc() > 1) { $module = 'mod_' . argv(1) . '.pdl'; - else { + } else { $o .= '
'; $o .= '

' . t('Edit System Page Description') . '

'; $edited = []; - $r = q("select k from pconfig where uid = %d and cat = 'system' and k like '%s' ", + $r = q( + "select k from pconfig where uid = %d and cat = 'system' and k like '%s' ", intval(local_channel()), dbesc('mod_%.pdl') ); @@ -86,8 +90,9 @@ class Pdledit extends Controller $s = @file_get_contents(theme_include($module)); if (!$s) { $a = glob('addon/*/' . $module); - if ($a) + if ($a) { $s = @file_get_contents($a[0]); + } } if (!$t) { $t = $s; @@ -111,5 +116,4 @@ class Pdledit extends Controller return $o; } - } diff --git a/Zotlabs/Module/Permcat.php b/Zotlabs/Module/Permcat.php index c1891cdf3..6e49ea6ec 100644 --- a/Zotlabs/Module/Permcat.php +++ b/Zotlabs/Module/Permcat.php @@ -5,22 +5,23 @@ namespace Zotlabs\Module; use Zotlabs\Lib as Zlib; use Zotlabs\Web\Controller; -class Permcat extends Controller { +class Permcat extends Controller +{ - private $permcats = []; + private $permcats = []; - public function init() { - if(! local_channel()) - return; + public function init() + { + if (! local_channel()) { + return; + } - $permcat = new Zlib\Permcat(local_channel()); + $permcat = new Zlib\Permcat(local_channel()); - if(argc() > 1) - json_return_and_die($permcat->fetch(argv(1))); + if (argc() > 1) { + json_return_and_die($permcat->fetch(argv(1))); + } - json_return_and_die($permcat->listing()); - - } - - -} \ No newline at end of file + json_return_and_die($permcat->listing()); + } +} diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 43a0f8a5d..f08258bad 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -1,4 +1,5 @@
' . t('This app is currently installed.'); } - - } diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 4c8152d45..35bfff1e5 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -1,4 +1,5 @@ 1) { - $nick = escape_tags(argv(1)); Libprofile::load($nick); @@ -75,7 +75,6 @@ class Photos extends Controller $acl = new AccessControl(App::$data['channel']); if ((argc() > 3) && (argv(2) === 'album')) { - $album = argv(3); if (!photos_album_exists($page_owner_uid, get_observer_hash(), $album)) { @@ -89,10 +88,10 @@ class Photos extends Controller */ if ($_REQUEST['dropalbum'] === t('Delete Album')) { - $folder_hash = ''; - $r = q("select hash from attach where is_dir = 1 and uid = %d and hash = '%s'", + $r = q( + "select hash from attach where is_dir = 1 and uid = %d and hash = '%s'", intval($page_owner_uid), dbesc($album) ); @@ -123,7 +122,8 @@ class Photos extends Controller goaway(z_root() . '/' . $_SESSION['photo_return']); } - $r = q("select id from item where resource_id in ( $str ) and resource_type = 'photo' and uid = %d " . item_normal(), + $r = q( + "select id from item where resource_id in ( $str ) and resource_type = 'photo' and uid = %d " . item_normal(), intval($page_owner_uid) ); if ($r) { @@ -134,11 +134,13 @@ class Photos extends Controller // remove the associated photos in case they weren't attached to an item (rare) - q("delete from photo where resource_id in ( $str ) and uid = %d", + q( + "delete from photo where resource_id in ( $str ) and uid = %d", intval($page_owner_uid) ); - q("delete from attach where hash in ( $str ) and uid = %d", + q( + "delete from attach where hash in ( $str ) and uid = %d", intval($page_owner_uid) ); @@ -178,7 +180,8 @@ class Photos extends Controller // The site admin can of course modify anything on their own site for // maintenance or legal compliance reasons. - $r = q("SELECT id, resource_id FROM photo WHERE ( xchan = '%s' or uid = %d ) AND resource_id = '%s' LIMIT 1", + $r = q( + "SELECT id, resource_id FROM photo WHERE ( xchan = '%s' or uid = %d ) AND resource_id = '%s' LIMIT 1", dbesc($ob_hash), intval(local_channel()), dbesc(argv(2)) @@ -201,8 +204,8 @@ class Photos extends Controller // perform move_to_album if ((argc() > 2) && array_key_exists('move_to_album', $_POST)) { - - $m = q("select folder from attach where hash = '%s' and uid = %d limit 1", + $m = q( + "select folder from attach where hash = '%s' and uid = %d limit 1", dbesc(argv(2)), intval($page_owner_uid) ); @@ -234,12 +237,12 @@ class Photos extends Controller $resource_id = argv(2); - $r = q("select * from photo where resource_id = '%s' and uid = %d and imgscale = 0 limit 1", + $r = q( + "select * from photo where resource_id = '%s' and uid = %d and imgscale = 0 limit 1", dbesc($resource_id), intval($page_owner_uid) ); if ($r) { - $ph = photo_factory(@file_get_contents(dbunescbin($r[0]['content'])), $r[0]['mimetype']); if ($ph && $ph->is_valid()) { $rotate_deg = ((intval($_POST['rotate']) == 1) ? 270 : 90); @@ -247,7 +250,8 @@ class Photos extends Controller $edited = datetime_convert(); - q("update attach set filesize = %d, edited = '%s' where hash = '%s' and uid = %d", + q( + "update attach set filesize = %d, edited = '%s' where hash = '%s' and uid = %d", strlen($ph->imageString()), dbescdate($edited), dbesc($resource_id), @@ -275,16 +279,19 @@ class Photos extends Controller unset($arr['os_syspath']); - if ($width > 1024 || $height > 1024) + if ($width > 1024 || $height > 1024) { $ph->scaleImage(1024); + } $ph->storeThumbnail($arr, PHOTO_RES_1024); - if ($width > 640 || $height > 640) + if ($width > 640 || $height > 640) { $ph->scaleImage(640); + } $ph->storeThumbnail($arr, PHOTO_RES_640); - if ($width > 320 || $height > 320) + if ($width > 320 || $height > 320) { $ph->scaleImage(320); + } $ph->storeThumbnail($arr, PHOTO_RES_320); } } @@ -295,7 +302,6 @@ class Photos extends Controller // edit existing photo properties if (x($_POST, 'item_id') !== false && intval($_POST['item_id'])) { - $title = ((x($_POST, 'title')) ? escape_tags(trim($_POST['title'])) : EMPTY_STR); $desc = ((x($_POST, 'desc')) ? escape_tags(trim($_POST['desc'])) : EMPTY_STR); $body = ((x($_POST, 'body')) ? trim($_POST['body']) : EMPTY_STR); @@ -310,13 +316,15 @@ class Photos extends Controller $resource_id = argv(2); - $p = q("SELECT mimetype, is_nsfw, filename, title, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC", + $p = q( + "SELECT mimetype, is_nsfw, filename, title, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC", dbesc($resource_id), intval($page_owner_uid) ); if ($p) { // update the photo structure with any of the changed elements which are common to all resolutions - $r = q("UPDATE photo SET title = '%s', description = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' WHERE resource_id = '%s' AND uid = %d", + $r = q( + "UPDATE photo SET title = '%s', description = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' WHERE resource_id = '%s' AND uid = %d", dbesc($title), dbesc($desc), dbesc($perm['allow_cid']), @@ -332,7 +340,8 @@ class Photos extends Controller $old_is_nsfw = $p[0]['is_nsfw']; if ($old_is_nsfw != $is_nsfw) { - $r = q("update photo set is_nsfw = %d where resource_id = '%s' and uid = %d", + $r = q( + "update photo set is_nsfw = %d where resource_id = '%s' and uid = %d", intval($is_nsfw), dbesc($resource_id), intval($page_owner_uid) @@ -346,7 +355,8 @@ class Photos extends Controller $visibility = 1; } - $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item_id), intval($page_owner_uid) ); @@ -398,11 +408,13 @@ class Photos extends Controller } } if ($post_tags) { - q("delete from term where otype = 1 and oid = %d", + q( + "delete from term where otype = 1 and oid = %d", intval($linked_item['id']) ); foreach ($post_tags as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) + q( + "insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", intval($page_owner_uid), intval($linked_item['id']), @@ -435,7 +447,8 @@ class Photos extends Controller } // make sure the linked item has the same permissions as the photo regardless of any other changes - $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', title = '%s', obj = '%s', body = '%s', edited = '%s', item_private = %d where id = %d", + $x = q( + "update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', title = '%s', obj = '%s', body = '%s', edited = '%s', item_private = %d where id = %d", dbesc($perm['allow_cid']), dbesc($perm['allow_gid']), dbesc($perm['deny_cid']), @@ -449,7 +462,8 @@ class Photos extends Controller ); // make sure the attach has the same permissions as the photo regardless of any other changes - $x = q("update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where hash = '%s' and uid = %d and is_photo = 1", + $x = q( + "update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where hash = '%s' and uid = %d and is_photo = 1", dbesc($perm['allow_cid']), dbesc($perm['allow_gid']), dbesc($perm['deny_cid']), @@ -465,13 +479,12 @@ class Photos extends Controller $sync = attach_export_data(App::$data['channel'], $resource_id); - if ($sync) + if ($sync) { Libsync::build_sync_packet($page_owner_uid, ['file' => [$sync]]); + } goaway(z_root() . '/' . $_SESSION['photo_return']); return; // NOTREACHED - - } @@ -550,7 +563,6 @@ class Photos extends Controller } goaway(z_root() . '/photos/' . App::$data['channel']['channel_address'] . '/album/' . $r['data']['folder']); - } @@ -594,14 +606,16 @@ class Photos extends Controller if (argc() > 2) { $datatype = argv(2); $datum = ''; - } else + } else { $datatype = 'summary'; + } } - if (argc() > 4) + if (argc() > 4) { $cmd = argv(4); - else + } else { $cmd = 'view'; + } // // Setup permissions structures @@ -645,7 +659,6 @@ class Photos extends Controller */ if ($can_post) { - $uploader = ''; $ret = array('post_url' => z_root() . '/photos/' . App::$data['channel']['channel_address'], @@ -656,7 +669,8 @@ class Photos extends Controller /* Show space usage */ - $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", + $r = q( + "select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", intval(App::$data['channel']['channel_account_id']) ); @@ -732,7 +746,6 @@ class Photos extends Controller '$submit' => t('Upload') )); - } // @@ -744,7 +757,6 @@ class Photos extends Controller */ if ($datatype === 'album') { - head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', @@ -759,14 +771,16 @@ class Photos extends Controller goaway(z_root() . '/photos/' . App::$data['channel']['channel_address']); } - if ($_GET['order'] === 'posted') + if ($_GET['order'] === 'posted') { $order = 'created ASC'; - elseif ($_GET['order'] === 'name') + } elseif ($_GET['order'] === 'name') { $order = 'filename ASC'; - else + } else { $order = 'created DESC'; + } - $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN + $r = q( + "SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN (SELECT resource_id, max(imgscale) imgscale FROM photo left join attach on folder = '%s' and photo.resource_id = attach.hash WHERE attach.uid = %d AND imgscale <= 4 AND photo_usage IN ( %d, %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id) ph ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale) ORDER BY $order LIMIT %d OFFSET %d", @@ -789,18 +803,17 @@ class Photos extends Controller // @fixme - syncronise actions with DAV - // $edit_tpl = get_markup_template('album_edit.tpl'); - // $album_edit = replace_macros($edit_tpl,array( - // '$nametext' => t('Enter a new album name'), - // '$name_placeholder' => t('or select an existing one (doubleclick)'), - // '$nickname' => App::$data['channel']['channel_address'], - // '$album' => $album_e, - // '$albums' => $albums['albums'], - // '$hexalbum' => bin2hex($album), - // '$submit' => t('Submit'), - // '$dropsubmit' => t('Delete Album') - // )); - + // $edit_tpl = get_markup_template('album_edit.tpl'); + // $album_edit = replace_macros($edit_tpl,array( + // '$nametext' => t('Enter a new album name'), + // '$name_placeholder' => t('or select an existing one (doubleclick)'), + // '$nickname' => App::$data['channel']['channel_address'], + // '$album' => $album_e, + // '$albums' => $albums['albums'], + // '$hexalbum' => bin2hex($album), + // '$submit' => t('Submit'), + // '$dropsubmit' => t('Delete Album') + // )); } $order = [ @@ -814,11 +827,11 @@ class Photos extends Controller if (count($r)) { $twist = 'rotright'; foreach ($r as $rr) { - - if ($twist == 'rotright') + if ($twist == 'rotright') { $twist = 'rotleft'; - else + } else { $twist = 'rotright'; + } $ext = $phototypes[$rr['mimetype']]; @@ -881,7 +894,6 @@ class Photos extends Controller */ if ($datatype === 'image') { - head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', @@ -889,31 +901,34 @@ class Photos extends Controller 'title' => 'oembed' ]); - $x = q("select folder from attach where hash = '%s' and uid = %d $sql_attach limit 1", + $x = q( + "select folder from attach where hash = '%s' and uid = %d $sql_attach limit 1", dbesc($datum), intval($owner_uid) ); // fetch image, item containing image, then comments - $ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,description,album,filename,mimetype,height,width,filesize,imgscale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM photo WHERE uid = %d AND resource_id = '%s' + $ph = q( + "SELECT id,aid,uid,xchan,resource_id,created,edited,title,description,album,filename,mimetype,height,width,filesize,imgscale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM photo WHERE uid = %d AND resource_id = '%s' $sql_extra ORDER BY imgscale ASC ", intval($owner_uid), dbesc($datum) ); if (!($ph && $x)) { - /* Check again - this time without specifying permissions */ - $ph = q("SELECT id FROM photo WHERE uid = %d AND resource_id = '%s' LIMIT 1", + $ph = q( + "SELECT id FROM photo WHERE uid = %d AND resource_id = '%s' LIMIT 1", intval($owner_uid), dbesc($datum) ); - if ($ph) + if ($ph) { notice(t('Permission denied. Access to this item may be restricted.') . EOL); - else + } else { notice(t('Photo not available') . EOL); + } return; } @@ -921,15 +936,17 @@ class Photos extends Controller $prevlink = ''; $nextlink = ''; - if ($_GET['order'] === 'posted') + if ($_GET['order'] === 'posted') { $order = 'created ASC'; - elseif ($_GET['order'] === 'name') + } elseif ($_GET['order'] === 'name') { $order = 'filename ASC'; - else + } else { $order = 'created DESC'; + } - $prvnxt = q("SELECT hash FROM attach WHERE folder = '%s' AND uid = %d AND is_photo = 1 + $prvnxt = q( + "SELECT hash FROM attach WHERE folder = '%s' AND uid = %d AND is_photo = 1 $sql_attach ORDER BY $order ", dbesc($x[0]['folder']), intval($owner_uid) @@ -940,10 +957,12 @@ class Photos extends Controller if ($prvnxt[$z]['hash'] == $ph[0]['resource_id']) { $prv = $z - 1; $nxt = $z + 1; - if ($prv < 0) + if ($prv < 0) { $prv = count($prvnxt) - 1; - if ($nxt >= count($prvnxt)) + } + if ($nxt >= count($prvnxt)) { $nxt = 0; + } break; } } @@ -953,8 +972,9 @@ class Photos extends Controller } - if (count($ph) == 1) + if (count($ph) == 1) { $hires = $lores = $ph[0]; + } if (count($ph) > 1) { if ($ph[1]['imgscale'] == 2) { // original is 640 or less, we can display it directly @@ -966,8 +986,8 @@ class Photos extends Controller } $album_link = z_root() . '/photos/' . App::$data['channel']['channel_address'] . '/album/' . $x[0]['folder']; - $tools = Null; - $lock = Null; + $tools = null; + $lock = null; if ($can_post && ($ph[0]['uid'] == $owner_uid)) { $tools = array( @@ -980,17 +1000,20 @@ class Photos extends Controller $lockstate = (((strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid']))) ? array('lock', t('Private Photo')) - : array('unlock', Null)); + : array('unlock', null)); App::$page['htmlhead'] .= ''; - if ($prevlink) + if ($prevlink) { $prevlink = array($prevlink, t('Previous')); + } $photo = array( 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['imgscale'] . '.' . $phototypes[$hires['mimetype']], @@ -998,13 +1021,15 @@ class Photos extends Controller 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['imgscale'] . '.' . $phototypes[$lores['mimetype']] . '?f=&_u=' . datetime_convert('', '', '', 'ymdhis') ); - if ($nextlink) + if ($nextlink) { $nextlink = array($nextlink, t('Next')); + } // Do we have an item for this photo? - $linked_items = q("SELECT * FROM item WHERE resource_id = '%s' and resource_type = 'photo' and uid = %d + $linked_items = q( + "SELECT * FROM item WHERE resource_id = '%s' and resource_type = 'photo' and uid = %d $sql_item LIMIT 1", dbesc($datum), intval($owner_uid) @@ -1014,18 +1039,17 @@ class Photos extends Controller $link_item = null; if ($linked_items) { - xchan_query($linked_items); $linked_items = fetch_post_tags($linked_items, true); $link_item = $linked_items[0]; $item_normal = item_normal(); - $r = q("select * from item where parent_mid = '%s' + $r = q( + "select * from item where parent_mid = '%s' $item_normal and uid = %d $sql_item ", dbesc($link_item['mid']), intval($link_item['uid']) - ); if ($r) { @@ -1048,7 +1072,8 @@ class Photos extends Controller } if ((local_channel()) && (local_channel() == $link_item['uid'])) { - q("UPDATE item SET item_unseen = 0 WHERE parent = %d and uid = %d and item_unseen = 1", + q( + "UPDATE item SET item_unseen = 0 WHERE parent = %d and uid = %d and item_unseen = 1", intval($link_item['parent']), intval(local_channel()) ); @@ -1059,7 +1084,7 @@ class Photos extends Controller } } - // logger('mod_photo: link_item' . print_r($link_item,true)); + // logger('mod_photo: link_item' . print_r($link_item,true)); // FIXME - remove this when we move to conversation module @@ -1067,7 +1092,6 @@ class Photos extends Controller $edit = null; if ($can_post) { - $album_e = $ph[0]['album']; $caption_e = $ph[0]['description']; $aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, PermissionDescription::fromGlobalPermission('view_storage')) : ''); @@ -1112,7 +1136,6 @@ class Photos extends Controller } if (count($linked_items)) { - $cmnt_tpl = get_markup_template('comment_item.tpl'); $tpl = get_markup_template('photo_item.tpl'); $return_url = App::$cmd; @@ -1188,7 +1211,6 @@ class Photos extends Controller ]; if ($r) { - foreach ($r as $item) { builtin_activity_puller($item, $conv_responses); } @@ -1237,8 +1259,9 @@ class Photos extends Controller $drop = ''; - if ($observer['xchan_hash'] === $item['author_xchan'] || $observer['xchan_hash'] === $item['owner_xchan']) + if ($observer['xchan_hash'] === $item['author_xchan'] || $observer['xchan_hash'] === $item['owner_xchan']) { $drop = replace_macros(get_markup_template('photo_drop.tpl'), array('$id' => $item['id'], '$delete' => t('Delete'))); + } $name_e = $profile_name; @@ -1260,7 +1283,6 @@ class Photos extends Controller '$drop' => $drop, '$comment' => $comment )); - } if ($observer && ($can_post || $can_comment)) { @@ -1279,7 +1301,6 @@ class Photos extends Controller '$ww' => '' )); } - } $paginate = paginate($a); } @@ -1346,7 +1367,8 @@ class Photos extends Controller App::set_pager_itemspage(60); - $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created, p.display_path FROM photo p + $r = q( + "SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created, p.display_path FROM photo p INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo WHERE photo.uid = %d AND photo_usage IN ( %d, %d ) AND is_nsfw = %d $sql_extra group by resource_id ) ph ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale) ORDER by p.created DESC LIMIT %d OFFSET %d", @@ -1362,14 +1384,15 @@ class Photos extends Controller if ($r) { $twist = 'rotright'; foreach ($r as $rr) { - - if (!attach_can_view_folder(App::$data['channel']['channel_id'], get_observer_hash(), $rr['resource_id'])) + if (!attach_can_view_folder(App::$data['channel']['channel_id'], get_observer_hash(), $rr['resource_id'])) { continue; + } - if ($twist == 'rotright') + if ($twist == 'rotright') { $twist = 'rotleft'; - else + } else { $twist = 'rotright'; + } $ext = $phototypes[$rr['mimetype']]; $alt_e = $rr['filename']; @@ -1399,7 +1422,6 @@ class Photos extends Controller echo $o; killme(); } else { - $o .= ""; $o .= replace_macros(get_markup_template('photos_recent.tpl'), [ diff --git a/Zotlabs/Module/Pin.php b/Zotlabs/Module/Pin.php index a98b9aaec..547882cf6 100644 --- a/Zotlabs/Module/Pin.php +++ b/Zotlabs/Module/Pin.php @@ -1,4 +1,5 @@ '%s' $seenstr @@ -179,10 +185,10 @@ class Ping extends Controller } if ((argc() > 1) && (argv(1) === 'pubs') && ($notify_pubs)) { - $local_result = []; - $r = q("SELECT * FROM item + $r = q( + "SELECT * FROM item WHERE uid = %d AND author_xchan != '%s' AND created > '%s' @@ -226,7 +232,8 @@ class Ping extends Controller if (x($_REQUEST, 'markRead') && local_channel() && (!$_SESSION['sudo'])) { switch ($_REQUEST['markRead']) { case 'stream': - $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1", + $r = q( + "UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1", intval(local_channel()) ); $_SESSION['loadtime_stream'] = datetime_convert(); @@ -235,26 +242,28 @@ class Ping extends Controller PConfig::Set(local_channel(), 'system', 'loadtime_channel', $_SESSION['loadtime_channel']); break; case 'home': - $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1 AND item_wall = 1", + $r = q( + "UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1 AND item_wall = 1", intval(local_channel()) ); $_SESSION['loadtime_channel'] = datetime_convert(); PConfig::Set(local_channel(), 'system', 'loadtime_channel', $_SESSION['loadtime_channel']); break; case 'all_events': - $r = q("UPDATE event SET dismissed = 1 WHERE uid = %d AND dismissed = 0 AND dtstart < '%s' AND dtstart > '%s' ", + $r = q( + "UPDATE event SET dismissed = 1 WHERE uid = %d AND dismissed = 0 AND dtstart < '%s' AND dtstart > '%s' ", intval(local_channel()), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) ); break; case 'notify': - $r = q("update notify set seen = 1 where uid = %d", + $r = q( + "update notify set seen = 1 where uid = %d", intval(local_channel()) ); break; case 'pubs': - $_SESSION['loadtime_pubstream'] = datetime_convert(); PConfig::Set(local_channel(), 'system', 'loadtime_pubstream', $_SESSION['loadtime_pubstream']); break; @@ -264,7 +273,8 @@ class Ping extends Controller } if (x($_REQUEST, 'markItemRead') && local_channel() && (!$_SESSION['sudo'])) { - $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND parent = %d", + $r = q( + "UPDATE item SET item_unseen = 0 WHERE uid = %d AND parent = %d", intval(local_channel()), intval($_REQUEST['markItemRead']) ); @@ -282,8 +292,8 @@ class Ping extends Controller */ if (argc() > 1 && argv(1) === 'notify') { - - $t = q("SELECT * FROM notify WHERE uid = %d AND seen = 0 ORDER BY CREATED DESC", + $t = q( + "SELECT * FROM notify WHERE uid = %d AND seen = 0 ORDER BY CREATED DESC", intval(local_channel()) ); @@ -291,8 +301,9 @@ class Ping extends Controller foreach ($t as $tt) { $message = trim(strip_tags(bbcode($tt['msg']))); - if (strpos($message, $tt['xname']) === 0) + if (strpos($message, $tt['xname']) === 0) { $message = substr($message, strlen($tt['xname']) + 1); + } $mid = basename($tt['link']); @@ -300,7 +311,8 @@ class Ping extends Controller if (in_array($tt['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) { // we need the thread parent - $r = q("select thr_parent from item where mid = '%s' and uid = %d limit 1", + $r = q( + "select thr_parent from item where mid = '%s' and uid = %d limit 1", dbesc($mid), intval(local_channel()) ); @@ -333,7 +345,8 @@ class Ping extends Controller $item_normal_moderate = $item_normal; $loadtime = get_loadtime('stream'); - $r = q("SELECT * FROM item + $r = q( + "SELECT * FROM item WHERE uid = %d AND author_xchan != '%s' AND changed > '%s' @@ -369,7 +382,8 @@ class Ping extends Controller $loadtime = get_loadtime('channel'); - $r = q("SELECT * FROM item + $r = q( + "SELECT * FROM item WHERE uid = %d AND author_xchan != '%s' AND changed > '%s' @@ -400,7 +414,8 @@ class Ping extends Controller if (argc() > 1 && (argv(1) === 'intros')) { $local_result = []; - $r = q("SELECT * FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ORDER BY abook_created DESC LIMIT 50", + $r = q( + "SELECT * FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ORDER BY abook_created DESC LIMIT 50", intval(local_channel()) ); @@ -425,7 +440,8 @@ class Ping extends Controller if ((argc() > 1 && (argv(1) === 'register')) && is_site_admin()) { $result = []; - $r = q("SELECT account_email, account_created from account where (account_flags & %d) > 0", + $r = q( + "SELECT account_email, account_created from account where (account_flags & %d) > 0", intval(ACCOUNT_PENDING) ); if ($r) { @@ -451,7 +467,8 @@ class Ping extends Controller $result = []; - $r = q("SELECT * FROM event left join xchan on event_xchan = xchan_hash + $r = q( + "SELECT * FROM event left join xchan on event_xchan = xchan_hash WHERE event.uid = %d AND dtstart < '%s' AND dtstart > '%s' and dismissed = 0 and etype in ( 'event', 'birthday' ) ORDER BY dtstart DESC LIMIT 1000", @@ -462,7 +479,6 @@ class Ping extends Controller if ($r) { foreach ($r as $rr) { - $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart']); $today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false); $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); @@ -486,7 +502,8 @@ class Ping extends Controller if (argc() > 1 && (argv(1) === 'files')) { $result = []; - $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item + $r = q( + "SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item LEFT JOIN xchan on author_xchan = xchan_hash WHERE item.verb = '%s' AND item.obj_type = '%s' @@ -517,10 +534,10 @@ class Ping extends Controller } if (argc() > 1 && (argv(1) === 'reports') && is_site_admin()) { - $local_result = []; - $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item + $r = q( + "SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item LEFT JOIN xchan on author_xchan = xchan_hash WHERE item.type = '%s' AND item.item_unseen = 1", dbesc(ITEM_TYPE_REPORT) @@ -551,15 +568,18 @@ class Ping extends Controller if ($vnotify & VNOTIFY_SYSTEM) { - $t = q("select count(*) as total from notify where uid = %d and seen = 0", + $t = q( + "select count(*) as total from notify where uid = %d and seen = 0", intval(local_channel()) ); - if ($t) + if ($t) { $result['notify'] = intval($t[0]['total']); + } } if ($vnotify & VNOTIFY_FILES) { - $files = q("SELECT count(id) as total FROM item + $files = q( + "SELECT count(id) as total FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d @@ -570,14 +590,16 @@ class Ping extends Controller intval(local_channel()), dbesc($ob_hash) ); - if ($files) + if ($files) { $result['files'] = intval($files[0]['total']); + } } if ($vnotify & VNOTIFY_NETWORK) { $loadtime = get_loadtime('stream'); - $r = q("SELECT id, author_xchan FROM item + $r = q( + "SELECT id, author_xchan FROM item WHERE uid = %d and changed > '%s' $seenstr $item_normal @@ -605,7 +627,8 @@ class Ping extends Controller if ($vnotify & VNOTIFY_CHANNEL) { $loadtime = get_loadtime('channel'); - $r = q("SELECT id, author_xchan FROM item + $r = q( + "SELECT id, author_xchan FROM item WHERE item_wall = 1 and uid = %d and changed > '%s' $seenstr $item_normal @@ -630,12 +653,14 @@ class Ping extends Controller if ($vnotify & VNOTIFY_INTRO) { - $intr = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", + $intr = q( + "SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", intval(local_channel()) ); - if ($intr) + if ($intr) { $result['intros'] = intval($intr[0]['total']); + } } @@ -643,26 +668,31 @@ class Ping extends Controller if ($vnotify & VNOTIFY_REGISTER) { if (App::$config['system']['register_policy'] == REGISTER_APPROVE && is_site_admin()) { - $regs = q("SELECT count(account_id) as total from account where (account_flags & %d) > 0", + $regs = q( + "SELECT count(account_id) as total from account where (account_flags & %d) > 0", intval(ACCOUNT_PENDING) ); - if ($regs) + if ($regs) { $result['register'] = intval($regs[0]['total']); + } } } if ($vnotify & VNOTIFY_REPORTS) { if (is_site_admin()) { - $reps = q("SELECT count(id) as total from item where item_type = %d", + $reps = q( + "SELECT count(id) as total from item where item_type = %d", intval(ITEM_TYPE_REPORT) ); - if ($reps) + if ($reps) { $result['reports'] = intval($reps[0]['total']); + } } } if ($vnotify & (VNOTIFY_EVENT | VNOTIFY_EVENTTODAY | VNOTIFY_BIRTHDAY)) { - $events = q("SELECT etype, dtstart, adjust FROM event + $events = q( + "SELECT etype, dtstart, adjust FROM event WHERE event.uid = %d AND dtstart < '%s' AND dtstart > '%s' and dismissed = 0 and etype in ( 'event', 'birthday' ) ORDER BY dtstart ASC ", @@ -686,29 +716,32 @@ class Ping extends Controller } if (datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['dtstart'], 'Y-m-d') === $str_now) { $result['all_events_today']++; - if ($bd) + if ($bd) { $result['birthdays_today']++; - else + } else { $result['events_today']++; + } } } } } } - if (!($vnotify & VNOTIFY_EVENT)) + if (!($vnotify & VNOTIFY_EVENT)) { $result['all_events'] = $result['events'] = 0; - if (!($vnotify & VNOTIFY_EVENTTODAY)) + } + if (!($vnotify & VNOTIFY_EVENTTODAY)) { $result['all_events_today'] = $result['events_today'] = 0; - if (!($vnotify & VNOTIFY_BIRTHDAY)) + } + if (!($vnotify & VNOTIFY_BIRTHDAY)) { $result['birthdays'] = 0; + } if ($vnotify & VNOTIFY_FORUMS) { $forums = get_forum_channels(local_channel()); if ($forums) { - $perms_sql = item_permissions_sql(local_channel()) . item_normal(); $fcount = count($forums); $forums['total'] = 0; @@ -720,7 +753,8 @@ class Ping extends Controller $p = ids_to_querystr($p, 'parent'); $pquery = (($p) ? "OR parent IN ( $p )" : ''); - $r = q("select sum(item_unseen) as unseen from item + $r = q( + "select sum(item_unseen) as unseen from item where uid = %d and ( owner_xchan = '%s' $pquery ) and item_unseen = 1 $perms_sql ", intval(local_channel()), dbesc($forums[$x]['xchan_hash']) @@ -742,7 +776,6 @@ class Ping extends Controller unset($forums[$x]['xchan_name']); unset($forums[$x]['xchan_url']); unset($forums[$x]['xchan_photo_s']); - } else { unset($forums[$x]); } @@ -771,5 +804,4 @@ class Ping extends Controller json_return_and_die($result); } - } diff --git a/Zotlabs/Module/Plike.php b/Zotlabs/Module/Plike.php index d5022f718..016cb9e2b 100644 --- a/Zotlabs/Module/Plike.php +++ b/Zotlabs/Module/Plike.php @@ -1,4 +1,5 @@ 'Like', - 'dislike' => 'Dislike', - ]; + $acts = [ + 'like' => 'Like', + 'dislike' => 'Dislike', + ]; - // unlike (etc.) reactions are an undo of positive reactions, rather than a negative action. - // The activity is the same in undo actions and will have the same activity mapping + // unlike (etc.) reactions are an undo of positive reactions, rather than a negative action. + // The activity is the same in undo actions and will have the same activity mapping - if(substr($reaction,0,2) === 'un') { - $undo = true; - $reaction = substr($reaction,2); - } + if (substr($reaction, 0, 2) === 'un') { + $undo = true; + $reaction = substr($reaction, 2); + } - if(array_key_exists($reaction,$acts)) { - return (($undo) ? 'Undo/' : EMPTY_STR) . $acts[$reaction]; - } + if (array_key_exists($reaction, $acts)) { + return (($undo) ? 'Undo/' : EMPTY_STR) . $acts[$reaction]; + } - return EMPTY_STR; - - } + return EMPTY_STR; + } - public function get() { + public function get() + { - $undo = false; - $object = $target = null; - $owner_uid = 0; - $post_type = EMPTY_STR; - $objtype = EMPTY_STR; - $allow_cid = $allow_gid = $deny_cid = $deny_gid = ''; - $output = EMPTY_STR; + $undo = false; + $object = $target = null; + $owner_uid = 0; + $post_type = EMPTY_STR; + $objtype = EMPTY_STR; + $allow_cid = $allow_gid = $deny_cid = $deny_gid = ''; + $output = EMPTY_STR; - $sys_channel = get_sys_channel(); - $sys_channel_id = (($sys_channel) ? $sys_channel['channel_id'] : 0); + $sys_channel = get_sys_channel(); + $sys_channel_id = (($sys_channel) ? $sys_channel['channel_id'] : 0); - $observer = App::get_observer(); - - $verb = ((array_key_exists('verb', $_GET)) ? notags(trim($_GET['verb'])) : EMPTY_STR); + $observer = App::get_observer(); - // Figure out what action we're performing - - $activity = $this->reaction_to_activity($verb); + $verb = ((array_key_exists('verb', $_GET)) ? notags(trim($_GET['verb'])) : EMPTY_STR); - if (! $activity) { - return EMPTY_STR; - } + // Figure out what action we're performing - // Check for negative (undo) condition - // eg: 'Undo/Like' results in $undo conditional and $activity set to 'Like' - - $test = explode('/', $activity); - if (count($test) > 1) { - $undo = true; - $activity = $test[1]; - } + $activity = $this->reaction_to_activity($verb); - $is_rsvp = in_array($activity, [ 'Accept', 'Reject', 'TentativeAccept' ]); + if (! $activity) { + return EMPTY_STR; + } - // Check for when target is something besides messages, where argv(1) is the type of thing - // and argv(2) is an identifier of things of that type - // We currently only recognise 'profile' but other types could be handled - - if (argc() == 3) { - - if (! $observer) { - killme(); - } - - if($obj_type == 'profile') { - $r = q("select * from profile where profile_guid = '%s' limit 1", - dbesc($obj_id) - ); + // Check for negative (undo) condition + // eg: 'Undo/Like' results in $undo conditional and $activity set to 'Like' - if (! $r) { - killme(); - } - - $profile = array_shift($r); - - $owner_uid = $profile['uid']; + $test = explode('/', $activity); + if (count($test) > 1) { + $undo = true; + $activity = $test[1]; + } - $public = ((intval($profile['is_default'] )) ? true : false); + $is_rsvp = in_array($activity, [ 'Accept', 'Reject', 'TentativeAccept' ]); - // if this is a private profile, select the destination recipients - - if (! $public) { - $d = q("select abook_xchan from abook where abook_profile = '%s' and abook_channel = %d", - dbesc($profile['profile_guid']), - intval($owner_uid) - ); - if (! $d) { - // No profile could be found. - killme(); - } - - // $d now contains a list of those who can see this profile. - // Set the access accordingly. - - foreach ($d as $dd) { - $allow_cid .= '<' . $dd['abook_xchan'] . '>'; - } - } - - $post_type = t('channel'); - $objtype = ACTIVITY_OBJ_PROFILE; - - } + // Check for when target is something besides messages, where argv(1) is the type of thing + // and argv(2) is an identifier of things of that type + // We currently only recognise 'profile' but other types could be handled - // We'll need the owner of the thing from up above to figure out what channel is the target + if (argc() == 3) { + if (! $observer) { + killme(); + } - if (! ($owner_uid)) { - killme(); - } - - // Check permissions of the observer. If this is the owner (mostly this is the case) - // this will return true for all permissions. - - $perms = get_all_perms($owner_uid,$observer['xchan_hash']); - - if (! ($perms['post_like'] && $perms['view_profile'])) { - killme(); - } + if ($obj_type == 'profile') { + $r = q( + "select * from profile where profile_guid = '%s' limit 1", + dbesc($obj_id) + ); - $channel = channelx_by_n($owner_uid); - - if (! $channel) { - killme(); - } - - $object = json_encode(Activity::fetch_profile([ 'id' => channel_url($channel) ])); + if (! $r) { + killme(); + } - // second like of the same thing is "undo" for the first like - - $z = q("select * from likes where channel_id = %d and liker = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' limit 1", - intval($channel['channel_id']), - dbesc($observer['xchan_hash']), - dbesc($activity), - dbesc(($tgttype)?$tgttype:$objtype), - dbesc($obj_id) - ); - - if($z) { - $z[0]['deleted'] = 1; - Libsync::build_sync_packet($channel['channel_id'],array('likes' => $z)); - - q("delete from likes where id = %d", - intval($z[0]['id']) - ); - 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($channel['channel_id']) - ); - if($r) - drop_item($r[0]['id'],false); + $profile = array_shift($r); - } - killme(); - } - } + $owner_uid = $profile['uid']; - $uuid = new_uuid(); - - $arr = []; + $public = ((intval($profile['is_default'])) ? true : false); - $arr['uuid'] = $uuid; + // if this is a private profile, select the destination recipients + + if (! $public) { + $d = q( + "select abook_xchan from abook where abook_profile = '%s' and abook_channel = %d", + dbesc($profile['profile_guid']), + intval($owner_uid) + ); + if (! $d) { + // No profile could be found. + killme(); + } + + // $d now contains a list of those who can see this profile. + // Set the access accordingly. + + foreach ($d as $dd) { + $allow_cid .= '<' . $dd['abook_xchan'] . '>'; + } + } + + $post_type = t('channel'); + $objtype = ACTIVITY_OBJ_PROFILE; + } + + // We'll need the owner of the thing from up above to figure out what channel is the target + + if (! ($owner_uid)) { + killme(); + } + + // Check permissions of the observer. If this is the owner (mostly this is the case) + // this will return true for all permissions. + + $perms = get_all_perms($owner_uid, $observer['xchan_hash']); + + if (! ($perms['post_like'] && $perms['view_profile'])) { + killme(); + } + + $channel = channelx_by_n($owner_uid); + + if (! $channel) { + killme(); + } + + $object = json_encode(Activity::fetch_profile([ 'id' => channel_url($channel) ])); + + // second like of the same thing is "undo" for the first like + + $z = q( + "select * from likes where channel_id = %d and liker = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' limit 1", + intval($channel['channel_id']), + dbesc($observer['xchan_hash']), + dbesc($activity), + dbesc(($tgttype) ? $tgttype : $objtype), + dbesc($obj_id) + ); + + if ($z) { + $z[0]['deleted'] = 1; + Libsync::build_sync_packet($channel['channel_id'], array('likes' => $z)); + + q( + "delete from likes where id = %d", + intval($z[0]['id']) + ); + 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($channel['channel_id']) + ); + if ($r) { + drop_item($r[0]['id'], false); + } + } + killme(); + } + } + + $uuid = new_uuid(); + + $arr = []; + + $arr['uuid'] = $uuid; $arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/' ) . $uuid; - - $arr['item_thread_top'] = 1; - $arr['item_origin'] = 1; - $arr['item_wall'] = 1; - - if($verb === 'like') - $bodyverb = t('%1$s likes %2$s\'s %3$s'); - if($verb === 'dislike') - $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - - if (! isset($bodyverb)) { - killme(); - } + $arr['item_thread_top'] = 1; + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; - $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]'; - $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; - $plink = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . $post_type . '[/zrl]'; - $private = (($public) ? 0 : 1); + if ($verb === 'like') { + $bodyverb = t('%1$s likes %2$s\'s %3$s'); + } + if ($verb === 'dislike') { + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); + } - - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $owner_uid; + if (! isset($bodyverb)) { + killme(); + } - $arr['item_flags'] = $item['item_flags']; - $arr['item_wall'] = $item['item_wall']; - $arr['parent_mid'] = $arr['mid']; - $arr['owner_xchan'] = $channel['xchan_hash']; - $arr['author_xchan'] = $observer['xchan_hash']; - - - $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); + $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . $post_type . '[/zrl]'; + $private = (($public) ? 0 : 1); - if($obj_type === 'profile') { - if($public) { - $arr['body'] .= "\n\n" . '[embed]' . z_root() . '/profile/' . $channel['channel_address'] . '[/embed]'; - } - else - $arr['body'] .= "\n\n[zmg=80x80]" . $profile['thumb'] . '[/zmg]'; - } - - - $arr['verb'] = $activity; - $arr['obj_type'] = $objtype; - $arr['obj'] = $object; - - if ($target) { - $arr['tgt_type'] = $tgttype; - $arr['target'] = $target; - } - - $arr['allow_cid'] = $allow_cid; - $arr['allow_gid'] = $allow_gid; - $arr['deny_cid'] = $deny_cid; - $arr['deny_gid'] = $deny_gid; - $arr['item_private'] = $private; - - call_hooks('post_local',$arr); - - $post = item_store($arr); - $post_id = $post['item_id']; - // save the conversation from expiration + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $owner_uid; - if(local_channel() && array_key_exists('item',$post) && (intval($post['item']['id']) != intval($post['item']['parent']))) - retain_item($post['item']['parent']); - - $arr['id'] = $post_id; - - call_hooks('post_local_end', $arr); - - $r = q("select * from item where id = %d", - intval($post_id) - ); - if($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); - } - $r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", - intval($channel['channel_id']), - dbesc($observer['xchan_hash']), - dbesc($channel['channel_hash']), - intval($post_id), - dbesc($mid), - dbesc($activity), - dbesc(($tgttype)? $tgttype : $objtype), - 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($channel['channel_hash']), - dbesc($mid), - dbesc($activity), - dbesc(($tgttype)? $tgttype : $objtype), - dbesc($obj_id) - ); - if ($r) { - Libsync::build_sync_packet($channel['channel_id'],array('likes' => $r)); - } - - Run::Summon( [ 'Notifier', 'like', $post_id ] ); - - killme(); - } - - - + $arr['item_flags'] = $item['item_flags']; + $arr['item_wall'] = $item['item_wall']; + $arr['parent_mid'] = $arr['mid']; + $arr['owner_xchan'] = $channel['xchan_hash']; + $arr['author_xchan'] = $observer['xchan_hash']; + + + $arr['body'] = sprintf($bodyverb, $alink, $ulink, $plink); + + if ($obj_type === 'profile') { + if ($public) { + $arr['body'] .= "\n\n" . '[embed]' . z_root() . '/profile/' . $channel['channel_address'] . '[/embed]'; + } else { + $arr['body'] .= "\n\n[zmg=80x80]" . $profile['thumb'] . '[/zmg]'; + } + } + + + $arr['verb'] = $activity; + $arr['obj_type'] = $objtype; + $arr['obj'] = $object; + + if ($target) { + $arr['tgt_type'] = $tgttype; + $arr['target'] = $target; + } + + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; + + call_hooks('post_local', $arr); + + $post = item_store($arr); + $post_id = $post['item_id']; + + // save the conversation from expiration + + if (local_channel() && array_key_exists('item', $post) && (intval($post['item']['id']) != intval($post['item']['parent']))) { + retain_item($post['item']['parent']); + } + + $arr['id'] = $post_id; + + call_hooks('post_local_end', $arr); + + $r = q( + "select * from item where id = %d", + intval($post_id) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); + } + + $r = q( + "insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", + intval($channel['channel_id']), + dbesc($observer['xchan_hash']), + dbesc($channel['channel_hash']), + intval($post_id), + dbesc($mid), + dbesc($activity), + dbesc(($tgttype) ? $tgttype : $objtype), + 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($channel['channel_hash']), + dbesc($mid), + dbesc($activity), + dbesc(($tgttype) ? $tgttype : $objtype), + dbesc($obj_id) + ); + if ($r) { + Libsync::build_sync_packet($channel['channel_id'], array('likes' => $r)); + } + + Run::Summon([ 'Notifier', 'like', $post_id ]); + + killme(); + } } diff --git a/Zotlabs/Module/Poco.php b/Zotlabs/Module/Poco.php index 69b0cd39a..505e5c0ba 100644 --- a/Zotlabs/Module/Poco.php +++ b/Zotlabs/Module/Poco.php @@ -1,10 +1,11 @@ 1) + if (argc() > 1) { $which = argv(1); - else { + } else { notice(t('Requested profile is not available.') . EOL); App::$error = 404; return; @@ -38,12 +38,14 @@ class Profile extends Controller if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; $profile = argv(1); - $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", + $r = q( + "select profile_guid from profile where id = %d and uid = %d limit 1", intval($profile), intval(local_channel()) ); - if (!$r) + if (!$r) { $profile = ''; + } $profile = $r[0]['profile_guid']; } @@ -63,7 +65,8 @@ class Profile extends Controller if (!$profile) { - $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", + $x = q( + "select channel_id as profile_uid from channel where channel_address = '%s' limit 1", dbesc(argv(1)) ); if ($x) { @@ -74,8 +77,9 @@ class Profile extends Controller if (ActivityStreams::is_as_request()) { $chan = channelx_by_nick(argv(1)); - if (!$chan) + if (!$chan) { http_status_exit(404, 'Not found'); + } $p = Activity::encode_person($chan, true, ((get_config('system', 'activitypub', ACTIVITYPUB_ENABLED)) ? true : false)); if (!$p) { http_status_exit(404, 'Not found'); @@ -85,7 +89,6 @@ class Profile extends Controller } Libprofile::load($which, $profile); - } public function get() @@ -131,7 +134,5 @@ class Profile extends Controller $o .= Libprofile::advanced(); call_hooks('profile_advanced', $o); return $o; - } - } diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 44ca8e6d2..4b06c3b19 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -1,4 +1,5 @@ is_valid()) { - $im->cropImage(300, $srcX, $srcY, $srcW, $srcH); $aid = get_account_id(); @@ -143,7 +142,8 @@ class Profile_photo extends Controller if ($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice(t('Image resize failed.') . EOL); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", + $x = q( + "delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", dbesc($base_image['resource_id']), local_channel(), intval(PHOTO_RES_PROFILE_300), @@ -158,15 +158,16 @@ class Profile_photo extends Controller // If setting for the default profile, unset the profile photo flag from any other photos I own if ($is_default_profile) { - - $r = q("update profile set photo = '%s', thumb = '%s' where is_default = 1 and uid = %d", + $r = q( + "update profile set photo = '%s', thumb = '%s' where is_default = 1 and uid = %d", dbesc(z_root() . '/photo/profile/l/' . local_channel()), dbesc(z_root() . '/photo/profile/m/' . local_channel()), intval(local_channel()) ); - $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d + $r = q( + "UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), @@ -176,9 +177,9 @@ class Profile_photo extends Controller send_profile_photo_activity($channel, $base_image, $profile); - } else { - $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", + $r = q( + "update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-4'), dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-5'), intval($_REQUEST['profile']), @@ -197,7 +198,8 @@ class Profile_photo extends Controller // changed to a generic URL by a clone operation. Otherwise the new photo may // not get pushed to other sites correctly. - $r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' + $r = q( + "UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'", dbesc($im->getType()), dbesc(datetime_convert()), @@ -221,7 +223,6 @@ class Profile_photo extends Controller // Update directory in background Run::Summon(['Directory', $channel['channel_id']]); - } else { notice(t('Unable to process image') . EOL); } @@ -243,7 +244,6 @@ class Profile_photo extends Controller $hash = $_REQUEST['importfile']; $importing = true; } else { - $matches = []; $partial = false; @@ -292,7 +292,8 @@ class Profile_photo extends Controller } if (($res && intval($res['data']['is_photo'])) || $importing) { - $i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale", + $i = q( + "select * from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($hash), intval(local_channel()) ); @@ -362,7 +363,8 @@ class Profile_photo extends Controller $pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0); - $c = q("select id, is_default from profile where uid = %d", + $c = q( + "select id, is_default from profile where uid = %d", intval(local_channel()) ); @@ -375,7 +377,8 @@ class Profile_photo extends Controller $_REQUEST['profile'] = $pf; } - $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", + $r = q( + "SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", intval(local_channel()), dbesc($resource_id) ); @@ -394,19 +397,22 @@ class Profile_photo extends Controller if ($havescale) { // unset any existing profile photos - $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", + $r = q( + "UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval(local_channel()) ); - $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", + $r = q( + "UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", intval(PHOTO_PROFILE), intval(local_channel()), dbesc($resource_id) ); - $r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", + $r = q( + "UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($channel['xchan_hash']) ); @@ -422,10 +428,10 @@ class Profile_photo extends Controller goaway(z_root() . '/profiles'); } - $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q( + "SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel()) - ); if (!$r) { notice(t('Photo not available.') . EOL); @@ -442,7 +448,8 @@ class Profile_photo extends Controller $smallest = 0; if ($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale", + $i = q( + "select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($r[0]['resource_id']), intval(local_channel()) ); @@ -464,12 +471,12 @@ class Profile_photo extends Controller } // falls through with App::$data['imagecrop'] set so we go straight to the cropping section - } // present an upload form - $profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc", + $profiles = q( + "select id, profile_name as name, is_default from profile where uid = %d order by id asc", intval(local_channel()) ); @@ -488,7 +495,6 @@ class Profile_photo extends Controller $importing = ((array_key_exists('importfile', App::$data)) ? true : false); if (!array_key_exists('imagecrop', App::$data)) { - $tpl = get_markup_template('profile_photo.tpl'); $o .= replace_macros($tpl, [ @@ -519,7 +525,6 @@ class Profile_photo extends Controller call_hooks('profile_photo_content_end', $o); return $o; } else { - // present a cropping form $filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution']; diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 232f7c0bf..d8de21e9b 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -1,4 +1,5 @@ 2) && (argv(1) === "drop") && intval(argv(2))) { - $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", + $r = q( + "SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", intval(argv(2)), intval(local_channel()) ); @@ -37,17 +38,20 @@ class Profiles extends Controller // move every contact using this profile as their default to the user default - $r = q("UPDATE abook SET abook_profile = (SELECT profile_guid FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1) WHERE abook_profile = '%s' AND abook_channel = %d ", + $r = q( + "UPDATE abook SET abook_profile = (SELECT profile_guid FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1) WHERE abook_profile = '%s' AND abook_channel = %d ", intval(local_channel()), dbesc($profile_guid), intval(local_channel()) ); - $r = q("DELETE FROM profile WHERE id = %d AND uid = %d", + $r = q( + "DELETE FROM profile WHERE id = %d AND uid = %d", intval(argv(2)), intval(local_channel()) ); - if ($r) + if ($r) { info(t('Profile deleted.') . EOL); + } // @fixme this is a much more complicated sync - add any changed abook entries and // also add deleted flag to profile structure @@ -61,17 +65,20 @@ class Profiles extends Controller if ((argc() > 1) && (argv(1) === 'new')) { + // check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't'); - // check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't'); - - $r0 = q("SELECT id FROM profile WHERE uid = %d", - intval(local_channel())); + $r0 = q( + "SELECT id FROM profile WHERE uid = %d", + intval(local_channel()) + ); $num_profiles = count($r0); $name = t('Profile-') . ($num_profiles + 1); - $r1 = q("SELECT fullname, photo, thumb FROM profile WHERE uid = %d AND is_default = 1 LIMIT 1", - intval(local_channel())); + $r1 = q( + "SELECT fullname, photo, thumb FROM profile WHERE uid = %d AND is_default = 1 LIMIT 1", + intval(local_channel()) + ); $r2 = profile_store_lowlevel( [ @@ -85,28 +92,32 @@ class Profiles extends Controller ] ); - $r3 = q("SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1", + $r3 = q( + "SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1", intval(local_channel()), dbesc($name) ); info(t('New profile created.') . EOL); - if (count($r3) == 1) + if (count($r3) == 1) { goaway(z_root() . '/profiles/' . $r3[0]['id']); + } goaway(z_root() . '/profiles'); } if ((argc() > 2) && (argv(1) === 'clone')) { - check_form_security_token_redirectOnErr('/profiles', 'profile_clone', 't'); - $r0 = q("SELECT id FROM profile WHERE uid = %d", - intval(local_channel())); + $r0 = q( + "SELECT id FROM profile WHERE uid = %d", + intval(local_channel()) + ); $num_profiles = count($r0); $name = t('Profile-') . ($num_profiles + 1); - $r1 = q("SELECT * FROM profile WHERE uid = %d AND id = %d LIMIT 1", + $r1 = q( + "SELECT * FROM profile WHERE uid = %d AND id = %d LIMIT 1", intval(local_channel()), intval(argv(2)) ); @@ -123,7 +134,8 @@ class Profiles extends Controller create_table_from_array('profile', $r1[0]); - $r3 = q("SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1", + $r3 = q( + "SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1", intval(local_channel()), dbesc($name) ); @@ -131,8 +143,9 @@ class Profiles extends Controller profiles_build_sync(local_channel()); - if (($r3) && (count($r3) == 1)) + if (($r3) && (count($r3) == 1)) { goaway(z_root() . '/profiles/' . $r3[0]['id']); + } goaway(z_root() . '/profiles'); @@ -140,8 +153,8 @@ class Profiles extends Controller } if ((argc() > 2) && (argv(1) === 'export')) { - - $r1 = q("SELECT * FROM profile WHERE uid = %d AND id = %d LIMIT 1", + $r1 = q( + "SELECT * FROM profile WHERE uid = %d AND id = %d LIMIT 1", intval(local_channel()), intval(argv(2)) ); @@ -165,16 +178,19 @@ class Profiles extends Controller } if (((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(), 'multi_profiles')) { - if (feature_enabled(local_channel(), 'multi_profiles')) + if (feature_enabled(local_channel(), 'multi_profiles')) { $id = argv(1); - else { - $x = q("select id from profile where uid = %d and is_default = 1", + } else { + $x = q( + "select id from profile where uid = %d and is_default = 1", intval(local_channel()) ); - if ($x) + if ($x) { $id = $x[0]['id']; + } } - $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", intval($id), intval(local_channel()) ); @@ -229,7 +245,8 @@ class Profiles extends Controller if ((argc() > 1) && (argv(1) !== "new") && intval(argv(1))) { - $orig = q("SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", + $orig = q( + "SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", intval(argv(1)), intval(local_channel()) ); @@ -252,10 +269,11 @@ class Profiles extends Controller $dob = $_POST['dob'] ? escape_tags(trim($_POST['dob'])) : '0000-00-00'; $y = substr($dob, 0, 4); - if ((!ctype_digit($y)) || ($y < 1900)) + if ((!ctype_digit($y)) || ($y < 1900)) { $ignore_year = true; - else + } else { $ignore_year = false; + } if ($dob !== '0000-00-00') { if (strpos($dob, '0000-') === 0) { @@ -263,8 +281,9 @@ class Profiles extends Controller $dob = substr($dob, 5); } $dob = datetime_convert('UTC', 'UTC', (($ignore_year) ? '1900-' . $dob : $dob), (($ignore_year) ? 'm-d' : 'Y-m-d')); - if ($ignore_year) + if ($ignore_year) { $dob = '0000-' . $dob; + } } $name = escape_tags(trim($_POST['name'])); @@ -370,10 +389,11 @@ class Profiles extends Controller $with = ((x($_POST, 'with')) ? escape_tags(trim($_POST['with'])) : ''); - if (!strlen($howlong)) + if (!strlen($howlong)) { $howlong = NULL_DATE; - else + } else { $howlong = datetime_convert(date_default_timezone_get(), 'UTC', $howlong); + } // linkify the relationship target if applicable @@ -384,17 +404,20 @@ class Profiles extends Controller $withchanged = true; $prf = ''; $lookup = $with; - if (strpos($lookup, '@') === 0) + if (strpos($lookup, '@') === 0) { $lookup = substr($lookup, 1); + } $lookup = str_replace('_', ' ', $lookup); $newname = $lookup; - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", dbesc($newname), intval(local_channel()) ); if (!$r) { - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_addr = '%s' AND abook_channel = %d LIMIT 1", + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_addr = '%s' AND abook_channel = %d LIMIT 1", dbesc($lookup . '@%'), intval(local_channel()) ); @@ -407,37 +430,43 @@ class Profiles extends Controller if ($prf) { $with = str_replace($lookup, '' . $newname . '', $with); - if (strpos($with, '@') === 0) + if (strpos($with, '@') === 0) { $with = substr($with, 1); + } } - } else + } else { $with = $orig[0]['partner']; + } } $profile_fields_basic = get_profile_fields_basic(); $profile_fields_advanced = get_profile_fields_advanced(); $advanced = ((feature_enabled(local_channel(), 'advanced_profiles')) ? true : false); - if ($advanced) + if ($advanced) { $fields = $profile_fields_advanced; - else + } else { $fields = $profile_fields_basic; + } $z = q("select * from profdef where true"); if ($z) { foreach ($z as $zz) { if (array_key_exists($zz['field_name'], $fields)) { - $w = q("select * from profext where channel_id = %d and hash = '%s' and k = '%s' limit 1", + $w = q( + "select * from profext where channel_id = %d and hash = '%s' and k = '%s' limit 1", intval(local_channel()), dbesc($orig[0]['profile_guid']), dbesc($zz['field_name']) ); if ($w) { - q("update profext set v = '%s' where id = %d", + q( + "update profext set v = '%s' where id = %d", dbesc(escape_tags(trim($_POST[$zz['field_name']]))), intval($w[0]['id']) ); } else { - q("insert into profext ( channel_id, hash, k, v ) values ( %d, '%s', '%s', '%s') ", + q( + "insert into profext ( channel_id, hash, k, v ) values ( %d, '%s', '%s', '%s') ", intval(local_channel()), dbesc($orig[0]['profile_guid']), dbesc($zz['field_name']), @@ -500,8 +529,10 @@ class Profiles extends Controller // in case this leaks to unintended recipients. Yes, it's in the public // profile but that doesn't mean we have to broadcast it to everybody. } - if ($locality != $orig[0]['locality'] || $region != $orig[0]['region'] - || $country_name != $orig[0]['country_name']) { + if ( + $locality != $orig[0]['locality'] || $region != $orig[0]['region'] + || $country_name != $orig[0]['country_name'] + ) { $changes[] = t('Location'); $comma1 = ((($locality) && ($region || $country_name)) ? ', ' : ' '); $comma2 = (($region && $country_name) ? ', ' : ''); @@ -509,10 +540,10 @@ class Profiles extends Controller } self::profile_activity($changes, $value); - } - $r = q("UPDATE profile + $r = q( + "UPDATE profile SET profile_name = '%s', fullname = '%s', pdesc = '%s', @@ -588,10 +619,12 @@ class Profiles extends Controller intval(local_channel()) ); - if ($r) + if ($r) { info(t('Profile updated.') . EOL); + } - $sync = q("select * from profile where id = %d and uid = %d limit 1", + $sync = q( + "select * from profile where id = %d and uid = %d limit 1", intval(argv(1)), intval(local_channel()) ); @@ -606,12 +639,14 @@ class Profiles extends Controller $channel = App::get_channel(); if ($namechanged && $is_default) { - $r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'", + $r = q( + "UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'", dbesc($name), dbesc(datetime_convert()), dbesc($channel['xchan_hash']) ); - $r = q("UPDATE channel SET channel_name = '%s' WHERE channel_hash = '%s'", + $r = q( + "UPDATE channel SET channel_name = '%s' WHERE channel_hash = '%s'", dbesc($name), dbesc($channel['xchan_hash']) ); @@ -646,16 +681,19 @@ class Profiles extends Controller $profile_fields_advanced = get_profile_fields_advanced(); if (((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(), 'multi_profiles')) { - if (feature_enabled(local_channel(), 'multi_profiles')) + if (feature_enabled(local_channel(), 'multi_profiles')) { $id = argv(1); - else { - $x = q("select id from profile where uid = %d and is_default = 1", + } else { + $x = q( + "select id from profile where uid = %d and is_default = 1", intval(local_channel()) ); - if ($x) + if ($x) { $id = $x[0]['id']; + } } - $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", + $r = q( + "SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1", intval($id), intval(local_channel()) ); @@ -672,10 +710,11 @@ class Profiles extends Controller )); $advanced = ((feature_enabled(local_channel(), 'advanced_profiles')) ? true : false); - if ($advanced) + if ($advanced) { $fields = $profile_fields_advanced; - else + } else { $fields = $profile_fields_basic; + } $hide_friends = array( 'hide_friends', @@ -690,7 +729,8 @@ class Profiles extends Controller $extra_fields = []; foreach ($q as $qq) { - $mine = q("select v from profext where k = '%s' and hash = '%s' and channel_id = %d limit 1", + $mine = q( + "select v from profext where k = '%s' and hash = '%s' and channel_id = %d limit 1", dbesc($qq['field_name']), dbesc($r[0]['profile_guid']), intval(local_channel()) @@ -709,8 +749,9 @@ class Profiles extends Controller $vcard = (($vctmp) ? get_vcard_array($vctmp, $r[0]['id']) : []); $f = get_config('system', 'birthday_input_format'); - if (!$f) + if (!$f) { $f = 'ymd'; + } $is_default = (($r[0]['is_default']) ? 1 : 0); @@ -814,11 +855,11 @@ class Profiles extends Controller return $o; } else { - - $r = q("SELECT * FROM profile WHERE uid = %d", - local_channel()); + $r = q( + "SELECT * FROM profile WHERE uid = %d", + local_channel() + ); if ($r) { - $tpl = get_markup_template('profile_entry.tpl'); foreach ($r as $rr) { $profiles .= replace_macros($tpl, array( @@ -839,26 +880,27 @@ class Profiles extends Controller '$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new"), '$profiles' => $profiles )); - } return $o; } - } public static function profile_activity($changed, $value) { - if (!local_channel() || !is_array($changed) || !count($changed)) + if (!local_channel() || !is_array($changed) || !count($changed)) { return; + } - if (!get_pconfig(local_channel(), 'system', 'post_profilechange')) + if (!get_pconfig(local_channel(), 'system', 'post_profilechange')) { return; + } $self = App::get_channel(); - if (!$self) + if (!$self) { return; + } $arr = []; $uuid = new_uuid(); @@ -886,10 +928,11 @@ class Profiles extends Controller $z = 0; foreach ($changed as $ch) { if (strlen($changes)) { - if ($z == ($t - 1)) + if ($z == ($t - 1)) { $changes .= t(' and '); - else + } else { $changes .= t(', '); + } } $z++; $changes .= $ch; @@ -901,8 +944,9 @@ class Profiles extends Controller // if it's a url, the HTML quotes will mess it up, so link it and don't try and zidify it because we don't know what it points to. $value = preg_replace_callback("/([^\]\='" . '"' . "]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ismu", 'red_zrl_callback', $value); // take out the bookmark indicator - if (substr($value, 0, 2) === '#^') + if (substr($value, 0, 2) === '#^') { $value = str_replace('#^', '', $value); + } $message = sprintf(t('%1$s changed %2$s to “%3$s”'), $A, $changes, $value); $message .= "\n\n" . sprintf(t('Visit %1$s\'s %2$s'), $A, $prof); @@ -933,7 +977,6 @@ class Profiles extends Controller // FIXME - limit delivery in notifier.php to those specificed in the perms argument Run::Summon(['Notifier', 'activity', $i, 'PERMS_R_PROFILE']); } - } public static function gender_selector($current = "", $suffix = "") @@ -995,8 +1038,9 @@ class Profiles extends Controller { $o = ''; - if (!get_config('system', 'profile_gender_textfield')) + if (!get_config('system', 'profile_gender_textfield')) { return $o; + } $o .= ""; return $o; @@ -1077,6 +1121,4 @@ class Profiles extends Controller $o .= ''; return $o; } - - } diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php index 0d539655e..d4f1dc8d1 100644 --- a/Zotlabs/Module/Profperm.php +++ b/Zotlabs/Module/Profperm.php @@ -1,6 +1,6 @@ 2) && intval(argv(1)) && intval(argv(2))) { - $r = q("SELECT abook_id FROM abook WHERE abook_id = %d and abook_channel = %d limit 1", + $r = q( + "SELECT abook_id FROM abook WHERE abook_id = %d and abook_channel = %d limit 1", intval(argv(2)), intval(local_channel()) ); - if ($r) + if ($r) { $change = intval(argv(2)); + } } if ((argc() > 1) && (intval(argv(1)))) { - $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", + $r = q( + "SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", intval(argv(1)), intval(local_channel()) ); @@ -73,34 +78,39 @@ class Profperm extends Controller $profile = $r[0]; - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", intval(local_channel()), dbesc($profile['profile_guid']) ); $ingroup = []; - if ($r) - foreach ($r as $member) + if ($r) { + foreach ($r as $member) { $ingroup[] = $member['abook_id']; + } + } $members = $r; if ($change) { if (in_array($change, $ingroup)) { - q("UPDATE abook SET abook_profile = '' WHERE abook_id = %d AND abook_channel = %d", + q( + "UPDATE abook SET abook_profile = '' WHERE abook_id = %d AND abook_channel = %d", intval($change), intval(local_channel()) ); } else { - q("UPDATE abook SET abook_profile = '%s' WHERE abook_id = %d AND abook_channel = %d", + q( + "UPDATE abook SET abook_profile = '%s' WHERE abook_id = %d AND abook_channel = %d", dbesc($profile['profile_guid']), intval($change), intval(local_channel()) ); - } - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", intval(local_channel()), dbesc($profile['profile_guid']) @@ -109,9 +119,11 @@ class Profperm extends Controller $members = $r; $ingroup = []; - if (count($r)) - foreach ($r as $member) + if (count($r)) { + foreach ($r as $member) { $ingroup[] = $member['abook_id']; + } + } } $o .= '

' . t('Profile Visibility Editor') . '

'; @@ -119,12 +131,12 @@ class Profperm extends Controller $o .= '

' . t('Profile') . ' \'' . $profile['profile_name'] . '\'

'; $o .= '
' . t('Click on a contact to add or remove.') . '
'; - } $o .= '
'; - if ($change) + if ($change) { $o = ''; + } $o .= '
'; $o .= '

' . t('Visible To') . '

'; @@ -167,8 +179,5 @@ class Profperm extends Controller } $o .= '
'; return $o; - } - - } diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index 98f96504c..1cf8ba164 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -1,4 +1,5 @@ updating)) { - $channel = App::get_channel(); $channel_acl = array( @@ -92,7 +92,6 @@ class Pubstream extends Controller } if (!$this->updating && !$this->loading) { - nav_set_selected(t('Public Stream')); if (!$mid) { @@ -105,8 +104,9 @@ class Pubstream extends Controller $static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1); $maxheight = get_config('system', 'home_divmore_height'); - if (!$maxheight) + if (!$maxheight) { $maxheight = 400; + } $o .= '
' . "\r\n"; $o .= "'; - } - } + [ + 'rel' => 'zot', + 'type' => 'application/x-zot+json', + 'href' => z_root() . '/channel/' . argv(1) + ], + + [ + 'rel' => 'self', + 'type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + 'href' => z_root() . '/channel/' . argv(1) + ], + + [ + 'rel' => 'self', + 'type' => 'application/activity+json', + 'href' => z_root() . '/channel/' . argv(1) + ] + ]; + + $x = [ 'channel_address' => argv(1), 'channel_links' => App::$channel_links ]; + call_hooks('channel_links', $x); + App::$channel_links = $x['channel_links']; + header('Link: ' . App::get_channel_links()); + } + } + + private function set_homebase() + { + + // If you're just visiting, let javascript take you home + + if (x($_SESSION, 'visitor_home')) { + $homebase = $_SESSION['visitor_home']; + } elseif (local_channel()) { + $homebase = z_root() . '/channel/' . App::$channel['channel_address']; + } + + if (isset($homebase)) { + App::$page['content'] .= ''; + } + } } diff --git a/Zotlabs/Widget/Activity.php b/Zotlabs/Widget/Activity.php index 2a84312e0..78e5cd777 100644 --- a/Zotlabs/Widget/Activity.php +++ b/Zotlabs/Widget/Activity.php @@ -4,7 +4,6 @@ namespace Zotlabs\Widget; use Zotlabs\Lib\LibBlock; - class Activity { @@ -25,7 +24,8 @@ class Activity $perms_sql = item_permissions_sql(local_channel()) . item_normal(); - $r = q("select author_xchan from item where item_unseen = 1 and uid = %d $perms_sql", + $r = q( + "select author_xchan from item where item_unseen = 1 and uid = %d $perms_sql", intval(local_channel()) ); @@ -64,6 +64,4 @@ class Activity } return $o; } - -} - +} diff --git a/Zotlabs/Widget/Activity_filter.php b/Zotlabs/Widget/Activity_filter.php index 13403bd4d..194059c92 100644 --- a/Zotlabs/Widget/Activity_filter.php +++ b/Zotlabs/Widget/Activity_filter.php @@ -118,7 +118,8 @@ class Activity_filter ]; - $groups = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + $groups = q( + "SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval(local_channel()) ); @@ -211,7 +212,8 @@ class Activity_filter } if (feature_enabled(local_channel(), 'filing')) { - $terms = q("select distinct term from term where uid = %d and ttype = %d order by term asc", + $terms = q( + "select distinct term from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); @@ -270,20 +272,19 @@ class Activity_filter 'title' => t('Show followed hashtags'), 'sub' => $tsub ]; - } -// if(x($_GET,'search')) { -// $filter_active = 'search'; -// $tabs[] = [ -// 'label' => t('Search'), -// 'icon' => 'search', -// 'url' => z_root() . '/' . $cmd . '/?search=' . $_GET['search'], -// 'sel' => 'active disabled', -// 'title' => t('Panel search') -// ]; -// } +// if(x($_GET,'search')) { +// $filter_active = 'search'; +// $tabs[] = [ +// 'label' => t('Search'), +// 'icon' => 'search', +// 'url' => z_root() . '/' . $cmd . '/?search=' . $_GET['search'], +// 'sel' => 'active disabled', +// 'title' => t('Panel search') +// ]; +// } $name = []; if (isset($_GET['name']) && $_GET['name']) { @@ -328,7 +329,5 @@ class Activity_filter } return $o; - } - } diff --git a/Zotlabs/Widget/Admin.php b/Zotlabs/Widget/Admin.php index 50af3b2b5..2cb617ef2 100644 --- a/Zotlabs/Widget/Admin.php +++ b/Zotlabs/Widget/Admin.php @@ -24,16 +24,16 @@ class Admin $aside = [ 'site' => array(z_root() . '/admin/site/', t('Site'), 'site'), -// 'profile_photo' => array(z_root() . '/admin/profile_photo', t('Site icon/logo'), 'profile_photo'), -// 'cover_photo' => array(z_root() . '/admin/cover_photo', t('Site photo'), 'cover_photo'), +// 'profile_photo' => array(z_root() . '/admin/profile_photo', t('Site icon/logo'), 'profile_photo'), +// 'cover_photo' => array(z_root() . '/admin/cover_photo', t('Site photo'), 'cover_photo'), 'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')), 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'), 'security' => array(z_root() . '/admin/security/', t('Security'), 'security'), -// 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'), +// 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'), 'addons' => array(z_root() . '/admin/addons/', t('Addons'), 'addons'), '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 Fields'), 'profs'), +// 'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'), 'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync') ]; @@ -68,7 +68,5 @@ class Admin )); return $o; - } } - diff --git a/Zotlabs/Widget/Affinity.php b/Zotlabs/Widget/Affinity.php index 5dd7e4cc0..ecca26414 100644 --- a/Zotlabs/Widget/Affinity.php +++ b/Zotlabs/Widget/Affinity.php @@ -10,8 +10,9 @@ class Affinity public function widget($arr) { - if (!local_channel()) + if (!local_channel()) { return ''; + } $default_cmin = ((Apps::system_app_installed(local_channel(), 'Friend Zoom')) ? get_pconfig(local_channel(), 'affinity', 'cmin', 0) : 0); $default_cmax = ((Apps::system_app_installed(local_channel(), 'Friend Zoom')) ? get_pconfig(local_channel(), 'affinity', 'cmax', 99) : 99); @@ -21,7 +22,6 @@ class Affinity if (Apps::system_app_installed(local_channel(), 'Friend Zoom')) { - $labels = array( 0 => t('Me'), 20 => t('Family'), @@ -48,4 +48,3 @@ class Affinity return ''; } } - \ No newline at end of file diff --git a/Zotlabs/Widget/Album.php b/Zotlabs/Widget/Album.php index 653112a01..500cf601e 100644 --- a/Zotlabs/Widget/Album.php +++ b/Zotlabs/Widget/Album.php @@ -3,6 +3,7 @@ namespace Zotlabs\Widget; use App; + require_once('include/attach.php'); class Album @@ -33,20 +34,23 @@ class Album */ if ($album) { - $x = q("select hash from attach where filename = '%s' and uid = %d limit 1", + $x = q( + "select hash from attach where filename = '%s' and uid = %d limit 1", dbesc($album), intval($owner_uid) ); if ($x) { $y = attach_can_view_folder($owner_uid, get_observer_hash(), $x[0]['hash']); - if (!$y) + if (!$y) { return ''; + } } } $order = 'DESC'; - $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN + $r = q( + "SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale) ORDER BY created $order ", @@ -63,11 +67,11 @@ class Album if ($r) { $twist = 'rotright'; foreach ($r as $rr) { - - if ($twist == 'rotright') + if ($twist == 'rotright') { $twist = 'rotleft'; - else + } else { $twist = 'rotright'; + } $ext = $phototypes[$rr['mimetype']]; @@ -109,4 +113,3 @@ class Album return $o; } } - diff --git a/Zotlabs/Widget/Appcategories.php b/Zotlabs/Widget/Appcategories.php index 2ec9c00bc..2544ffd7f 100644 --- a/Zotlabs/Widget/Appcategories.php +++ b/Zotlabs/Widget/Appcategories.php @@ -8,8 +8,9 @@ class Appcategories public function widget($arr) { - if (!local_channel()) + if (!local_channel()) { return ''; + } $selected = ((x($_REQUEST, 'cat')) ? htmlspecialchars($_REQUEST['cat'], ENT_COMPAT, 'UTF-8') : ''); @@ -19,13 +20,15 @@ class Appcategories // Leaving this line which negates the effect of the two invalid lines prior $srchurl = z_root() . '/apps'; - if (argc() > 1 && argv(1) === 'available') + if (argc() > 1 && argv(1) === 'available') { $srchurl .= '/available'; + } $terms = []; - $r = q("select distinct(term.term) + $r = q( + "select distinct(term.term) from term join app on term.oid = app.id where app_channel = %d and term.uid = app_channel @@ -38,8 +41,9 @@ class Appcategories ); if ($r) { - foreach ($r as $rr) + foreach ($r as $rr) { $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); + } return replace_macros(get_markup_template('categories_widget.tpl'), array( '$title' => t('Categories'), diff --git a/Zotlabs/Widget/Appcloud.php b/Zotlabs/Widget/Appcloud.php index e927ea980..f3cbe74c2 100644 --- a/Zotlabs/Widget/Appcloud.php +++ b/Zotlabs/Widget/Appcloud.php @@ -7,9 +7,9 @@ class Appcloud public function widget($arr) { - if (!local_channel()) + if (!local_channel()) { return ''; + } return app_tagblock(z_root() . '/apps'); } } - diff --git a/Zotlabs/Widget/Appstore.php b/Zotlabs/Widget/Appstore.php index ee55889aa..18cdca009 100644 --- a/Zotlabs/Widget/Appstore.php +++ b/Zotlabs/Widget/Appstore.php @@ -2,7 +2,6 @@ namespace Zotlabs\Widget; - class Appstore { diff --git a/Zotlabs/Widget/Archive.php b/Zotlabs/Widget/Archive.php index c6b3f4687..a12cf1205 100644 --- a/Zotlabs/Widget/Archive.php +++ b/Zotlabs/Widget/Archive.php @@ -2,7 +2,6 @@ namespace Zotlabs\Widget; - use App; class Archive @@ -19,11 +18,13 @@ class Archive $uid = App::$profile_uid; - if (!feature_enabled($uid, 'archives')) + if (!feature_enabled($uid, 'archives')) { return ''; + } - if (!perm_is_allowed($uid, get_observer_hash(), 'view_stream')) + if (!perm_is_allowed($uid, get_observer_hash(), 'view_stream')) { return ''; + } $wall = ((array_key_exists('wall', $arr)) ? intval($arr['wall']) : 0); $wall = ((array_key_exists('articles', $arr)) ? 2 : $wall); @@ -37,8 +38,9 @@ class Archive $ret = list_post_dates($uid, $wall, $mindate); - if (!count($ret)) + if (!count($ret)) { return ''; + } $cutoff_year = intval(datetime_convert('', date_default_timezone_get(), 'now', 'Y')) - $visible_years; $cutoff = ((array_key_exists($cutoff_year, $ret)) ? true : false); @@ -56,4 +58,3 @@ class Archive return $o; } } - diff --git a/Zotlabs/Widget/Bookmarkedchats.php b/Zotlabs/Widget/Bookmarkedchats.php index 876727eea..2584a5e2a 100644 --- a/Zotlabs/Widget/Bookmarkedchats.php +++ b/Zotlabs/Widget/Bookmarkedchats.php @@ -10,13 +10,16 @@ class Bookmarkedchats public function widget($arr) { - if (!feature_enabled(App::$profile['profile_uid'], 'ajaxchat')) + if (!feature_enabled(App::$profile['profile_uid'], 'ajaxchat')) { return ''; + } $h = get_observer_hash(); - if (!$h) + if (!$h) { return; - $r = q("select xchat_url, xchat_desc from xchat where xchat_xchan = '%s' order by xchat_desc", + } + $r = q( + "select xchat_url, xchat_desc from xchat where xchat_xchan = '%s' order by xchat_desc", dbesc($h) ); if ($r) { diff --git a/Zotlabs/Widget/Catcloud.php b/Zotlabs/Widget/Catcloud.php index 05daf5330..4cab3218e 100644 --- a/Zotlabs/Widget/Catcloud.php +++ b/Zotlabs/Widget/Catcloud.php @@ -10,25 +10,25 @@ class Catcloud public function widget($arr) { - if ((!App::$profile['profile_uid']) || (!App::$profile['channel_hash'])) + if ((!App::$profile['profile_uid']) || (!App::$profile['channel_hash'])) { return ''; + } $limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 50); if (array_key_exists('type', $arr)) { switch ($arr['type']) { - case 'cards': - - if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_pages')) + if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_pages')) { return ''; + } return card_catblock(App::$profile['profile_uid'], $limit, '', App::$profile['channel_hash']); case 'articles': - - if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_articles')) + if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_articles')) { return ''; + } return article_catblock(App::$profile['profile_uid'], $limit, '', App::$profile['channel_hash']); @@ -39,12 +39,10 @@ class Catcloud } - if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) + if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) { return ''; + } return catblock(App::$profile['profile_uid'], $limit, '', App::$profile['channel_hash']); - - } - } diff --git a/Zotlabs/Widget/Catcloud_wall.php b/Zotlabs/Widget/Catcloud_wall.php index 32fe24ae8..4a1b9b50d 100644 --- a/Zotlabs/Widget/Catcloud_wall.php +++ b/Zotlabs/Widget/Catcloud_wall.php @@ -10,14 +10,15 @@ class Catcloud_wall public function widget($arr) { - if ((!App::$profile['profile_uid']) || (!App::$profile['channel_hash'])) + if ((!App::$profile['profile_uid']) || (!App::$profile['channel_hash'])) { return ''; - if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) + } + if (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) { return ''; + } $limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 50); return catblock(App::$profile['profile_uid'], $limit, '', App::$profile['channel_hash'], 'wall'); } - } diff --git a/Zotlabs/Widget/Categories.php b/Zotlabs/Widget/Categories.php index 86a24717f..cd26dba18 100644 --- a/Zotlabs/Widget/Categories.php +++ b/Zotlabs/Widget/Categories.php @@ -13,17 +13,21 @@ class Categories $cards = ((array_key_exists('cards', $arr) && $arr['cards']) ? true : false); - if (($cards) && (!Apps::system_app_installed(App::$profile['profile_uid'], 'Cards'))) + if (($cards) && (!Apps::system_app_installed(App::$profile['profile_uid'], 'Cards'))) { return ''; + } $articles = ((array_key_exists('articles', $arr) && $arr['articles']) ? true : false); - if (($articles) && (!Apps::addon_app_installed(App::$profile['profile_uid'], 'articles'))) + if (($articles) && (!Apps::addon_app_installed(App::$profile['profile_uid'], 'articles'))) { return ''; + } - if ((!App::$profile['profile_uid']) - || (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), (($cards || $articles) ? 'view_pages' : 'view_articles')))) { + if ( + (!App::$profile['profile_uid']) + || (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), (($cards || $articles) ? 'view_pages' : 'view_articles'))) + ) { return ''; } @@ -32,21 +36,22 @@ class Categories $srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is', '', $srchurl), '&'); $srchurl = str_replace(array('?f=', '&f='), array('', ''), $srchurl); - if ($cards) + if ($cards) { return self::cardcategories_widget($srchurl, $cat); - elseif ($articles) + } elseif ($articles) { return self::articlecategories_widget($srchurl, $cat); - else + } else { return self::categories_widget($srchurl, $cat); - + } } public static function articlecategories_widget($baseurl, $selected = '') { - if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) + if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) { return ''; + } $sql_extra = item_permissions_sql(App::$profile['profile_uid']); @@ -55,7 +60,8 @@ class Categories and item.item_blocked = 0 "; $terms = []; - $r = q("select distinct(term.term) + $r = q( + "select distinct(term.term) from term join item on term.oid = item.id where item.uid = %d and term.uid = item.uid @@ -71,8 +77,9 @@ class Categories dbesc(App::$profile['channel_hash']) ); if ($r && count($r)) { - foreach ($r as $rr) + foreach ($r as $rr) { $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); + } return replace_macros(get_markup_template('categories_widget.tpl'), array( '$title' => t('Categories'), @@ -90,8 +97,9 @@ class Categories public static function cardcategories_widget($baseurl, $selected = '') { - if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) + if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) { return ''; + } $sql_extra = item_permissions_sql(App::$profile['profile_uid']); @@ -100,7 +108,8 @@ class Categories and item.item_blocked = 0 "; $terms = []; - $r = q("select distinct(term.term) + $r = q( + "select distinct(term.term) from term join item on term.oid = item.id where item.uid = %d and term.uid = item.uid @@ -116,8 +125,9 @@ class Categories dbesc(App::$profile['channel_hash']) ); if ($r && count($r)) { - foreach ($r as $rr) + foreach ($r as $rr) { $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); + } return replace_macros(get_markup_template('categories_widget.tpl'), array( '$title' => t('Categories'), @@ -136,8 +146,9 @@ class Categories public static function categories_widget($baseurl, $selected = '') { - if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) + if (!Apps::system_app_installed(App::$profile['profile_uid'], 'Categories')) { return ''; + } require_once('include/security.php'); @@ -146,7 +157,8 @@ class Categories $item_normal = item_normal(); $terms = []; - $r = q("select distinct(term.term) from term join item on term.oid = item.id + $r = q( + "select distinct(term.term) from term join item on term.oid = item.id where item.uid = %d and term.uid = item.uid and term.ttype = %d @@ -164,8 +176,9 @@ class Categories dbesc(ACTIVITY_UPDATE) ); if ($r && count($r)) { - foreach ($r as $rr) + foreach ($r as $rr) { $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); + } return replace_macros(get_markup_template('categories_widget.tpl'), array( '$title' => t('Categories'), @@ -179,5 +192,4 @@ class Categories } return ''; } - } diff --git a/Zotlabs/Widget/Cdav.php b/Zotlabs/Widget/Cdav.php index 550dc140a..3be6e49ba 100644 --- a/Zotlabs/Widget/Cdav.php +++ b/Zotlabs/Widget/Cdav.php @@ -2,8 +2,6 @@ namespace Zotlabs\Widget; - - use App; use DBA; use Sabre\CardDAV\Backend\PDO; @@ -13,14 +11,16 @@ class Cdav public function widget() { - if (!local_channel()) + if (!local_channel()) { return; + } $channel = App::get_channel(); $principalUri = 'principals/' . $channel['channel_address']; - if (!cdav_principal($principalUri)) + if (!cdav_principal($principalUri)) { return; + } $pdo = DBA::$dba->db; @@ -29,13 +29,13 @@ class Cdav $o = ''; if (argc() <= 3 && argv(1) === 'calendar') { - $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $sabrecals = $caldavBackend->getCalendarsForUser($principalUri); //TODO: we should probably also check for permission to send stream here - $local_channels = q("SELECT * FROM channel LEFT JOIN abook ON abook_xchan = channel_hash WHERE channel_system = 0 AND channel_removed = 0 AND channel_hash != '%s' AND abook_channel = %d", + $local_channels = q( + "SELECT * FROM channel LEFT JOIN abook ON abook_xchan = channel_hash WHERE channel_system = 0 AND channel_removed = 0 AND channel_hash != '%s' AND abook_channel = %d", dbesc($channel['channel_hash']), intval($channel['channel_id']) ); @@ -50,12 +50,15 @@ class Cdav //list calendars foreach ($sabrecals as $sabrecal) { - if ($sabrecal['share-access'] == 1) + if ($sabrecal['share-access'] == 1) { $access = ''; - if ($sabrecal['share-access'] == 2) + } + if ($sabrecal['share-access'] == 2) { $access = 'read'; - if ($sabrecal['share-access'] == 3) + } + if ($sabrecal['share-access'] == 3) { $access = 'read-write'; + } $invites = $caldavBackend->getInvites($sabrecal['id']); @@ -153,11 +156,9 @@ class Cdav ]); return $o; - } if (argc() >= 2 && argv(1) === 'addressbook') { - $carddavBackend = new PDO($pdo); $sabreabooks = $carddavBackend->getAddressBooksForUser($principalUri); @@ -188,8 +189,6 @@ class Cdav ]); return $o; - } - } } diff --git a/Zotlabs/Widget/Chatroom_list.php b/Zotlabs/Widget/Chatroom_list.php index 8dbfd2f6b..425dc9488 100644 --- a/Zotlabs/Widget/Chatroom_list.php +++ b/Zotlabs/Widget/Chatroom_list.php @@ -11,8 +11,9 @@ class Chatroom_list public function widget($arr) { - if (!App::$profile) + if (!App::$profile) { return ''; + } $r = Chatroom::roomlist(App::$profile['profile_uid']); diff --git a/Zotlabs/Widget/Chatroom_members.php b/Zotlabs/Widget/Chatroom_members.php index 619c23b73..c9385831f 100644 --- a/Zotlabs/Widget/Chatroom_members.php +++ b/Zotlabs/Widget/Chatroom_members.php @@ -13,5 +13,4 @@ class Chatroom_members '$header' => t('Chat Members') )); } - } diff --git a/Zotlabs/Widget/Clock.php b/Zotlabs/Widget/Clock.php index 65b34d9cc..fd37c383f 100644 --- a/Zotlabs/Widget/Clock.php +++ b/Zotlabs/Widget/Clock.php @@ -60,4 +60,3 @@ EOT; return $o; } } - diff --git a/Zotlabs/Widget/Collections.php b/Zotlabs/Widget/Collections.php index 9a01c4cb9..3afe16d89 100644 --- a/Zotlabs/Widget/Collections.php +++ b/Zotlabs/Widget/Collections.php @@ -11,8 +11,8 @@ class Collections public function widget($args) { -// if(argc() < 2) -// return; +// if(argc() < 2) +// return; $mode = ((array_key_exists('mode', $args)) ? $args['mode'] : 'conversation'); diff --git a/Zotlabs/Widget/Common_friends.php b/Zotlabs/Widget/Common_friends.php index 383118524..d30f066d2 100644 --- a/Zotlabs/Widget/Common_friends.php +++ b/Zotlabs/Widget/Common_friends.php @@ -2,8 +2,6 @@ namespace Zotlabs\Widget; - - use App; class Common_friends @@ -12,32 +10,36 @@ class Common_friends public function widget($arr) { - if ((!App::$profile['profile_uid']) - || (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_contacts'))) { + if ( + (!App::$profile['profile_uid']) + || (!perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_contacts')) + ) { return ''; } return self::common_friends_visitor_widget(App::$profile['profile_uid']); - } public static function common_friends_visitor_widget($profile_uid, $cnt = 25) { - if (local_channel() == $profile_uid) + if (local_channel() == $profile_uid) { return; + } $observer_hash = get_observer_hash(); - if ((!$observer_hash) || (!perm_is_allowed($profile_uid, $observer_hash, 'view_contacts'))) + if ((!$observer_hash) || (!perm_is_allowed($profile_uid, $observer_hash, 'view_contacts'))) { return; + } require_once('include/socgraph.php'); $t = count_common_friends($profile_uid, $observer_hash); - if (!$t) + if (!$t) { return; + } $r = common_friends($profile_uid, $observer_hash, 0, $cnt, true); @@ -50,7 +52,5 @@ class Common_friends '$more' => sprintf(t('View all %d common connections'), $t), '$items' => $r )); - } - } diff --git a/Zotlabs/Widget/Cover_photo.php b/Zotlabs/Widget/Cover_photo.php index 6305ed28d..aa96da2a4 100644 --- a/Zotlabs/Widget/Cover_photo.php +++ b/Zotlabs/Widget/Cover_photo.php @@ -15,8 +15,9 @@ class Cover_photo $o = ''; - if (App::$module == 'channel' && $_REQUEST['mid']) + if (App::$module == 'channel' && $_REQUEST['mid']) { return ''; + } $channel_id = 0; @@ -28,12 +29,15 @@ class Cover_photo $site_banner = System::get_site_name(); } - if (array_key_exists('channel_id', $arr) && intval($arr['channel_id'])) + if (array_key_exists('channel_id', $arr) && intval($arr['channel_id'])) { $channel_id = intval($arr['channel_id']); - if (!$channel_id) + } + if (!$channel_id) { $channel_id = App::$profile_uid; - if (!$channel_id) + } + if (!$channel_id) { return ''; + } // only show cover photos once per login session $hide_cover = false; @@ -47,26 +51,30 @@ class Cover_photo $channel = channelx_by_n($channel_id); - if (array_key_exists('style', $arr) && isset($arr['style'])) + if (array_key_exists('style', $arr) && isset($arr['style'])) { $style = $arr['style']; - else + } else { $style = 'width:100%; height: auto;'; + } // ensure they can't sneak in an eval(js) function - if (strpbrk($style, '(\'"<>') !== false) + if (strpbrk($style, '(\'"<>') !== false) { $style = ''; + } - if (array_key_exists('title', $arr) && isset($arr['title'])) + if (array_key_exists('title', $arr) && isset($arr['title'])) { $title = $arr['title']; - else + } else { $title = $channel['channel_name']; + } - if (array_key_exists('subtitle', $arr) && isset($arr['subtitle'])) + if (array_key_exists('subtitle', $arr) && isset($arr['subtitle'])) { $subtitle = $arr['subtitle']; - else + } else { $subtitle = str_replace('@', '@', $channel['xchan_addr']); + } if ($site_banner) { diff --git a/Zotlabs/Widget/Design_tools.php b/Zotlabs/Widget/Design_tools.php index bc62db4db..399525d05 100644 --- a/Zotlabs/Widget/Design_tools.php +++ b/Zotlabs/Widget/Design_tools.php @@ -10,9 +10,10 @@ class Design_tools public function widget($arr) { - if (perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'write_pages') || (App::$is_sys && is_site_admin())) + if (perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'write_pages') || (App::$is_sys && is_site_admin())) { return design_tools(); + } return EMPTY_STR; } -} \ No newline at end of file +} diff --git a/Zotlabs/Widget/Dirtags.php b/Zotlabs/Widget/Dirtags.php index 93e9e6689..3dbc60e59 100644 --- a/Zotlabs/Widget/Dirtags.php +++ b/Zotlabs/Widget/Dirtags.php @@ -2,7 +2,6 @@ namespace Zotlabs\Widget; - class Dirtags { @@ -10,5 +9,4 @@ class Dirtags { return dir_tagblock(z_root() . '/directory', null); } - } diff --git a/Zotlabs/Widget/Eventstools.php b/Zotlabs/Widget/Eventstools.php index bde2bd8dd..b0623c596 100644 --- a/Zotlabs/Widget/Eventstools.php +++ b/Zotlabs/Widget/Eventstools.php @@ -8,8 +8,9 @@ class Eventstools public function widget($arr) { - if (!local_channel()) + if (!local_channel()) { return; + } return replace_macros(get_markup_template('events_tools_side.tpl'), array( '$title' => t('Events Tools'), diff --git a/Zotlabs/Widget/Filer.php b/Zotlabs/Widget/Filer.php index ebb72cee5..c1dbc3955 100644 --- a/Zotlabs/Widget/Filer.php +++ b/Zotlabs/Widget/Filer.php @@ -2,8 +2,6 @@ namespace Zotlabs\Widget; - - use App; class Filer @@ -11,22 +9,26 @@ class Filer public function widget($arr) { - if (!local_channel()) + if (!local_channel()) { return ''; + } $selected = ((x($_REQUEST, 'file')) ? $_REQUEST['file'] : ''); $terms = []; - $r = q("select distinct term from term where uid = %d and ttype = %d order by term asc", + $r = q( + "select distinct term from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); - if (!$r) + if (!$r) { return; + } - foreach ($r as $rr) + foreach ($r as $rr) { $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); + } return replace_macros(get_markup_template('fileas_widget.tpl'), array( '$title' => t('Saved Folders'), @@ -37,5 +39,4 @@ class Filer '$base' => z_root() . '/' . App::$cmd )); } - } diff --git a/Zotlabs/Widget/Findpeople.php b/Zotlabs/Widget/Findpeople.php index a0222ab70..95ef5870a 100644 --- a/Zotlabs/Widget/Findpeople.php +++ b/Zotlabs/Widget/Findpeople.php @@ -40,8 +40,5 @@ class Findpeople '$advanced_hint' => "\r\n" . t('Advanced example: name=fred and country=iceland'), '$loggedin' => local_channel() )); - } - } - diff --git a/Zotlabs/Widget/Follow.php b/Zotlabs/Widget/Follow.php index a389849fc..2b871f8c7 100644 --- a/Zotlabs/Widget/Follow.php +++ b/Zotlabs/Widget/Follow.php @@ -15,7 +15,8 @@ class Follow } $uid = App::$channel['channel_id']; - $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ", + $r = q( + "select count(*) as total from abook where abook_channel = %d and abook_self = 0 ", intval($uid) ); @@ -39,4 +40,3 @@ class Follow ]); } } - diff --git a/Zotlabs/Widget/Fullprofile.php b/Zotlabs/Widget/Fullprofile.php index d9e8fe7ff..c22729743 100644 --- a/Zotlabs/Widget/Fullprofile.php +++ b/Zotlabs/Widget/Fullprofile.php @@ -5,7 +5,6 @@ namespace Zotlabs\Widget; use App; use Zotlabs\Lib\Libprofile; - class Fullprofile { diff --git a/Zotlabs/Widget/Groups.php b/Zotlabs/Widget/Groups.php index b7e792f78..7f7d98c2c 100644 --- a/Zotlabs/Widget/Groups.php +++ b/Zotlabs/Widget/Groups.php @@ -30,14 +30,16 @@ class Groups $xf = false; - $x1 = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and not v like '%s'", + $x1 = q( + "select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and not v like '%s'", intval(local_channel()), dbesc('%send_stream%') ); if ($x1) { $xc = ids_to_querystr($x1, 'xchan', true); - $x2 = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s' and xchan in (" . $xc . ") ", + $x2 = q( + "select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s' and xchan in (" . $xc . ") ", intval(local_channel()), dbesc('%tag_deliver%') ); @@ -46,7 +48,8 @@ class Groups $xf = ids_to_querystr($x2, 'xchan', true); // private forums - $x3 = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s' and xchan in (" . $xc . ") and not xchan in (" . $xf . ") ", + $x3 = q( + "select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s' and xchan in (" . $xc . ") and not xchan in (" . $xf . ") ", intval(local_channel()), dbesc('%post_wall%') ); @@ -59,7 +62,8 @@ class Groups // note: XCHAN_TYPE_GROUP = 1 $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_type = 1 ) " : " and xchan_type = 1 "); - $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name $limit ", + $r1 = q( + "select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name $limit ", intval(local_channel()) ); @@ -73,7 +77,8 @@ class Groups // There also should be a way to update this via ajax. for ($x = 0; $x < count($r1); $x++) { - $r = q("select sum(item_unseen) as unseen from item + $r = q( + "select sum(item_unseen) as unseen from item where uid = %d and owner_xchan = '%s' and item_unseen = 1 $perms_sql ", intval(local_channel()), dbesc($r1[$x]['xchan_hash']) @@ -109,7 +114,6 @@ class Groups $output .= '

' . t('Groups') . '

'; $o .= '
'; return $o; - } } - diff --git a/Zotlabs/Widget/Vcard.php b/Zotlabs/Widget/Vcard.php index bf7bfc641..8d3f2083f 100644 --- a/Zotlabs/Widget/Vcard.php +++ b/Zotlabs/Widget/Vcard.php @@ -11,6 +11,4 @@ class Vcard { return vcard_from_xchan('', App::get_observer()); } - } - diff --git a/Zotlabs/Widget/Website_portation_tools.php b/Zotlabs/Widget/Website_portation_tools.php index dc97c7fcf..7c11a1f08 100644 --- a/Zotlabs/Widget/Website_portation_tools.php +++ b/Zotlabs/Widget/Website_portation_tools.php @@ -2,7 +2,6 @@ namespace Zotlabs\Widget; - use App; class Website_portation_tools @@ -14,12 +13,15 @@ class Website_portation_tools // mod menu doesn't load a profile. For any modules which load a profile, check it. // otherwise local_channel() is sufficient for permissions. - if (App::$profile['profile_uid']) - if ((App::$profile['profile_uid'] != local_channel()) && (!App::$is_sys)) + if (App::$profile['profile_uid']) { + if ((App::$profile['profile_uid'] != local_channel()) && (!App::$is_sys)) { return ''; + } + } - if (!local_channel()) + if (!local_channel()) { return ''; + } return website_portation_tools(); } diff --git a/Zotlabs/Zot6/IHandler.php b/Zotlabs/Zot6/IHandler.php index 69e115abb..6bbeae55b 100644 --- a/Zotlabs/Zot6/IHandler.php +++ b/Zotlabs/Zot6/IHandler.php @@ -12,6 +12,4 @@ interface IHandler public function Refresh($sender, $recipients, $hub, $force); public function Purge($sender, $recipients, $hub); - } - diff --git a/Zotlabs/Zot6/Receiver.php b/Zotlabs/Zot6/Receiver.php index 704139622..d1c2b5d97 100644 --- a/Zotlabs/Zot6/Receiver.php +++ b/Zotlabs/Zot6/Receiver.php @@ -58,7 +58,6 @@ class Receiver if ($this->rawdata) { $this->data = json_decode($this->rawdata, true); if (($this->data) && (!is_array($this->data)) && (substr($this->data, 0, 1) === "{")) { - // Multiple json encoding has been seen in the wild and needs to be fixed on the sending side. // Proceed anyway and log the event with a backtrace. @@ -184,7 +183,6 @@ class Receiver { switch ($this->messagetype) { - case 'purge': $this->response = $this->handler->Purge($this->sender, $this->recipients, $this->hub); break; @@ -210,7 +208,6 @@ class Receiver $this->response = $this->handler->Notify($this->data, $this->hub); } break; - } logger('response_to_return: ' . print_r($this->response, true), LOGGER_DATA); @@ -229,8 +226,4 @@ class Receiver $this->response = Crypto::encapsulate(json_encode($this->response), $this->hub['hubloc_sitekey'], $algorithm); } } - } - - - diff --git a/Zotlabs/Zot6/Zot6Handler.php b/Zotlabs/Zot6/Zot6Handler.php index 24b23a020..98dabcbba 100644 --- a/Zotlabs/Zot6/Zot6Handler.php +++ b/Zotlabs/Zot6/Zot6Handler.php @@ -68,11 +68,11 @@ class Zot6Handler implements IHandler $ret = array('success' => false); if ($recipients) { - // This would be a permissions update, typically for one connection foreach ($recipients as $recip) { - $r = q("select channel.*,xchan.* from channel + $r = q( + "select channel.*,xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_hash ='%s' limit 1", dbesc($recip) @@ -81,7 +81,6 @@ class Zot6Handler implements IHandler $x = Libzot::refresh(['hubloc_id_url' => $hub['hubloc_id_url']], $r[0], $force); } } else { - // system wide refresh $x = Libzot::refresh(['hubloc_id_url' => $hub['hubloc_id_url']], null, $force); } @@ -96,26 +95,29 @@ class Zot6Handler implements IHandler $ret = array('success' => false); - // newsig is newkey signed with oldkey + // newsig is newkey signed with oldkey // The original xchan will remain. In Zot/Receiver we will have imported the new xchan and hubloc to verify // the packet authenticity. What we will do now is verify that the keychange operation was signed by the // oldkey, and if so change all the abook, abconfig, group, and permission elements which reference the // old xchan_hash. - if ((!$data['old_key']) && (!$data['new_key']) && (!$data['new_sig'])) + if ((!$data['old_key']) && (!$data['new_key']) && (!$data['new_sig'])) { return $ret; + } $old = null; if (Libzot::verify($data['old_guid'], $data['old_guid_sig'], $data['old_key'])) { $oldhash = make_xchan_hash($data['old_guid'], $data['old_key']); - $old = q("select * from xchan where xchan_hash = '%s' limit 1", + $old = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($oldhash) ); - } else + } else { return $ret; + } if (!$old) { @@ -128,7 +130,8 @@ class Zot6Handler implements IHandler return $ret; } - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); @@ -166,13 +169,15 @@ class Zot6Handler implements IHandler if ($recipients) { // basically this means "unfriend" foreach ($recipients as $recip) { - $channel = q("select channel.*,xchan.* from channel + $channel = q( + "select channel.*,xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_hash = '%s' limit 1", dbesc($recip) ); if ($channel) { - $abook = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + $abook = q( + "select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1", intval($channel[0]['channel_id']), dbesc($sender) ); @@ -183,7 +188,6 @@ class Zot6Handler implements IHandler } $ret['success'] = true; } else { - // Unfriend everybody - basically this means the channel has committed suicide remove_all_xchan_resources($sender); @@ -193,5 +197,4 @@ class Zot6Handler implements IHandler return $ret; } - } diff --git a/include/account.php b/include/account.php index 4b093f025..a26e21de1 100644 --- a/include/account.php +++ b/include/account.php @@ -8,417 +8,429 @@ use Zotlabs\Lib\Crypto; use Zotlabs\Lib\System; -function get_account_by_id($account_id) { - $r = q("select * from account where account_id = %d", - intval($account_id) - ); - return (($r) ? array_shift($r) : false); +function get_account_by_id($account_id) +{ + $r = q( + "select * from account where account_id = %d", + intval($account_id) + ); + return (($r) ? array_shift($r) : false); } -function check_account_email($email) { +function check_account_email($email) +{ - $email = punify($email); - $result = [ 'error' => false, 'message' => '' ]; + $email = punify($email); + $result = [ 'error' => false, 'message' => '' ]; - // Caution: empty email isn't counted as an error in this function. - // Check for empty value separately. + // Caution: empty email isn't counted as an error in this function. + // Check for empty value separately. - if (! strlen($email)) { - return $result; - } + if (! strlen($email)) { + return $result; + } - if (! validate_email($email)) { - $result['message'] .= t('Not a valid email address') . EOL; - } - elseif (! allowed_email($email)) { - $result['message'] = t('Your email domain is not among those allowed on this site'); - } - else { - $r = q("select account_email from account where account_email = '%s' limit 1", - dbesc($email) - ); - if ($r) { - $result['message'] .= t('Your email address is already registered at this site.'); - } - } - if ($result['message']) { - $result['error'] = true; - } + if (! validate_email($email)) { + $result['message'] .= t('Not a valid email address') . EOL; + } elseif (! allowed_email($email)) { + $result['message'] = t('Your email domain is not among those allowed on this site'); + } else { + $r = q( + "select account_email from account where account_email = '%s' limit 1", + dbesc($email) + ); + if ($r) { + $result['message'] .= t('Your email address is already registered at this site.'); + } + } + if ($result['message']) { + $result['error'] = true; + } - $arr = array('email' => $email, 'result' => $result); - call_hooks('check_account_email', $arr); + $arr = array('email' => $email, 'result' => $result); + call_hooks('check_account_email', $arr); - return $arr['result']; + return $arr['result']; } -function check_account_password($password) { - $result = [ 'error' => false, 'message' => '' ]; +function check_account_password($password) +{ + $result = [ 'error' => false, 'message' => '' ]; - // The only validation we perform by default is pure Javascript to - // check minimum length and that both entered passwords match. - // Use hooked functions to perform complexity requirement checks. + // The only validation we perform by default is pure Javascript to + // check minimum length and that both entered passwords match. + // Use hooked functions to perform complexity requirement checks. - $arr = [ 'password' => $password, 'result' => $result ]; - call_hooks('check_account_password', $arr); + $arr = [ 'password' => $password, 'result' => $result ]; + call_hooks('check_account_password', $arr); - return $arr['result']; + return $arr['result']; } -function check_account_invite($invite_code) { - $result = [ 'error' => false, 'message' => '' ]; +function check_account_invite($invite_code) +{ + $result = [ 'error' => false, 'message' => '' ]; - $using_invites = get_config('system','invitation_only'); + $using_invites = get_config('system', 'invitation_only'); - if ($using_invites && defined('INVITE_WORKING')) { - if (! $invite_code) { - $result['message'] .= t('An invitation is required.') . EOL; - } - $r = q("select * from register where hash = '%s' limit 1", dbesc($invite_code)); - if (! $r) { - $result['message'] .= t('Invitation could not be verified.') . EOL; - } - } - if (strlen($result['message'])) { - $result['error'] = true; - } + if ($using_invites && defined('INVITE_WORKING')) { + if (! $invite_code) { + $result['message'] .= t('An invitation is required.') . EOL; + } + $r = q("select * from register where hash = '%s' limit 1", dbesc($invite_code)); + if (! $r) { + $result['message'] .= t('Invitation could not be verified.') . EOL; + } + } + if (strlen($result['message'])) { + $result['error'] = true; + } - $arr = [ 'invite_code' => $invite_code, 'result' => $result ]; - call_hooks('check_account_invite', $arr); + $arr = [ 'invite_code' => $invite_code, 'result' => $result ]; + call_hooks('check_account_invite', $arr); - return $arr['result']; + return $arr['result']; } -function check_account_admin($arr) { - if (is_site_admin()) { - return true; - } - $admin_email = trim(get_config('system','admin_email','')); - if (strlen($admin_email) && $admin_email === trim($arr['email'])) { - return true; - } - return false; +function check_account_admin($arr) +{ + if (is_site_admin()) { + return true; + } + $admin_email = trim(get_config('system', 'admin_email', '')); + if (strlen($admin_email) && $admin_email === trim($arr['email'])) { + return true; + } + return false; } -function account_total() { - $r = q("select account_id from account where true"); - // Distinguish between an empty array and an error - if (is_array($r)) { - return count($r); - } - return false; +function account_total() +{ + $r = q("select account_id from account where true"); + // Distinguish between an empty array and an error + if (is_array($r)) { + return count($r); + } + return false; } -function account_store_lowlevel($arr) { +function account_store_lowlevel($arr) +{ $store = [ - 'account_parent' => ((array_key_exists('account_parent',$arr)) ? $arr['account_parent'] : '0'), - 'account_default_channel' => ((array_key_exists('account_default_channel',$arr)) ? $arr['account_default_channel'] : '0'), - 'account_salt' => ((array_key_exists('account_salt',$arr)) ? $arr['account_salt'] : ''), - 'account_password' => ((array_key_exists('account_password',$arr)) ? $arr['account_password'] : ''), - 'account_email' => ((array_key_exists('account_email',$arr)) ? $arr['account_email'] : ''), - 'account_external' => ((array_key_exists('account_external',$arr)) ? $arr['account_external'] : ''), - 'account_language' => ((array_key_exists('account_language',$arr)) ? $arr['account_language'] : 'en'), - 'account_created' => ((array_key_exists('account_created',$arr)) ? $arr['account_created'] : '0001-01-01 00:00:00'), - 'account_lastlog' => ((array_key_exists('account_lastlog',$arr)) ? $arr['account_lastlog'] : '0001-01-01 00:00:00'), - 'account_flags' => ((array_key_exists('account_flags',$arr)) ? $arr['account_flags'] : '0'), - 'account_roles' => ((array_key_exists('account_roles',$arr)) ? $arr['account_roles'] : '0'), - 'account_reset' => ((array_key_exists('account_reset',$arr)) ? $arr['account_reset'] : ''), - 'account_expires' => ((array_key_exists('account_expires',$arr)) ? $arr['account_expires'] : '0001-01-01 00:00:00'), - 'account_expire_notified' => ((array_key_exists('account_expire_notified',$arr)) ? $arr['account_expire_notified'] : '0001-01-01 00:00:00'), - 'account_service_class' => ((array_key_exists('account_service_class',$arr)) ? $arr['account_service_class'] : ''), - 'account_level' => ((array_key_exists('account_level',$arr)) ? $arr['account_level'] : '0'), - 'account_password_changed' => ((array_key_exists('account_password_changed',$arr)) ? $arr['account_password_changed'] : '0001-01-01 00:00:00') - ]; - - return create_table_from_array('account',$store); + 'account_parent' => ((array_key_exists('account_parent', $arr)) ? $arr['account_parent'] : '0'), + 'account_default_channel' => ((array_key_exists('account_default_channel', $arr)) ? $arr['account_default_channel'] : '0'), + 'account_salt' => ((array_key_exists('account_salt', $arr)) ? $arr['account_salt'] : ''), + 'account_password' => ((array_key_exists('account_password', $arr)) ? $arr['account_password'] : ''), + 'account_email' => ((array_key_exists('account_email', $arr)) ? $arr['account_email'] : ''), + 'account_external' => ((array_key_exists('account_external', $arr)) ? $arr['account_external'] : ''), + 'account_language' => ((array_key_exists('account_language', $arr)) ? $arr['account_language'] : 'en'), + 'account_created' => ((array_key_exists('account_created', $arr)) ? $arr['account_created'] : '0001-01-01 00:00:00'), + 'account_lastlog' => ((array_key_exists('account_lastlog', $arr)) ? $arr['account_lastlog'] : '0001-01-01 00:00:00'), + 'account_flags' => ((array_key_exists('account_flags', $arr)) ? $arr['account_flags'] : '0'), + 'account_roles' => ((array_key_exists('account_roles', $arr)) ? $arr['account_roles'] : '0'), + 'account_reset' => ((array_key_exists('account_reset', $arr)) ? $arr['account_reset'] : ''), + 'account_expires' => ((array_key_exists('account_expires', $arr)) ? $arr['account_expires'] : '0001-01-01 00:00:00'), + 'account_expire_notified' => ((array_key_exists('account_expire_notified', $arr)) ? $arr['account_expire_notified'] : '0001-01-01 00:00:00'), + 'account_service_class' => ((array_key_exists('account_service_class', $arr)) ? $arr['account_service_class'] : ''), + 'account_level' => ((array_key_exists('account_level', $arr)) ? $arr['account_level'] : '0'), + 'account_password_changed' => ((array_key_exists('account_password_changed', $arr)) ? $arr['account_password_changed'] : '0001-01-01 00:00:00') + ]; + return create_table_from_array('account', $store); } -function create_account($arr) { +function create_account($arr) +{ - // Required: { email, password } + // Required: { email, password } - $result = [ 'success' => false, 'email' => '', 'password' => '', 'message' => '' ]; + $result = [ 'success' => false, 'email' => '', 'password' => '', 'message' => '' ]; - $invite_code = ((isset($arr['invite_code'])) ? notags(trim($arr['invite_code'])) : ''); - $email = ((isset($arr['email'])) ? notags(punify(trim($arr['email']))) : ''); - $password = ((isset($arr['password'])) ? trim($arr['password']) : ''); - $password2 = ((isset($arr['password2'])) ? trim($arr['password2']) : ''); - $parent = ((isset($arr['parent'])) ? intval($arr['parent']) : 0 ); - $flags = ((isset($arr['account_flags'])) ? intval($arr['account_flags']) : ACCOUNT_OK); - $roles = ((isset($arr['account_roles'])) ? intval($arr['account_roles']) : 0 ); - $expires = ((isset($arr['expires'])) ? intval($arr['expires']) : NULL_DATE); + $invite_code = ((isset($arr['invite_code'])) ? notags(trim($arr['invite_code'])) : ''); + $email = ((isset($arr['email'])) ? notags(punify(trim($arr['email']))) : ''); + $password = ((isset($arr['password'])) ? trim($arr['password']) : ''); + $password2 = ((isset($arr['password2'])) ? trim($arr['password2']) : ''); + $parent = ((isset($arr['parent'])) ? intval($arr['parent']) : 0 ); + $flags = ((isset($arr['account_flags'])) ? intval($arr['account_flags']) : ACCOUNT_OK); + $roles = ((isset($arr['account_roles'])) ? intval($arr['account_roles']) : 0 ); + $expires = ((isset($arr['expires'])) ? intval($arr['expires']) : NULL_DATE); - $default_service_class = get_config('system','default_service_class', EMPTY_STR); + $default_service_class = get_config('system', 'default_service_class', EMPTY_STR); - if (! ($email && $password)) { - $result['message'] = t('Please enter the required information.'); - return $result; - } + if (! ($email && $password)) { + $result['message'] = t('Please enter the required information.'); + return $result; + } - // prevent form hackery + // prevent form hackery - if (($roles & ACCOUNT_ROLE_ADMIN) && (! check_account_admin($arr))) { - $roles = $roles - ACCOUNT_ROLE_ADMIN; - } + if (($roles & ACCOUNT_ROLE_ADMIN) && (! check_account_admin($arr))) { + $roles = $roles - ACCOUNT_ROLE_ADMIN; + } - // allow the admin_email account to be admin, but only if it's the first account. + // allow the admin_email account to be admin, but only if it's the first account. - $c = account_total(); - if (($c === 0) && (check_account_admin($arr))) { - $roles |= ACCOUNT_ROLE_ADMIN; - } + $c = account_total(); + if (($c === 0) && (check_account_admin($arr))) { + $roles |= ACCOUNT_ROLE_ADMIN; + } - // Ensure that there is a host keypair. + // Ensure that there is a host keypair. - if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { - $hostkey = Crypto::new_keypair(4096); - set_config('system', 'pubkey', $hostkey['pubkey']); - set_config('system', 'prvkey', $hostkey['prvkey']); - } + if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { + $hostkey = Crypto::new_keypair(4096); + set_config('system', 'pubkey', $hostkey['pubkey']); + set_config('system', 'prvkey', $hostkey['prvkey']); + } - $invite_result = check_account_invite($invite_code); - if ($invite_result['error']) { - $result['message'] = $invite_result['message']; - return $result; - } + $invite_result = check_account_invite($invite_code); + if ($invite_result['error']) { + $result['message'] = $invite_result['message']; + return $result; + } - $email_result = check_account_email($email); + $email_result = check_account_email($email); - if ($email_result['error']) { - $result['message'] = $email_result['message']; - return $result; - } + if ($email_result['error']) { + $result['message'] = $email_result['message']; + return $result; + } - $password_result = check_account_password($password); + $password_result = check_account_password($password); - if ($password_result['error']) { - $result['message'] = $password_result['message']; - return $result; - } + if ($password_result['error']) { + $result['message'] = $password_result['message']; + return $result; + } - $salt = random_string(32); - $password_encoded = hash('whirlpool', $salt . $password); + $salt = random_string(32); + $password_encoded = hash('whirlpool', $salt . $password); - $r = account_store_lowlevel( - [ - 'account_parent' => intval($parent), - 'account_salt' => $salt, - 'account_password' => $password_encoded, - 'account_email' => $email, - 'account_language' => get_best_language(), - 'account_created' => datetime_convert(), - 'account_flags' => intval($flags), - 'account_roles' => intval($roles), - 'account_expires' => $expires, - 'account_service_class' => $default_service_class - ] - ); - if (! $r) { - logger('create_account: DB INSERT failed.'); - $result['message'] = t('Failed to store account information.'); - return($result); - } + $r = account_store_lowlevel( + [ + 'account_parent' => intval($parent), + 'account_salt' => $salt, + 'account_password' => $password_encoded, + 'account_email' => $email, + 'account_language' => get_best_language(), + 'account_created' => datetime_convert(), + 'account_flags' => intval($flags), + 'account_roles' => intval($roles), + 'account_expires' => $expires, + 'account_service_class' => $default_service_class + ] + ); + if (! $r) { + logger('create_account: DB INSERT failed.'); + $result['message'] = t('Failed to store account information.'); + return($result); + } - $r = q("select * from account where account_email = '%s' and account_password = '%s' limit 1", - dbesc($email), - dbesc($password_encoded) - ); - if ($r && is_array($r) && count($r)) { - $result['account'] = $r[0]; - } - else { - logger('create_account: could not retrieve newly created account'); - } + $r = q( + "select * from account where account_email = '%s' and account_password = '%s' limit 1", + dbesc($email), + dbesc($password_encoded) + ); + if ($r && is_array($r) && count($r)) { + $result['account'] = $r[0]; + } else { + logger('create_account: could not retrieve newly created account'); + } - // Set the parent record to the current record_id if no parent was provided + // Set the parent record to the current record_id if no parent was provided - if (! $parent) { - $r = q("update account set account_parent = %d where account_id = %d", - intval($result['account']['account_id']), - intval($result['account']['account_id']) - ); - if (! $r) { - logger('create_account: failed to set parent'); - } - $result['account']['parent'] = $result['account']['account_id']; - } + if (! $parent) { + $r = q( + "update account set account_parent = %d where account_id = %d", + intval($result['account']['account_id']), + intval($result['account']['account_id']) + ); + if (! $r) { + logger('create_account: failed to set parent'); + } + $result['account']['parent'] = $result['account']['account_id']; + } - $result['success'] = true; - $result['email'] = $email; - $result['password'] = $password; + $result['success'] = true; + $result['email'] = $email; + $result['password'] = $password; - call_hooks('register_account',$result); + call_hooks('register_account', $result); - return $result; + return $result; } -function verify_email_address($arr) { +function verify_email_address($arr) +{ - if (array_key_exists('resend',$arr)) { - $email = $arr['email']; - $a = q("select * from account where account_email = '%s' limit 1", - dbesc($arr['email']) - ); - if (! ($a && ($a[0]['account_flags'] & ACCOUNT_UNVERIFIED))) { - return false; - } - $account = array_shift($a); - $v = q("select * from register where uid = %d and password = 'verify' limit 1", - intval($account['account_id']) - ); - if ($v) { - $hash = $v[0]['hash']; - } - else { - return false; - } - } - else { - $hash = random_string(24); + if (array_key_exists('resend', $arr)) { + $email = $arr['email']; + $a = q( + "select * from account where account_email = '%s' limit 1", + dbesc($arr['email']) + ); + if (! ($a && ($a[0]['account_flags'] & ACCOUNT_UNVERIFIED))) { + return false; + } + $account = array_shift($a); + $v = q( + "select * from register where uid = %d and password = 'verify' limit 1", + intval($account['account_id']) + ); + if ($v) { + $hash = $v[0]['hash']; + } else { + return false; + } + } else { + $hash = random_string(24); - $r = q("INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", - dbesc($hash), - dbesc(datetime_convert()), - intval($arr['account']['account_id']), - dbesc('verify'), - dbesc($arr['account']['account_language']) - ); - $account = $arr['account']; - } + $r = q( + "INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", + dbesc($hash), + dbesc(datetime_convert()), + intval($arr['account']['account_id']), + dbesc('verify'), + dbesc($arr['account']['account_language']) + ); + $account = $arr['account']; + } - push_lang(($account['account_language']) ? $account['account_language'] : 'en'); + push_lang(($account['account_language']) ? $account['account_language'] : 'en'); - $email_msg = replace_macros(get_intltext_template('register_verify_member.tpl'), - [ - '$sitename' => System::get_site_name(), - '$siteurl' => z_root(), - '$email' => $arr['email'], - '$uid' => $account['account_id'], - '$hash' => $hash, - '$details' => $details - ] - ); + $email_msg = replace_macros( + get_intltext_template('register_verify_member.tpl'), + [ + '$sitename' => System::get_site_name(), + '$siteurl' => z_root(), + '$email' => $arr['email'], + '$uid' => $account['account_id'], + '$hash' => $hash, + '$details' => $details + ] + ); - $res = z_mail( - [ - 'toEmail' => $arr['email'], - 'messageSubject' => sprintf( t('Registration confirmation for %s'), System::get_site_name()), - 'textVersion' => $email_msg, - ] - ); + $res = z_mail( + [ + 'toEmail' => $arr['email'], + 'messageSubject' => sprintf(t('Registration confirmation for %s'), System::get_site_name()), + 'textVersion' => $email_msg, + ] + ); - pop_lang(); + pop_lang(); - if ($res) { - $delivered ++; - } - else { - logger('send_reg_approval_email: failed to account_id: ' . $arr['account']['account_id']); - } - return $res; + if ($res) { + $delivered ++; + } else { + logger('send_reg_approval_email: failed to account_id: ' . $arr['account']['account_id']); + } + return $res; } -function send_reg_approval_email($arr) { +function send_reg_approval_email($arr) +{ - $r = q("select * from account where (account_roles & %d) >= 4096", - intval(ACCOUNT_ROLE_ADMIN) - ); - if (! ($r && is_array($r) && count($r))) { - return false; - } + $r = q( + "select * from account where (account_roles & %d) >= 4096", + intval(ACCOUNT_ROLE_ADMIN) + ); + if (! ($r && is_array($r) && count($r))) { + return false; + } - $admins = []; + $admins = []; - foreach ($r as $rr) { - if (strlen($rr['account_email'])) { - $admins[] = [ 'email' => $rr['account_email'], 'lang' => $rr['account_lang'] ]; - } - } + foreach ($r as $rr) { + if (strlen($rr['account_email'])) { + $admins[] = [ 'email' => $rr['account_email'], 'lang' => $rr['account_lang'] ]; + } + } - if (! count($admins)) { - return false; - } + if (! count($admins)) { + return false; + } - $hash = random_string(); + $hash = random_string(); - $r = q("INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", - dbesc($hash), - dbesc(datetime_convert()), - intval($arr['account']['account_id']), - dbesc(''), - dbesc($arr['account']['account_language']) - ); + $r = q( + "INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", + dbesc($hash), + dbesc(datetime_convert()), + intval($arr['account']['account_id']), + dbesc(''), + dbesc($arr['account']['account_language']) + ); - $ip = ((isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : EMPTY_STR); + $ip = ((isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : EMPTY_STR); - $details = (($ip) ? $ip . ' [' . gethostbyaddr($ip) . ']' : '[unknown or stealth IP]'); + $details = (($ip) ? $ip . ' [' . gethostbyaddr($ip) . ']' : '[unknown or stealth IP]'); - $delivered = 0; + $delivered = 0; - foreach ($admins as $admin) { - if (strlen($admin['lang'])) { - push_lang($admin['lang']); - } - else { - push_lang('en'); - } + foreach ($admins as $admin) { + if (strlen($admin['lang'])) { + push_lang($admin['lang']); + } else { + push_lang('en'); + } - $email_msg = replace_macros(get_intltext_template('register_verify_eml.tpl'), [ - '$sitename' => get_config('system','sitename'), - '$siteurl' => z_root(), - '$email' => $arr['email'], - '$uid' => $arr['account']['account_id'], - '$hash' => $hash, - '$details' => $details - ]); + $email_msg = replace_macros(get_intltext_template('register_verify_eml.tpl'), [ + '$sitename' => get_config('system', 'sitename'), + '$siteurl' => z_root(), + '$email' => $arr['email'], + '$uid' => $arr['account']['account_id'], + '$hash' => $hash, + '$details' => $details + ]); - $res = z_mail( - [ - 'toEmail' => $admin['email'], - 'messageSubject' => sprintf( t('Registration request at %s'), get_config('system','sitename')), - 'textVersion' => $email_msg, - ] - ); + $res = z_mail( + [ + 'toEmail' => $admin['email'], + 'messageSubject' => sprintf(t('Registration request at %s'), get_config('system', 'sitename')), + 'textVersion' => $email_msg, + ] + ); - if ($res) { - $delivered ++; - } - else { - logger('send_reg_approval_email: failed to ' . $admin['email'] . 'account_id: ' . $arr['account']['account_id']); - } - - pop_lang(); - } + if ($res) { + $delivered ++; + } else { + logger('send_reg_approval_email: failed to ' . $admin['email'] . 'account_id: ' . $arr['account']['account_id']); + } + + pop_lang(); + } - return ($delivered ? true : false); + return ($delivered ? true : false); } -function send_register_success_email($email,$password) { +function send_register_success_email($email, $password) +{ - $email_msg = replace_macros(get_intltext_template('register_open_eml.tpl'), [ - '$sitename' => System::get_site_name(), - '$siteurl' => z_root(), - '$email' => $email, - '$password' => t('your registration password'), - ]); + $email_msg = replace_macros(get_intltext_template('register_open_eml.tpl'), [ + '$sitename' => System::get_site_name(), + '$siteurl' => z_root(), + '$email' => $email, + '$password' => t('your registration password'), + ]); - $res = z_mail( - [ - 'toEmail' => $email, - 'messageSubject' => sprintf( t('Registration details for %s'), System::get_site_name()), - 'textVersion' => $email_msg, - ] - ); + $res = z_mail( + [ + 'toEmail' => $email, + 'messageSubject' => sprintf(t('Registration details for %s'), System::get_site_name()), + 'textVersion' => $email_msg, + ] + ); - return ($res ? true : false); + return ($res ? true : false); } /** @@ -427,71 +439,77 @@ function send_register_success_email($email,$password) { * @param string $hash * @return array|bool */ -function account_allow($hash) { +function account_allow($hash) +{ - $ret = array('success' => false); + $ret = array('success' => false); - $register = q("SELECT * FROM register WHERE hash = '%s' LIMIT 1", - dbesc($hash) - ); + $register = q( + "SELECT * FROM register WHERE hash = '%s' LIMIT 1", + dbesc($hash) + ); - if (! $register) { - return $ret; - } + if (! $register) { + return $ret; + } - $account = q("SELECT * FROM account WHERE account_id = %d LIMIT 1", - intval($register[0]['uid']) - ); + $account = q( + "SELECT * FROM account WHERE account_id = %d LIMIT 1", + intval($register[0]['uid']) + ); - if (! $account) { - return $ret; - } + if (! $account) { + return $ret; + } - $r = q("DELETE FROM register WHERE hash = '%s'", - dbesc($register[0]['hash']) - ); + $r = q( + "DELETE FROM register WHERE hash = '%s'", + dbesc($register[0]['hash']) + ); - $r = q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d) > 0 and account_id = %d", - intval(ACCOUNT_BLOCKED), - intval(ACCOUNT_BLOCKED), - intval($register[0]['uid']) - ); - $r = q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d) > 0 and account_id = %d", - intval(ACCOUNT_PENDING), - intval(ACCOUNT_PENDING), - intval($register[0]['uid']) - ); + $r = q( + "update account set account_flags = (account_flags & ~%d) where (account_flags & %d) > 0 and account_id = %d", + intval(ACCOUNT_BLOCKED), + intval(ACCOUNT_BLOCKED), + intval($register[0]['uid']) + ); + $r = q( + "update account set account_flags = (account_flags & ~%d) where (account_flags & %d) > 0 and account_id = %d", + intval(ACCOUNT_PENDING), + intval(ACCOUNT_PENDING), + intval($register[0]['uid']) + ); - push_lang($register[0]['lang']); + push_lang($register[0]['lang']); - $email_tpl = get_intltext_template("register_open_eml.tpl"); - $email_msg = replace_macros($email_tpl, [ - '$sitename' => System::get_site_name(), - '$siteurl' => z_root(), - '$username' => $account[0]['account_email'], - '$email' => $account[0]['account_email'], - '$password' => '', - '$uid' => $account[0]['account_id'] - ]); + $email_tpl = get_intltext_template("register_open_eml.tpl"); + $email_msg = replace_macros($email_tpl, [ + '$sitename' => System::get_site_name(), + '$siteurl' => z_root(), + '$username' => $account[0]['account_email'], + '$email' => $account[0]['account_email'], + '$password' => '', + '$uid' => $account[0]['account_id'] + ]); - $res = z_mail( - [ - 'toEmail' => $account[0]['account_email'], - 'messageSubject' => sprintf( t('Registration details for %s'), System::get_site_name()), - 'textVersion' => $email_msg, - ] - ); + $res = z_mail( + [ + 'toEmail' => $account[0]['account_email'], + 'messageSubject' => sprintf(t('Registration details for %s'), System::get_site_name()), + 'textVersion' => $email_msg, + ] + ); - pop_lang(); + pop_lang(); - if (get_config('system','auto_channel_create')) { - auto_channel_create($register[0]['uid']); - } + if (get_config('system', 'auto_channel_create')) { + auto_channel_create($register[0]['uid']); + } - if ($res) { - info( t('Account approved.') . EOL ); - return true; - } + if ($res) { + info(t('Account approved.') . EOL); + return true; + } } @@ -506,153 +524,167 @@ function account_allow($hash) { * @return bool */ -function account_deny($hash) { +function account_deny($hash) +{ - $register = q("SELECT * FROM register WHERE hash = '%s' LIMIT 1", - dbesc($hash) - ); + $register = q( + "SELECT * FROM register WHERE hash = '%s' LIMIT 1", + dbesc($hash) + ); - if(! $register) { - return false; - } + if (! $register) { + return false; + } - $account = q("SELECT account_id, account_email FROM account WHERE account_id = %d LIMIT 1", - intval($register[0]['uid']) - ); + $account = q( + "SELECT account_id, account_email FROM account WHERE account_id = %d LIMIT 1", + intval($register[0]['uid']) + ); - if (! $account) { - return false; - } + if (! $account) { + return false; + } - $r = q("DELETE FROM account WHERE account_id = %d", - intval($register[0]['uid']) - ); + $r = q( + "DELETE FROM account WHERE account_id = %d", + intval($register[0]['uid']) + ); - $r = q("DELETE FROM register WHERE id = %d", - intval($register[0]['id']) - ); - notice( sprintf(t('Registration revoked for %s'), $account[0]['account_email']) . EOL); - - return true; + $r = q( + "DELETE FROM register WHERE id = %d", + intval($register[0]['id']) + ); + notice(sprintf(t('Registration revoked for %s'), $account[0]['account_email']) . EOL); + return true; } // called from regver to activate an account from the email verification link -function account_approve($hash) { +function account_approve($hash) +{ - $ret = false; + $ret = false; - // Note: when the password in the register table is 'verify', the uid actually contains the account_id + // Note: when the password in the register table is 'verify', the uid actually contains the account_id - $register = q("SELECT * FROM register WHERE hash = '%s' and password = 'verify' LIMIT 1", - dbesc($hash) - ); + $register = q( + "SELECT * FROM register WHERE hash = '%s' and password = 'verify' LIMIT 1", + dbesc($hash) + ); - if (! $register) { - return $ret; - } + if (! $register) { + return $ret; + } - $account = q("SELECT * FROM account WHERE account_id = %d LIMIT 1", - intval($register[0]['uid']) - ); + $account = q( + "SELECT * FROM account WHERE account_id = %d LIMIT 1", + intval($register[0]['uid']) + ); - if (! $account) { - return $ret; - } + if (! $account) { + return $ret; + } - $r = q("DELETE FROM register WHERE hash = '%s' and password = 'verify'", - dbesc($register[0]['hash']) - ); + $r = q( + "DELETE FROM register WHERE hash = '%s' and password = 'verify'", + dbesc($register[0]['hash']) + ); - $r = q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", - intval(ACCOUNT_BLOCKED), - intval(ACCOUNT_BLOCKED), - intval($register[0]['uid']) - ); - $r = q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", - intval(ACCOUNT_PENDING), - intval(ACCOUNT_PENDING), - intval($register[0]['uid']) - ); - $r = q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", - intval(ACCOUNT_UNVERIFIED), - intval(ACCOUNT_UNVERIFIED), - intval($register[0]['uid']) - ); + $r = q( + "update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", + intval(ACCOUNT_BLOCKED), + intval(ACCOUNT_BLOCKED), + intval($register[0]['uid']) + ); + $r = q( + "update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", + intval(ACCOUNT_PENDING), + intval(ACCOUNT_PENDING), + intval($register[0]['uid']) + ); + $r = q( + "update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", + intval(ACCOUNT_UNVERIFIED), + intval(ACCOUNT_UNVERIFIED), + intval($register[0]['uid']) + ); - // get a fresh copy after we've modified it. + // get a fresh copy after we've modified it. - $account = q("SELECT * FROM account WHERE account_id = %d LIMIT 1", - intval($register[0]['uid']) - ); + $account = q( + "SELECT * FROM account WHERE account_id = %d LIMIT 1", + intval($register[0]['uid']) + ); - if (! $account) { - return $ret; - } + if (! $account) { + return $ret; + } - if (get_config('system','auto_channel_create')) { - auto_channel_create($register[0]['uid']); - } - else { - $_SESSION['login_return_url'] = 'new_channel'; - authenticate_success($account[0],null,true,true,false,true); - } + if (get_config('system', 'auto_channel_create')) { + auto_channel_create($register[0]['uid']); + } else { + $_SESSION['login_return_url'] = 'new_channel'; + authenticate_success($account[0], null, true, true, false, true); + } - return true; + return true; } /** * @brief Checks for accounts that have past their expiration date. * - * If the account has a service class which is not the site default, + * If the account has a service class which is not the site default, * the service class is reset to the site default and expiration reset to never. * If the account has no service class it is expired and subsequently disabled. * called from include/poller.php as a scheduled task. * * Reclaiming resources which are no longer within the service class limits is - * not the job of this function, but this can be implemented by plugin if desired. - * Default behaviour is to stop allowing additional resources to be consumed. + * not the job of this function, but this can be implemented by plugin if desired. + * Default behaviour is to stop allowing additional resources to be consumed. */ -function downgrade_accounts() { +function downgrade_accounts() +{ - $r = q("select * from account where not ( account_flags & %d ) > 0 + $r = q( + "select * from account where not ( account_flags & %d ) > 0 and account_expires > '%s' and account_expires < %s ", - intval(ACCOUNT_EXPIRED), - dbesc(NULL_DATE), - db_getfunc('UTC_TIMESTAMP') - ); + intval(ACCOUNT_EXPIRED), + dbesc(NULL_DATE), + db_getfunc('UTC_TIMESTAMP') + ); - if (! $r) { - return; - } + if (! $r) { + return; + } - $basic = get_config('system','default_service_class'); + $basic = get_config('system', 'default_service_class'); - foreach ($r as $rr) { - if (($basic) && ($rr['account_service_class']) && ($rr['account_service_class'] != $basic)) { - $x = q("UPDATE account set account_service_class = '%s', account_expires = '%s' + foreach ($r as $rr) { + if (($basic) && ($rr['account_service_class']) && ($rr['account_service_class'] != $basic)) { + $x = q( + "UPDATE account set account_service_class = '%s', account_expires = '%s' where account_id = %d", - dbesc($basic), - dbesc(NULL_DATE), - intval($rr['account_id']) - ); - $ret = [ 'account' => $rr ]; - call_hooks('account_downgrade', $ret ); - logger('downgrade_accounts: Account id ' . $rr['account_id'] . ' downgraded.'); - } - else { - $x = q("UPDATE account SET account_flags = (account_flags | %d) where account_id = %d", - intval(ACCOUNT_EXPIRED), - intval($rr['account_id']) - ); - $ret = [ 'account' => $rr ]; - call_hooks('account_downgrade', $ret); - logger('downgrade_accounts: Account id ' . $rr['account_id'] . ' expired.'); - } - } + dbesc($basic), + dbesc(NULL_DATE), + intval($rr['account_id']) + ); + $ret = [ 'account' => $rr ]; + call_hooks('account_downgrade', $ret); + logger('downgrade_accounts: Account id ' . $rr['account_id'] . ' downgraded.'); + } else { + $x = q( + "UPDATE account SET account_flags = (account_flags | %d) where account_id = %d", + intval(ACCOUNT_EXPIRED), + intval($rr['account_id']) + ); + $ret = [ 'account' => $rr ]; + call_hooks('account_downgrade', $ret); + logger('downgrade_accounts: Account id ' . $rr['account_id'] . ' expired.'); + } + } } @@ -680,20 +712,21 @@ function downgrade_accounts() { * @param string|bool $usage (optional) The value to check against * @return bool */ -function service_class_allows($uid, $property, $usage = false) { - $limit = service_class_fetch($uid, $property); +function service_class_allows($uid, $property, $usage = false) +{ + $limit = service_class_fetch($uid, $property); - if ($limit === false) { - return true; // No service class set => everything is allowed - } - - $limit = engr_units_to_bytes($limit); - if ($usage === false) { - // We use negative values for not allowed properties in a subscriber plan - return (($limit) ? (bool) $limit : true); - } else { - return (((intval($usage)) < intval($limit)) ? true : false); - } + if ($limit === false) { + return true; // No service class set => everything is allowed + } + + $limit = engr_units_to_bytes($limit); + if ($usage === false) { + // We use negative values for not allowed properties in a subscriber plan + return (($limit) ? (bool) $limit : true); + } else { + return (((intval($usage)) < intval($limit)) ? true : false); + } } /** @@ -717,22 +750,23 @@ function service_class_allows($uid, $property, $usage = false) { * @param int|bool $usage (optional) The value to check against * @return bool */ -function account_service_class_allows($aid, $property, $usage = false) { +function account_service_class_allows($aid, $property, $usage = false) +{ - $limit = account_service_class_fetch($aid, $property); + $limit = account_service_class_fetch($aid, $property); - if ($limit === false) { - return true; // No service class is set => everything is allowed - } - - $limit = engr_units_to_bytes($limit); + if ($limit === false) { + return true; // No service class is set => everything is allowed + } + + $limit = engr_units_to_bytes($limit); - if ($usage === false) { - // We use negative values for not allowed properties in a subscriber plan - return (($limit) ? (bool) $limit : true); - } else { - return (((intval($usage)) < intval($limit)) ? true : false); - } + if ($usage === false) { + // We use negative values for not allowed properties in a subscriber plan + return (($limit) ? (bool) $limit : true); + } else { + return (((intval($usage)) < intval($limit)) ? true : false); + } } /** @@ -752,32 +786,33 @@ function account_service_class_allows($aid, $property, $usage = false) { * * @todo Should we merge this with account_service_class_fetch()? */ -function service_class_fetch($uid, $property) { +function service_class_fetch($uid, $property) +{ - if ($uid == local_channel()) { - $service_class = App::$account['account_service_class']; - } - else { - $r = q("select account_service_class + if ($uid == local_channel()) { + $service_class = App::$account['account_service_class']; + } else { + $r = q( + "select account_service_class from channel c, account a where c.channel_account_id = a.account_id and c.channel_id = %d limit 1", - intval($uid) - ); - if ($r) { - $service_class = $r[0]['account_service_class']; - } - } - if (! $service_class) { - return false; // everything is allowed - } - $arr = get_config('service_class', $service_class); + intval($uid) + ); + if ($r) { + $service_class = $r[0]['account_service_class']; + } + } + if (! $service_class) { + return false; // everything is allowed + } + $arr = get_config('service_class', $service_class); - if (! is_array($arr) || (! count($arr))) { - return false; - } + if (! is_array($arr) || (! count($arr))) { + return false; + } - return((array_key_exists($property, $arr)) ? $arr[$property] : false); + return((array_key_exists($property, $arr)) ? $arr[$property] : false); } /** @@ -792,46 +827,53 @@ function service_class_fetch($uid, $property) { * @param string $property The service property name to check for * @return bool|int */ -function account_service_class_fetch($aid, $property) { +function account_service_class_fetch($aid, $property) +{ - $r = q("select account_service_class as service_class from account where account_id = %d limit 1", - intval($aid) - ); - if($r !== false && count($r)) { - $service_class = $r[0]['service_class']; - } + $r = q( + "select account_service_class as service_class from account where account_id = %d limit 1", + intval($aid) + ); + if ($r !== false && count($r)) { + $service_class = $r[0]['service_class']; + } - if(! x($service_class)) - return false; // everything is allowed + if (! x($service_class)) { + return false; // everything is allowed + } - $arr = get_config('service_class', $service_class); + $arr = get_config('service_class', $service_class); - if(! is_array($arr) || (! count($arr))) - return false; + if (! is_array($arr) || (! count($arr))) { + return false; + } - return((array_key_exists($property, $arr)) ? $arr[$property] : false); + return((array_key_exists($property, $arr)) ? $arr[$property] : false); } -function upgrade_link($bbcode = false) { - $l = get_config('service_class', 'upgrade_link'); - if(! $l) - return ''; - if($bbcode) - $t = sprintf('[zrl=%s]' . t('Click here to upgrade.') . '[/zrl]', $l); - else - $t = sprintf('' . t('Click here to upgrade.') . '', $l); - return $t; +function upgrade_link($bbcode = false) +{ + $l = get_config('service_class', 'upgrade_link'); + if (! $l) { + return ''; + } + if ($bbcode) { + $t = sprintf('[zrl=%s]' . t('Click here to upgrade.') . '[/zrl]', $l); + } else { + $t = sprintf('' . t('Click here to upgrade.') . '', $l); + } + return $t; } -function upgrade_message($bbcode = false) { - $x = upgrade_link($bbcode); - return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ; +function upgrade_message($bbcode = false) +{ + $x = upgrade_link($bbcode); + return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ; } -function upgrade_bool_message($bbcode = false) { - $x = upgrade_link($bbcode); - return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ; +function upgrade_bool_message($bbcode = false) +{ + $x = upgrade_link($bbcode); + return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ; } - - diff --git a/include/acl_selectors.php b/include/acl_selectors.php index e5988efe4..5d036244d 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -8,8 +8,9 @@ use Zotlabs\Lib\Apps; use Zotlabs\Lib\PermissionDescription; -function fixacl(&$item) { - $item = str_replace( [ '<', '>' ], [ '', '' ], $item); +function fixacl(&$item) +{ + $item = str_replace([ '<', '>' ], [ '', '' ], $item); } /** @@ -24,139 +25,137 @@ function fixacl(&$item) { * * @return string html modal dialog built from acl_selector.tpl */ -function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_description = '', $dialog_description = '', $context_help = '', $readonly = false) { +function populate_acl($defaults = null, $show_jotnets = true, $emptyACL_description = '', $dialog_description = '', $context_help = '', $readonly = false) +{ - $allow_cid = $allow_gid = $deny_cid = $deny_gid = false; - $showall_origin = ''; - $showall_icon = 'fa-globe'; - $role = get_pconfig(local_channel(), 'system', 'permissions_role'); + $allow_cid = $allow_gid = $deny_cid = $deny_gid = false; + $showall_origin = ''; + $showall_icon = 'fa-globe'; + $role = get_pconfig(local_channel(), 'system', 'permissions_role'); - if (! $emptyACL_description) { - $showall_caption = t('Visible to your default audience'); - - } - elseif (is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) { - $showall_caption = $emptyACL_description->get_permission_description(); - $showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : ''); - $showall_icon = $emptyACL_description->get_permission_icon(); - } - else { - // For backwards compatibility we still accept a string... for now! - $showall_caption = $emptyACL_description; - } + if (! $emptyACL_description) { + $showall_caption = t('Visible to your default audience'); + } elseif (is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) { + $showall_caption = $emptyACL_description->get_permission_description(); + $showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : ''); + $showall_icon = $emptyACL_description->get_permission_icon(); + } else { + // For backwards compatibility we still accept a string... for now! + $showall_caption = $emptyACL_description; + } - if (is_array($defaults)) { - $allow_cid = ((strlen($defaults['allow_cid'])) - ? explode('><', $defaults['allow_cid']) : [] ); - $allow_gid = ((strlen($defaults['allow_gid'])) - ? explode('><', $defaults['allow_gid']) : [] ); - $deny_cid = ((strlen($defaults['deny_cid'])) - ? explode('><', $defaults['deny_cid']) : [] ); - $deny_gid = ((strlen($defaults['deny_gid'])) - ? explode('><', $defaults['deny_gid']) : [] ); - array_walk($allow_cid,'fixacl'); - array_walk($allow_gid,'fixacl'); - array_walk($deny_cid,'fixacl'); - array_walk($deny_gid,'fixacl'); - } + if (is_array($defaults)) { + $allow_cid = ((strlen($defaults['allow_cid'])) + ? explode('><', $defaults['allow_cid']) : [] ); + $allow_gid = ((strlen($defaults['allow_gid'])) + ? explode('><', $defaults['allow_gid']) : [] ); + $deny_cid = ((strlen($defaults['deny_cid'])) + ? explode('><', $defaults['deny_cid']) : [] ); + $deny_gid = ((strlen($defaults['deny_gid'])) + ? explode('><', $defaults['deny_gid']) : [] ); + array_walk($allow_cid, 'fixacl'); + array_walk($allow_gid, 'fixacl'); + array_walk($deny_cid, 'fixacl'); + array_walk($deny_gid, 'fixacl'); + } - $channel = ((local_channel()) ? App::get_channel() : ''); - $has_acl = false; - $single_group = false; - $just_me = false; - $custom = false; + $channel = ((local_channel()) ? App::get_channel() : ''); + $has_acl = false; + $single_group = false; + $just_me = false; + $custom = false; - if ($allow_cid || $allow_gid || $deny_gid || $deny_cid) { - $has_acl = true; - $custom = true; - } + if ($allow_cid || $allow_gid || $deny_gid || $deny_cid) { + $has_acl = true; + $custom = true; + } - if (count($allow_gid) === 1 && (! $allow_cid) && (! $deny_gid) && (! $deny_cid)) { - $single_group = true; - $custom = false; - } + if (count($allow_gid) === 1 && (! $allow_cid) && (! $deny_gid) && (! $deny_cid)) { + $single_group = true; + $custom = false; + } - if (count($allow_cid) === 1 && $channel && $allow_cid[0] === $channel['channel_hash'] && (! $allow_gid) && (! $deny_gid) && (! $deny_cid)) { - $just_me = true; - $custom = false; - } + if (count($allow_cid) === 1 && $channel && $allow_cid[0] === $channel['channel_hash'] && (! $allow_gid) && (! $deny_gid) && (! $deny_cid)) { + $just_me = true; + $custom = false; + } - $groups = EMPTY_STR; + $groups = EMPTY_STR; - $r = q("SELECT id, hash, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", - intval(local_channel()) - ); + $r = q( + "SELECT id, hash, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + intval(local_channel()) + ); - if ($r) { - foreach ($r as $rr) { - $selected = (($single_group && $rr['hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); - $groups .= '' . "\r\n"; - } - } + if ($r) { + foreach ($r as $rr) { + $selected = (($single_group && $rr['hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); + $groups .= '' . "\r\n"; + } + } - if ($channel && Apps::system_app_installed($channel['channel_id'],'Virtual Lists')) { - $selected = (($single_group && 'connections:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); - $groups .= '' . "\r\n"; - if (get_pconfig($channel['channel_id'],'system','activitypub',get_config('system','activitypub', ACTIVITYPUB_ENABLED))) { - $selected = (($single_group && 'activitypub:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); - $groups .= '' . "\r\n"; - } - $selected = (($single_group && 'zot:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); - $groups .= '' . "\r\n"; - - } + if ($channel && Apps::system_app_installed($channel['channel_id'], 'Virtual Lists')) { + $selected = (($single_group && 'connections:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); + $groups .= '' . "\r\n"; + if (get_pconfig($channel['channel_id'], 'system', 'activitypub', get_config('system', 'activitypub', ACTIVITYPUB_ENABLED))) { + $selected = (($single_group && 'activitypub:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); + $groups .= '' . "\r\n"; + } + $selected = (($single_group && 'zot:' . $channel['channel_hash'] === $allow_gid[0]) ? ' selected = "selected" ' : ''); + $groups .= '' . "\r\n"; + } - $forums = get_forum_channels(local_channel(),1); - $selected = false; - if ($forums) { - foreach ($forums as $f) { + $forums = get_forum_channels(local_channel(), 1); + $selected = false; + if ($forums) { + foreach ($forums as $f) { + $selected = (($single_group && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : ''); + $groups .= '' . "\r\n"; + } + } - $selected = (($single_group && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : ''); - $groups .= '' . "\r\n"; - } - } + // preset acl with DM to a single xchan (not a group) + if ($selected === false && count($allow_cid) === 1 && $channel && $allow_cid[0] !== $channel['channel_hash'] && (! $allow_gid) && (! $deny_gid) && (! $deny_cid)) { + $f = q( + "select * from xchan where xchan_hash = '%s'", + dbesc($allow_cid[0]) + ); + if ($f) { + $custom = false; + $selected = ' selected="selected" '; + $groups .= '' . "\r\n"; + } + } - // preset acl with DM to a single xchan (not a group) - if ($selected === false && count($allow_cid) === 1 && $channel && $allow_cid[0] !== $channel['channel_hash'] && (! $allow_gid) && (! $deny_gid) && (! $deny_cid)) { - $f = q("select * from xchan where xchan_hash = '%s'", - dbesc($allow_cid[0]) - ); - if ($f) { - $custom = false; - $selected = ' selected="selected" '; - $groups .= '' . "\r\n"; - } - } + $tpl = get_markup_template("acl_selector.tpl"); + $o = replace_macros($tpl, array( + '$showall' => $showall_caption, + '$onlyme' => t('Only me'), + '$groups' => $groups, + '$public_selected' => (($has_acl) ? false : ' selected="selected" '), + '$justme_selected' => (($just_me) ? ' selected="selected" ' : ''), + '$custom_selected' => (($custom) ? ' selected="selected" ' : ''), + '$showallOrigin' => $showall_origin, + '$showallIcon' => $showall_icon, + '$select_label' => t('Who can see this?'), + '$custom' => t('Custom selection'), + '$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'), + '$show' => t('Show'), + '$hide' => t("Don't show"), + '$search' => t('Search'), + '$allowcid' => json_encode($allow_cid), + '$allowgid' => json_encode($allow_gid), + '$denycid' => json_encode($deny_cid), + '$denygid' => json_encode($deny_gid), + '$aclModalTitle' => t('Permissions'), + '$aclModalDesc' => $dialog_description, + '$aclModalDismiss' => t('Close'), +// '$helpUrl' => (($context_help == '') ? '' : (z_root() . '/help/' . $context_help)) + )); - $tpl = get_markup_template("acl_selector.tpl"); - $o = replace_macros($tpl, array( - '$showall' => $showall_caption, - '$onlyme' => t('Only me'), - '$groups' => $groups, - '$public_selected' => (($has_acl) ? false : ' selected="selected" '), - '$justme_selected' => (($just_me) ? ' selected="selected" ' : ''), - '$custom_selected' => (($custom) ? ' selected="selected" ' : ''), - '$showallOrigin' => $showall_origin, - '$showallIcon' => $showall_icon, - '$select_label' => t('Who can see this?'), - '$custom' => t('Custom selection'), - '$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'), - '$show' => t('Show'), - '$hide' => t("Don't show"), - '$search' => t('Search'), - '$allowcid' => json_encode($allow_cid), - '$allowgid' => json_encode($allow_gid), - '$denycid' => json_encode($deny_cid), - '$denygid' => json_encode($deny_gid), - '$aclModalTitle' => t('Permissions'), - '$aclModalDesc' => $dialog_description, - '$aclModalDismiss' => t('Close'), -// '$helpUrl' => (($context_help == '') ? '' : (z_root() . '/help/' . $context_help)) - )); - - return $o; + return $o; } /** @@ -170,18 +169,19 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti * * @return string Description to present to user in modal permissions dialog */ -function get_post_aclDialogDescription() { +function get_post_aclDialogDescription() +{ - // I'm trying to make two points in this description text - warn about finality of wall - // post permissions, and try to clear up confusion that these permissions set who is - // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking - // the "Show" button on a group does not post it to the feed of people in that group, it - // mearly allows those people to view the post if they are viewing/following this channel. - $description = t('Post permissions cannot be changed after a post is shared.
These permissions set who is allowed to view the post.'); + // I'm trying to make two points in this description text - warn about finality of wall + // post permissions, and try to clear up confusion that these permissions set who is + // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking + // the "Show" button on a group does not post it to the feed of people in that group, it + // mearly allows those people to view the post if they are viewing/following this channel. + $description = t('Post permissions cannot be changed after a post is shared.
These permissions set who is allowed to view the post.'); - // Lets keep the emphasis styling seperate from the translation. It may change. - //$emphasisOpen = '
'; - //$emphasisClose = ''; + // Lets keep the emphasis styling seperate from the translation. It may change. + //$emphasisOpen = ''; + //$emphasisClose = ''; - return $description; + return $description; } diff --git a/include/addon.php b/include/addon.php index 3f5173912..49058ca0f 100644 --- a/include/addon.php +++ b/include/addon.php @@ -13,18 +13,19 @@ * @param string $error_text text of error * @param bool $uninstall uninstall plugin */ -function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){ - logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR); - if ($notice != '') { - notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR); - } +function handleerrors_plugin($plugin, $notice, $log, $uninstall = false) +{ + logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR); + if ($notice != '') { + notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR); + } - if ($uninstall) { - $idx = array_search($plugin, App::$plugins); - unset(App::$plugins[$idx]); - uninstall_plugin($plugin); - set_config("system","addon", implode(", ",App::$plugins)); - } + if ($uninstall) { + $idx = array_search($plugin, App::$plugins); + unset(App::$plugins[$idx]); + uninstall_plugin($plugin); + set_config("system", "addon", implode(", ", App::$plugins)); + } } /** @@ -32,18 +33,19 @@ function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){ * * @param string $plugin name of the addon */ -function unload_plugin($plugin){ - logger("Addons: unloading " . $plugin, LOGGER_DEBUG); +function unload_plugin($plugin) +{ + logger("Addons: unloading " . $plugin, LOGGER_DEBUG); - @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if (function_exists($plugin . '_unload')) { - $func = $plugin . '_unload'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"Unable to unload.",$e->getMessage()); - } - } + @include_once('addon/' . $plugin . '/' . $plugin . '.php'); + if (function_exists($plugin . '_unload')) { + $func = $plugin . '_unload'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "Unable to unload.", $e->getMessage()); + } + } } /** @@ -52,33 +54,35 @@ function unload_plugin($plugin){ * @param string $plugin name of the addon * @return bool */ -function uninstall_plugin($plugin) { +function uninstall_plugin($plugin) +{ - unload_plugin($plugin); + unload_plugin($plugin); - if(! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) { - q("DELETE FROM addon WHERE aname = '%s' ", - dbesc($plugin) - ); - return false; - } + if (! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) { + q( + "DELETE FROM addon WHERE aname = '%s' ", + dbesc($plugin) + ); + return false; + } - logger("Addons: uninstalling " . $plugin); - //$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); - @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if(function_exists($plugin . '_uninstall')) { - $func = $plugin . '_uninstall'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"Unable to uninstall.","Unable to run _uninstall : ".$e->getMessage()); - } - } - - q("DELETE FROM addon WHERE aname = '%s' ", - dbesc($plugin) - ); + logger("Addons: uninstalling " . $plugin); + //$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); + @include_once('addon/' . $plugin . '/' . $plugin . '.php'); + if (function_exists($plugin . '_uninstall')) { + $func = $plugin . '_uninstall'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "Unable to uninstall.", "Unable to run _uninstall : ".$e->getMessage()); + } + } + q( + "DELETE FROM addon WHERE aname = '%s' ", + dbesc($plugin) + ); } /** @@ -90,37 +94,41 @@ function uninstall_plugin($plugin) { * @param string $plugin name of the addon * @return bool */ -function install_plugin($plugin) { - if(! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) - return false; +function install_plugin($plugin) +{ + if (! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) { + return false; + } - logger("Addons: installing " . $plugin); - $t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); - @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if(function_exists($plugin . '_install')) { - $func = $plugin . '_install'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"Install failed.","Install failed : ".$e->getMessage()); - return; - } - } + logger("Addons: installing " . $plugin); + $t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); + @include_once('addon/' . $plugin . '/' . $plugin . '.php'); + if (function_exists($plugin . '_install')) { + $func = $plugin . '_install'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "Install failed.", "Install failed : ".$e->getMessage()); + return; + } + } - $plugin_admin = (function_exists($plugin . '_plugin_admin') ? 1 : 0); + $plugin_admin = (function_exists($plugin . '_plugin_admin') ? 1 : 0); - $d = q("select * from addon where aname = '%s' limit 1", - dbesc($plugin) - ); - if(! $d) { - q("INSERT INTO addon (aname, installed, tstamp, plugin_admin) VALUES ( '%s', 1, %d , %d ) ", - dbesc($plugin), - intval($t), - $plugin_admin - ); - } + $d = q( + "select * from addon where aname = '%s' limit 1", + dbesc($plugin) + ); + if (! $d) { + q( + "INSERT INTO addon (aname, installed, tstamp, plugin_admin) VALUES ( '%s', 1, %d , %d ) ", + dbesc($plugin), + intval($t), + $plugin_admin + ); + } - load_plugin($plugin); + load_plugin($plugin); } /** @@ -129,38 +137,40 @@ function install_plugin($plugin) { * @param string $plugin name of the addon * @return bool */ -function load_plugin($plugin) { - // silently fail if plugin was removed - if(! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) - return false; +function load_plugin($plugin) +{ + // silently fail if plugin was removed + if (! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) { + return false; + } - logger("Addons: loading " . $plugin, LOGGER_DEBUG); - //$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); - @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if(function_exists($plugin . '_load')) { - $func = $plugin . '_load'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"Unable to load.","FAILED loading : ".$e->getMessage(),true); - return; - } + logger("Addons: loading " . $plugin, LOGGER_DEBUG); + //$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); + @include_once('addon/' . $plugin . '/' . $plugin . '.php'); + if (function_exists($plugin . '_load')) { + $func = $plugin . '_load'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "Unable to load.", "FAILED loading : ".$e->getMessage(), true); + return; + } - // we can add the following with the previous SQL - // once most site tables have been updated. - // This way the system won't fall over dead during the update. + // we can add the following with the previous SQL + // once most site tables have been updated. + // This way the system won't fall over dead during the update. - if(file_exists('addon/' . $plugin . '/.hidden')) { - q("update addon set hidden = 1 where name = '%s'", - dbesc($plugin) - ); - } - return true; - } - else { - logger("Addons: FAILED loading " . $plugin . " (missing _load function)"); - return false; - } + if (file_exists('addon/' . $plugin . '/.hidden')) { + q( + "update addon set hidden = 1 where name = '%s'", + dbesc($plugin) + ); + } + return true; + } else { + logger("Addons: FAILED loading " . $plugin . " (missing _load function)"); + return false; + } } @@ -170,14 +180,17 @@ function load_plugin($plugin) { * @param string $name * @return bool */ -function plugin_is_installed($name) { - $r = q("select aname from addon where aname = '%s' and installed = 1 limit 1", - dbesc($name) - ); - if($r) - return true; +function plugin_is_installed($name) +{ + $r = q( + "select aname from addon where aname = '%s' and installed = 1 limit 1", + dbesc($name) + ); + if ($r) { + return true; + } - return false; + return false; } /** @@ -187,132 +200,139 @@ function plugin_is_installed($name) { * @return bool */ -function addon_is_installed($name) { - $r = q("select aname from addon where aname = '%s' and installed = 1 limit 1", - dbesc($name) - ); - if($r) - return true; +function addon_is_installed($name) +{ + $r = q( + "select aname from addon where aname = '%s' and installed = 1 limit 1", + dbesc($name) + ); + if ($r) { + return true; + } - return false; + return false; } /** * @brief Reload all updated plugins. */ -function reload_plugins() { - $plugins = get_config('system', 'addon'); - if(strlen($plugins)) { - $r = q("SELECT * FROM addon WHERE installed = 1"); - if(count($r)) - $installed = $r; - else - $installed = []; +function reload_plugins() +{ + $plugins = get_config('system', 'addon'); + if (strlen($plugins)) { + $r = q("SELECT * FROM addon WHERE installed = 1"); + if (count($r)) { + $installed = $r; + } else { + $installed = []; + } - $parr = explode(',', $plugins); + $parr = explode(',', $plugins); - if(count($parr)) { - foreach($parr as $pl) { - $pl = trim($pl); + if (count($parr)) { + foreach ($parr as $pl) { + $pl = trim($pl); - $fname = 'addon/' . $pl . '/' . $pl . '.php'; + $fname = 'addon/' . $pl . '/' . $pl . '.php'; - if(file_exists($fname)) { - $t = @filemtime($fname); - foreach($installed as $i) { - if(($i['aname'] == $pl) && ($i['tstamp'] != $t)) { - logger('Reloading plugin: ' . $i['aname']); - @include_once($fname); + if (file_exists($fname)) { + $t = @filemtime($fname); + foreach ($installed as $i) { + if (($i['aname'] == $pl) && ($i['tstamp'] != $t)) { + logger('Reloading plugin: ' . $i['aname']); + @include_once($fname); - if(function_exists($pl . '_unload')) { - $func = $pl . '_unload'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"","UNLOAD FAILED (uninstalling) : ".$e->getMessage(),true); - continue; - } - } - if(function_exists($pl . '_load')) { - $func = $pl . '_load'; - try { - $func(); - } catch (Exception $e) { - handleerrors_plugin($plugin,"","LOAD FAILED (uninstalling): ".$e->getMessage(),true); - continue; - } - } - q("UPDATE addon SET tstamp = %d WHERE id = %d", - intval($t), - intval($i['id']) - ); - } - } - } - } - } - } + if (function_exists($pl . '_unload')) { + $func = $pl . '_unload'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "", "UNLOAD FAILED (uninstalling) : ".$e->getMessage(), true); + continue; + } + } + if (function_exists($pl . '_load')) { + $func = $pl . '_load'; + try { + $func(); + } catch (Exception $e) { + handleerrors_plugin($plugin, "", "LOAD FAILED (uninstalling): ".$e->getMessage(), true); + continue; + } + } + q( + "UPDATE addon SET tstamp = %d WHERE id = %d", + intval($t), + intval($i['id']) + ); + } + } + } + } + } + } } -function plugins_installed_list() { +function plugins_installed_list() +{ - $r = q("select * from addon where installed = 1 order by aname asc"); - return(($r) ? ids_to_array($r,'aname') : []); + $r = q("select * from addon where installed = 1 order by aname asc"); + return(($r) ? ids_to_array($r, 'aname') : []); } -function plugins_sync() { +function plugins_sync() +{ - /** - * - * Synchronise plugins: - * - * App::$config['system']['addon'] contains a comma-separated list of names - * of plugins/addons which are used on this system. - * Go through the database list of already installed addons, and if we have - * an entry, but it isn't in the config list, call the unload procedure - * and mark it uninstalled in the database (for now we'll remove it). - * Then go through the config list and if we have a plugin that isn't installed, - * call the install procedure and add it to the database. - * - */ + /** + * + * Synchronise plugins: + * + * App::$config['system']['addon'] contains a comma-separated list of names + * of plugins/addons which are used on this system. + * Go through the database list of already installed addons, and if we have + * an entry, but it isn't in the config list, call the unload procedure + * and mark it uninstalled in the database (for now we'll remove it). + * Then go through the config list and if we have a plugin that isn't installed, + * call the install procedure and add it to the database. + * + */ - $installed = plugins_installed_list(); + $installed = plugins_installed_list(); - $plugins = get_config('system', 'addon', ''); + $plugins = get_config('system', 'addon', ''); - $plugins_arr = explode(',', $plugins); + $plugins_arr = explode(',', $plugins); - // array_trim is in include/text.php + // array_trim is in include/text.php - if(! array_walk($plugins_arr,'array_trim')) - return; + if (! array_walk($plugins_arr, 'array_trim')) { + return; + } - App::$plugins = $plugins_arr; + App::$plugins = $plugins_arr; - $installed_arr = []; + $installed_arr = []; - if(count($installed)) { - foreach($installed as $i) { - if(! in_array($i, $plugins_arr)) { - unload_plugin($i); - } - else { - $installed_arr[] = $i; - } - } - } - - if(count($plugins_arr)) { - foreach($plugins_arr as $p) { - if(! in_array($p, $installed_arr)) { - load_plugin($p); - } - } - } + if (count($installed)) { + foreach ($installed as $i) { + if (! in_array($i, $plugins_arr)) { + unload_plugin($i); + } else { + $installed_arr[] = $i; + } + } + } + if (count($plugins_arr)) { + foreach ($plugins_arr as $p) { + if (! in_array($p, $installed_arr)) { + load_plugin($p); + } + } + } } @@ -321,19 +341,20 @@ function plugins_sync() { * * @return array */ -function visible_plugin_list() { - - $r = q("select * from addon where hidden = 0 order by aname asc"); - $x = (($r) ? ids_to_array($r,'aname') : []); - $y = []; - if($x) { - foreach($x as $xv) { - if(is_dir('addon/' . $xv)) { - $y[] = $xv; - } - } - } - return $y; +function visible_plugin_list() +{ + + $r = q("select * from addon where hidden = 0 order by aname asc"); + $x = (($r) ? ids_to_array($r, 'aname') : []); + $y = []; + if ($x) { + foreach ($x as $xv) { + if (is_dir('addon/' . $xv)) { + $y[] = $xv; + } + } + } + return $y; } @@ -348,23 +369,27 @@ function visible_plugin_list() { * @param int $priority A priority (defaults to 0) * @return mixed|bool */ -function register_hook($hook, $file, $function, $priority = 0) { - $r = q("SELECT * FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' LIMIT 1", - dbesc($hook), - dbesc($file), - dbesc($function) - ); - if($r) - return true; +function register_hook($hook, $file, $function, $priority = 0) +{ + $r = q( + "SELECT * FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' LIMIT 1", + dbesc($hook), + dbesc($file), + dbesc($function) + ); + if ($r) { + return true; + } - $r = q("INSERT INTO hook (hook, file, fn, priority) VALUES ( '%s', '%s', '%s', '%s' )", - dbesc($hook), - dbesc($file), - dbesc($function), - dbesc($priority) - ); + $r = q( + "INSERT INTO hook (hook, file, fn, priority) VALUES ( '%s', '%s', '%s', '%s' )", + dbesc($hook), + dbesc($file), + dbesc($function), + dbesc($priority) + ); - return $r; + return $r; } @@ -378,14 +403,16 @@ function register_hook($hook, $file, $function, $priority = 0) { * @param string $function the name of the function that the hook called * @return array */ -function unregister_hook($hook, $file, $function) { - $r = q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'", - dbesc($hook), - dbesc($file), - dbesc($function) - ); +function unregister_hook($hook, $file, $function) +{ + $r = q( + "DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'", + dbesc($hook), + dbesc($file), + dbesc($function) + ); - return $r; + return $r; } /** @@ -400,35 +427,35 @@ function unregister_hook($hook, $file, $function) { */ -function load_hooks() { +function load_hooks() +{ - App::$hooks = []; + App::$hooks = []; - $r = q("SELECT * FROM hook WHERE true ORDER BY priority DESC"); - if($r) { - - foreach($r as $rv) { - $duplicated = false; - if(! array_key_exists($rv['hook'],App::$hooks)) { - App::$hooks[$rv['hook']] = []; - } - else { - foreach(App::$hooks[$rv['hook']] as $h) { - if($h[0] === $rv['file'] && $h[1] === $rv['fn']) { - $duplicated = true; - q("delete from hook where id = %d", - intval($rv['id']) - ); - logger('duplicate hook ' . $h[1] . ' removed'); - } - } - } - if(! $duplicated) { - App::$hooks[$rv['hook']][] = [ $rv['file'], $rv['fn'], $rv['priority'], $rv['hook_version']]; - } - } - } - // logger('hooks: ' . print_r(App::$hooks,true)); + $r = q("SELECT * FROM hook WHERE true ORDER BY priority DESC"); + if ($r) { + foreach ($r as $rv) { + $duplicated = false; + if (! array_key_exists($rv['hook'], App::$hooks)) { + App::$hooks[$rv['hook']] = []; + } else { + foreach (App::$hooks[$rv['hook']] as $h) { + if ($h[0] === $rv['file'] && $h[1] === $rv['fn']) { + $duplicated = true; + q( + "delete from hook where id = %d", + intval($rv['id']) + ); + logger('duplicate hook ' . $h[1] . ' removed'); + } + } + } + if (! $duplicated) { + App::$hooks[$rv['hook']][] = [ $rv['file'], $rv['fn'], $rv['priority'], $rv['hook_version']]; + } + } + } + // logger('hooks: ' . print_r(App::$hooks,true)); } /** @@ -450,15 +477,18 @@ function load_hooks() { * @param int $version (optional) default 0 * @param int $priority (optional) default 0 */ -function insert_hook($hook, $fn, $version = 0, $priority = 0) { +function insert_hook($hook, $fn, $version = 0, $priority = 0) +{ - if(! is_array(App::$hooks)) - App::$hooks = []; + if (! is_array(App::$hooks)) { + App::$hooks = []; + } - if(! array_key_exists($hook, App::$hooks)) - App::$hooks[$hook] = []; + if (! array_key_exists($hook, App::$hooks)) { + App::$hooks[$hook] = []; + } - App::$hooks[$hook][] = array('', $fn, $priority, $version); + App::$hooks[$hook][] = array('', $fn, $priority, $version); } /** @@ -470,46 +500,47 @@ function insert_hook($hook, $fn, $version = 0, $priority = 0) { * @param string $name of the hook to call * @param[in,out] string|array &$data to transmit to the callback handler */ -function call_hooks($name, &$data = null) { - $a = 0; +function call_hooks($name, &$data = null) +{ + $a = 0; - if (isset(App::$hooks[$name])) { - foreach(App::$hooks[$name] as $hook) { - $origfn = $hook[1]; - if($hook[0]) - @include_once($hook[0]); - if(preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) { - $hook[1] = unserialize($hook[1]); - } - elseif(strpos($hook[1],'::')) { - // We shouldn't need to do this, but it appears that PHP - // isn't able to directly execute a string variable with a class - // method in the manner we are attempting it, so we'll - // turn it into an array. - $hook[1] = explode('::',$hook[1]); - } + if (isset(App::$hooks[$name])) { + foreach (App::$hooks[$name] as $hook) { + $origfn = $hook[1]; + if ($hook[0]) { + @include_once($hook[0]); + } + if (preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) { + $hook[1] = unserialize($hook[1]); + } elseif (strpos($hook[1], '::')) { + // We shouldn't need to do this, but it appears that PHP + // isn't able to directly execute a string variable with a class + // method in the manner we are attempting it, so we'll + // turn it into an array. + $hook[1] = explode('::', $hook[1]); + } - if(is_callable($hook[1])) { - $func = $hook[1]; - if($hook[3]) - $func($data); - else - $func($a, $data); - } - else { - - // Don't do any DB write calls if we're currently logging a possibly failed DB call. - if(! DBA::$logging) { - // The hook should be removed so we don't process it. - q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'", - dbesc($name), - dbesc($hook[0]), - dbesc($origfn) - ); - } - } - } - } + if (is_callable($hook[1])) { + $func = $hook[1]; + if ($hook[3]) { + $func($data); + } else { + $func($a, $data); + } + } else { + // Don't do any DB write calls if we're currently logging a possibly failed DB call. + if (! DBA::$logging) { + // The hook should be removed so we don't process it. + q( + "DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'", + dbesc($name), + dbesc($hook[0]), + dbesc($origfn) + ); + } + } + } + } } @@ -528,47 +559,48 @@ function call_hooks($name, &$data = null) { * @param string $plugin the name of the plugin * @return array with the plugin information */ -function get_plugin_info($plugin){ - $m = []; - $info = array( - 'name' => $plugin, - 'description' => '', - 'author' => [], - 'maintainer' => [], - 'version' => '', - 'requires' => '' - ); +function get_plugin_info($plugin) +{ + $m = []; + $info = array( + 'name' => $plugin, + 'description' => '', + 'author' => [], + 'maintainer' => [], + 'version' => '', + 'requires' => '' + ); - if (!is_file("addon/$plugin/$plugin.php")) - return $info; + if (!is_file("addon/$plugin/$plugin.php")) { + return $info; + } - $f = file_get_contents("addon/$plugin/$plugin.php"); - $f = escape_tags($f); - $r = preg_match("|/\*.*\*/|msU", $f, $m); + $f = file_get_contents("addon/$plugin/$plugin.php"); + $f = escape_tags($f); + $r = preg_match("|/\*.*\*/|msU", $f, $m); - if ($r){ - $ll = explode("\n", $m[0]); - foreach( $ll as $l ) { - $l = trim($l, "\t\n\r */"); - if ($l != ""){ - list($k, $v) = array_map("trim", explode(":", $l, 2)); - $k = strtolower($k); - if ($k == 'author' || $k == 'maintainer'){ - $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); - if ($r) { - $info[$k][] = array('name' => $m[1], 'link' => $m[2]); - } else { - $info[$k][] = array('name' => $v); - } - } - else { - $info[$k] = $v; - } - } - } - } + if ($r) { + $ll = explode("\n", $m[0]); + foreach ($ll as $l) { + $l = trim($l, "\t\n\r */"); + if ($l != "") { + list($k, $v) = array_map("trim", explode(":", $l, 2)); + $k = strtolower($k); + if ($k == 'author' || $k == 'maintainer') { + $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); + if ($r) { + $info[$k][] = array('name' => $m[1], 'link' => $m[2]); + } else { + $info[$k][] = array('name' => $v); + } + } else { + $info[$k] = $v; + } + } + } + } - return $info; + return $info; } /** @@ -586,116 +618,123 @@ function get_plugin_info($plugin){ * @param string $widget the name of the widget * @return array with the information */ -function get_widget_info($widget){ - $m = []; - $info = array( - 'name' => $widget, - 'description' => '', - 'author' => [], - 'maintainer' => [], - 'version' => '', - 'requires' => '' - ); +function get_widget_info($widget) +{ + $m = []; + $info = array( + 'name' => $widget, + 'description' => '', + 'author' => [], + 'maintainer' => [], + 'version' => '', + 'requires' => '' + ); - $ucwidget = ucfirst($widget); + $ucwidget = ucfirst($widget); - $checkpaths = [ - "Zotlabs/SiteWidget/$ucwidget.php", - "Zotlabs/Widget/$ucwidget.php", - "addon/$ucwidget/$ucwidget.php", - "addon/$widget.php" - ]; + $checkpaths = [ + "Zotlabs/SiteWidget/$ucwidget.php", + "Zotlabs/Widget/$ucwidget.php", + "addon/$ucwidget/$ucwidget.php", + "addon/$widget.php" + ]; - $widget_found = false; + $widget_found = false; - foreach ($checkpaths as $path) { - if (is_file($path)) { - $widget_found = true; - $f = file_get_contents($path); - break; - } - } + foreach ($checkpaths as $path) { + if (is_file($path)) { + $widget_found = true; + $f = file_get_contents($path); + break; + } + } - if(! ($widget_found && $f)) - return $info; + if (! ($widget_found && $f)) { + return $info; + } - $f = escape_tags($f); - $r = preg_match("|/\*.*\*/|msU", $f, $m); + $f = escape_tags($f); + $r = preg_match("|/\*.*\*/|msU", $f, $m); - if ($r) { - $ll = explode("\n", $m[0]); - foreach( $ll as $l ) { - $l = trim($l, "\t\n\r */"); - if ($l != ""){ - list($k, $v) = array_map("trim", explode(":", $l, 2)); - $k = strtolower($k); - if ($k == 'author' || $k == 'maintainer'){ - $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); - if ($r) { - $info[$k][] = array('name' => $m[1], 'link' => $m[2]); - } else { - $info[$k][] = array('name' => $v); - } - } - else { - $info[$k] = $v; - } - } - } - } + if ($r) { + $ll = explode("\n", $m[0]); + foreach ($ll as $l) { + $l = trim($l, "\t\n\r */"); + if ($l != "") { + list($k, $v) = array_map("trim", explode(":", $l, 2)); + $k = strtolower($k); + if ($k == 'author' || $k == 'maintainer') { + $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); + if ($r) { + $info[$k][] = array('name' => $m[1], 'link' => $m[2]); + } else { + $info[$k][] = array('name' => $v); + } + } else { + $info[$k] = $v; + } + } + } + } - return $info; + return $info; } -function check_plugin_versions($info) { +function check_plugin_versions($info) +{ - if(! is_array($info)) - return true; + if (! is_array($info)) { + return true; + } - if(array_key_exists('minversion',$info) && $info['minversion']) { - if(! version_compare(STD_VERSION,trim($info['minversion']), '>=')) { - logger('minversion limit: ' . $info['name'],LOGGER_NORMAL,LOG_WARNING); - return false; - } - } - if(array_key_exists('maxversion',$info) && $info['maxversion']) { - if(! version_compare(STD_VERSION,trim($info['maxversion']), '<')) { - logger('maxversion limit: ' . $info['name'],LOGGER_NORMAL,LOG_WARNING); - return false; - } - } - if(array_key_exists('minphpversion',$info) && $info['minphpversion']) { - if(! version_compare(PHP_VERSION,trim($info['minphpversion']), '>=')) { - logger('minphpversion limit: ' . $info['name'],LOGGER_NORMAL,LOG_WARNING); - return false; - } - } + if (array_key_exists('minversion', $info) && $info['minversion']) { + if (! version_compare(STD_VERSION, trim($info['minversion']), '>=')) { + logger('minversion limit: ' . $info['name'], LOGGER_NORMAL, LOG_WARNING); + return false; + } + } + if (array_key_exists('maxversion', $info) && $info['maxversion']) { + if (! version_compare(STD_VERSION, trim($info['maxversion']), '<')) { + logger('maxversion limit: ' . $info['name'], LOGGER_NORMAL, LOG_WARNING); + return false; + } + } + if (array_key_exists('minphpversion', $info) && $info['minphpversion']) { + if (! version_compare(PHP_VERSION, trim($info['minphpversion']), '>=')) { + logger('minphpversion limit: ' . $info['name'], LOGGER_NORMAL, LOG_WARNING); + return false; + } + } - if(array_key_exists('requires',$info)) { - $arr = explode(',',$info['requires']); - $found = true; - if($arr) { - foreach($arr as $test) { - $test = trim($test); - if(! $test) - continue; - if(strpos($test,'.')) { - $conf = explode('.',$test); - if(get_config(trim($conf[0]),trim($conf[1]))) - return true; - else - return false; - } - if(! in_array($test,App::$plugins)) - $found = false; - } - } - if(! $found) - return false; - } + if (array_key_exists('requires', $info)) { + $arr = explode(',', $info['requires']); + $found = true; + if ($arr) { + foreach ($arr as $test) { + $test = trim($test); + if (! $test) { + continue; + } + if (strpos($test, '.')) { + $conf = explode('.', $test); + if (get_config(trim($conf[0]), trim($conf[1]))) { + return true; + } else { + return false; + } + } + if (! in_array($test, App::$plugins)) { + $found = false; + } + } + } + if (! $found) { + return false; + } + } - return true; + return true; } @@ -715,66 +754,69 @@ function check_plugin_versions($info) { * @param string $theme the name of the theme * @return array */ -function get_theme_info($theme){ - $m = []; - $info = array( - 'name' => $theme, - 'description' => '', - 'author' => [], - 'version' => '', - 'minversion' => '', - 'maxversion' => '', - 'compat' => '', - 'credits' => '', - 'maintainer' => [], - 'experimental' => false, - 'unsupported' => false - ); +function get_theme_info($theme) +{ + $m = []; + $info = array( + 'name' => $theme, + 'description' => '', + 'author' => [], + 'version' => '', + 'minversion' => '', + 'maxversion' => '', + 'compat' => '', + 'credits' => '', + 'maintainer' => [], + 'experimental' => false, + 'unsupported' => false + ); - if(file_exists("view/theme/$theme/experimental")) - $info['experimental'] = true; + if (file_exists("view/theme/$theme/experimental")) { + $info['experimental'] = true; + } - if(file_exists("view/theme/$theme/unsupported")) - $info['unsupported'] = true; + if (file_exists("view/theme/$theme/unsupported")) { + $info['unsupported'] = true; + } - if (!is_file("view/theme/$theme/php/theme.php")) - return $info; + if (!is_file("view/theme/$theme/php/theme.php")) { + return $info; + } - $f = file_get_contents("view/theme/$theme/php/theme.php"); - $r = preg_match("|/\*.*\*/|msU", $f, $m); + $f = file_get_contents("view/theme/$theme/php/theme.php"); + $r = preg_match("|/\*.*\*/|msU", $f, $m); - if ($r){ - $ll = explode("\n", $m[0]); - foreach( $ll as $l ) { - $l = trim($l, "\t\n\r */"); - if ($l != ""){ - list($k, $v) = array_map("trim", explode(":", $l, 2)); - $k = strtolower($k); - if ($k == 'author'){ - $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); - if ($r) { - $info['author'][] = array('name' => $m[1], 'link' => $m[2]); - } else { - $info['author'][] = array('name' => $v); - } - } - elseif ($k == 'maintainer'){ - $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); - if ($r) { - $info['maintainer'][] = array('name' => $m[1], 'link' => $m[2]); - } else { - $info['maintainer'][] = array('name' => $v); - } - } else { - if (array_key_exists($k, $info)){ - $info[$k] = $v; - } - } - } - } - } + if ($r) { + $ll = explode("\n", $m[0]); + foreach ($ll as $l) { + $l = trim($l, "\t\n\r */"); + if ($l != "") { + list($k, $v) = array_map("trim", explode(":", $l, 2)); + $k = strtolower($k); + if ($k == 'author') { + $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); + if ($r) { + $info['author'][] = array('name' => $m[1], 'link' => $m[2]); + } else { + $info['author'][] = array('name' => $v); + } + } elseif ($k == 'maintainer') { + $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); + if ($r) { + $info['maintainer'][] = array('name' => $m[1], 'link' => $m[2]); + } else { + $info['maintainer'][] = array('name' => $v); + } + } else { + if (array_key_exists($k, $info)) { + $info[$k] = $v; + } + } + } + } + } - return $info; + return $info; } /** @@ -785,15 +827,17 @@ function get_theme_info($theme){ * @param string $theme The name of the theme * @return string */ -function get_theme_screenshot($theme) { +function get_theme_screenshot($theme) +{ - $exts = array('.png', '.jpg'); - foreach($exts as $ext) { - if(file_exists('view/theme/' . $theme . '/img/screenshot' . $ext)) - return(z_root() . '/view/theme/' . $theme . '/img/screenshot' . $ext); - } + $exts = array('.png', '.jpg'); + foreach ($exts as $ext) { + if (file_exists('view/theme/' . $theme . '/img/screenshot' . $ext)) { + return(z_root() . '/view/theme/' . $theme . '/img/screenshot' . $ext); + } + } - return(z_root() . '/images/blank.png'); + return(z_root() . '/images/blank.png'); } /** @@ -802,77 +846,84 @@ function get_theme_screenshot($theme) { * @param string $src * @param string $media change media attribute (default to 'screen') */ -function head_add_css($src, $media = 'screen') { - App::$css_sources[] = array($src, $media); +function head_add_css($src, $media = 'screen') +{ + App::$css_sources[] = array($src, $media); } -function head_remove_css($src, $media = 'screen') { +function head_remove_css($src, $media = 'screen') +{ - $index = array_search(array($src, $media), App::$css_sources); - if($index !== false) - unset(App::$css_sources[$index]); + $index = array_search(array($src, $media), App::$css_sources); + if ($index !== false) { + unset(App::$css_sources[$index]); + } } -function head_get_css() { - $str = ''; - $sources = App::$css_sources; - if(count($sources)) { - foreach($sources as $source) - $str .= format_css_if_exists($source); - } +function head_get_css() +{ + $str = ''; + $sources = App::$css_sources; + if (count($sources)) { + foreach ($sources as $source) { + $str .= format_css_if_exists($source); + } + } - return $str; + return $str; } -function head_add_link($arr) { - if($arr) { - App::$linkrel[] = $arr; - } +function head_add_link($arr) +{ + if ($arr) { + App::$linkrel[] = $arr; + } } -function head_get_links() { - $str = ''; - $sources = App::$linkrel; - if(count($sources)) { - foreach($sources as $source) { - if(is_array($source) && count($source)) { - $str .= ' $v) { - $str .= ' ' . $k . '="' . $v . '"'; - } - $str .= ' />' . "\r\n"; +function head_get_links() +{ + $str = ''; + $sources = App::$linkrel; + if (count($sources)) { + foreach ($sources as $source) { + if (is_array($source) && count($source)) { + $str .= ' $v) { + $str .= ' ' . $k . '="' . $v . '"'; + } + $str .= ' />' . "\r\n"; + } + } + } - } - } - } - - return $str; + return $str; } -function format_css_if_exists($source) { +function format_css_if_exists($source) +{ - // script_path() returns https://yoursite.tld + // script_path() returns https://yoursite.tld - $path_prefix = script_path(); + $path_prefix = script_path(); - $script = $source[0]; + $script = $source[0]; - if(strpos($script, '/') !== false) { - // The script is a path relative to the server root - $path = $script; - // If the url starts with // then it's an absolute URL - if(substr($script,0,2) === '//') { - $path_prefix = ''; - } - } else { - // It's a file from the theme - $path = '/' . theme_include($script); - } + if (strpos($script, '/') !== false) { + // The script is a path relative to the server root + $path = $script; + // If the url starts with // then it's an absolute URL + if (substr($script, 0, 2) === '//') { + $path_prefix = ''; + } + } else { + // It's a file from the theme + $path = '/' . theme_include($script); + } - if($path) { - $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; - return '' . "\r\n"; - } + if ($path) { + $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; + return '' . "\r\n"; + } } /** @@ -885,46 +936,51 @@ function format_css_if_exists($source) { * * @return string */ -function script_path() { - if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) - $scheme = 'https'; - elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) - $scheme = 'https'; - elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') - $scheme = 'https'; - else - $scheme = 'http'; +function script_path() +{ + if (x($_SERVER, 'HTTPS') && $_SERVER['HTTPS']) { + $scheme = 'https'; + } elseif (x($_SERVER, 'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) { + $scheme = 'https'; + } elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') { + $scheme = 'https'; + } else { + $scheme = 'http'; + } - // Some proxy setups may require using http_host + // Some proxy setups may require using http_host - if(isset(App::$config['system']['script_path_use_http_host']) && intval(App::$config['system']['script_path_use_http_host'])) - $server_var = 'HTTP_HOST'; - else - $server_var = 'SERVER_NAME'; + if (isset(App::$config['system']['script_path_use_http_host']) && intval(App::$config['system']['script_path_use_http_host'])) { + $server_var = 'HTTP_HOST'; + } else { + $server_var = 'SERVER_NAME'; + } - if(x($_SERVER,$server_var)) { - $hostname = $_SERVER[$server_var]; - } - else { - return z_root(); - } + if (x($_SERVER, $server_var)) { + $hostname = $_SERVER[$server_var]; + } else { + return z_root(); + } - return $scheme . '://' . $hostname; + return $scheme . '://' . $hostname; } -function head_add_js($src, $priority = 0) { - if(! (isset(App::$js_sources[$priority]) && is_array(App::$js_sources[$priority]))) { - App::$js_sources[$priority] = []; - } - App::$js_sources[$priority][] = $src; +function head_add_js($src, $priority = 0) +{ + if (! (isset(App::$js_sources[$priority]) && is_array(App::$js_sources[$priority]))) { + App::$js_sources[$priority] = []; + } + App::$js_sources[$priority][] = $src; } -function head_remove_js($src, $priority = 0) { +function head_remove_js($src, $priority = 0) +{ - $index = array_search($src, App::$js_sources[$priority]); - if($index !== false) - unset(App::$js_sources[$priority][$index]); + $index = array_search($src, App::$js_sources[$priority]); + if ($index !== false) { + unset(App::$js_sources[$priority][$index]); + } } /** @@ -934,137 +990,149 @@ function head_remove_js($src, $priority = 0) { * * @return string */ -function head_get_js() { +function head_get_js() +{ - $str = ''; - if(App::$js_sources) { - ksort(App::$js_sources,SORT_NUMERIC); - foreach(App::$js_sources as $sources) { - if(count($sources)) { - foreach($sources as $source) { - if($source === 'main.js') - continue; - $str .= format_js_if_exists($source); - } - } - } - } + $str = ''; + if (App::$js_sources) { + ksort(App::$js_sources, SORT_NUMERIC); + foreach (App::$js_sources as $sources) { + if (count($sources)) { + foreach ($sources as $source) { + if ($source === 'main.js') { + continue; + } + $str .= format_js_if_exists($source); + } + } + } + } - return $str; + return $str; } -function head_get_main_js() { - $str = ''; - $sources = array('main.js'); - if(count($sources)) - foreach($sources as $source) - $str .= format_js_if_exists($source,true); +function head_get_main_js() +{ + $str = ''; + $sources = array('main.js'); + if (count($sources)) { + foreach ($sources as $source) { + $str .= format_js_if_exists($source, true); + } + } - return $str; + return $str; } -function format_js_if_exists($source) { - $path_prefix = script_path(); +function format_js_if_exists($source) +{ + $path_prefix = script_path(); - if(strpos($source,'/') !== false) { - // The source is a known path on the system - $path = $source; - // If the url starts with // then it's an absolute URL - if(substr($source,0,2) === '//') { - $path_prefix = ''; - } - } - else { - // It's a file from the theme - $path = '/' . theme_include($source); - } - if($path) { - $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; - return '' . "\r\n" ; - } + if (strpos($source, '/') !== false) { + // The source is a known path on the system + $path = $source; + // If the url starts with // then it's an absolute URL + if (substr($source, 0, 2) === '//') { + $path_prefix = ''; + } + } else { + // It's a file from the theme + $path = '/' . theme_include($source); + } + if ($path) { + $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; + return '' . "\r\n" ; + } } -function theme_include($file, $root = '') { +function theme_include($file, $root = '') +{ - // Make sure $root ends with a slash / if it's not blank - if($root !== '' && substr($root,-1) !== '/') - $root = $root . '/'; - $theme_info = App::$theme_info; + // Make sure $root ends with a slash / if it's not blank + if ($root !== '' && substr($root, -1) !== '/') { + $root = $root . '/'; + } + $theme_info = App::$theme_info; - if(array_key_exists('extends',$theme_info)) - $parent = $theme_info['extends']; - else - $parent = 'NOPATH'; + if (array_key_exists('extends', $theme_info)) { + $parent = $theme_info['extends']; + } else { + $parent = 'NOPATH'; + } - $theme = Zotlabs\Render\Theme::current(); - $thname = $theme[0]; + $theme = Zotlabs\Render\Theme::current(); + $thname = $theme[0]; - $ext = substr($file,strrpos($file,'.')+1); + $ext = substr($file, strrpos($file, '.')+1); - $paths = array( - "{$root}view/theme/$thname/$ext/$file", - "{$root}view/theme/$parent/$ext/$file", - "{$root}view/site/$ext/$file", - "{$root}view/$ext/$file", - ); + $paths = array( + "{$root}view/theme/$thname/$ext/$file", + "{$root}view/theme/$parent/$ext/$file", + "{$root}view/site/$ext/$file", + "{$root}view/$ext/$file", + ); - foreach($paths as $p) { - // strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php) - if(strpos($p,'NOPATH') !== false) - continue; - if(file_exists($p)) - return $p; - } + foreach ($paths as $p) { + // strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php) + if (strpos($p, 'NOPATH') !== false) { + continue; + } + if (file_exists($p)) { + return $p; + } + } - return ''; + return ''; } -function get_intltext_template($s, $root = '') { +function get_intltext_template($s, $root = '') +{ $testroot = ($root=='') ? $testroot = "ROOT" : $root; $t = App::template_engine(); - if (isset(App::$override_intltext_templates[$testroot][$s]["content"])) { - return App::$override_intltext_templates[$testroot][$s]["content"]; - } else { - if (isset(App::$override_intltext_templates[$testroot][$s]["root"]) && - isset(App::$override_intltext_templates[$testroot][$s]["file"])) { - $s = App::$override_intltext_templates[$testroot][$s]["file"]; - $root = App::$override_intltext_templates[$testroot][$s]["root"]; - } elseif (App::$override_templateroot) { - $newroot = App::$override_templateroot.$root; - if ($newroot != '' && substr($newroot,-1) != '/' ) { + if (isset(App::$override_intltext_templates[$testroot][$s]["content"])) { + return App::$override_intltext_templates[$testroot][$s]["content"]; + } else { + if (isset(App::$override_intltext_templates[$testroot][$s]["root"]) && + isset(App::$override_intltext_templates[$testroot][$s]["file"])) { + $s = App::$override_intltext_templates[$testroot][$s]["file"]; + $root = App::$override_intltext_templates[$testroot][$s]["root"]; + } elseif (App::$override_templateroot) { + $newroot = App::$override_templateroot.$root; + if ($newroot != '' && substr($newroot, -1) != '/') { $newroot .= '/'; - } - $template = $t->get_intltext_template($s, $newroot); - } - $template = $t->get_intltext_template($s, $root); - return $template; + } + $template = $t->get_intltext_template($s, $newroot); } + $template = $t->get_intltext_template($s, $root); + return $template; + } } -function get_markup_template($s, $root = '') { +function get_markup_template($s, $root = '') +{ $testroot = ($root=='') ? $testroot = "ROOT" : $root; $t = App::template_engine(); - if (isset(App::$override_markup_templates[$testroot][$s]["content"])) { - return App::$override_markup_templates[$testroot][$s]["content"]; - } else { - if (isset(App::$override_markup_templates[$testroot][$s]["root"]) && - isset(App::$override_markup_templates[$testroot][$s]["file"])) { - $s = App::$override_markup_templates[$testroot][$s]["file"]; - $root = App::$override_markup_templates[$testroot][$s]["root"]; - } elseif (App::$override_templateroot) { - $newroot = App::$override_templateroot.$root; - if ($newroot != '' && substr($newroot,-1) != '/' ) { + if (isset(App::$override_markup_templates[$testroot][$s]["content"])) { + return App::$override_markup_templates[$testroot][$s]["content"]; + } else { + if (isset(App::$override_markup_templates[$testroot][$s]["root"]) && + isset(App::$override_markup_templates[$testroot][$s]["file"])) { + $s = App::$override_markup_templates[$testroot][$s]["file"]; + $root = App::$override_markup_templates[$testroot][$s]["root"]; + } elseif (App::$override_templateroot) { + $newroot = App::$override_templateroot.$root; + if ($newroot != '' && substr($newroot, -1) != '/') { $newroot .= '/'; - } - $template = $t->get_markup_template($s, $newroot); - } - $template = $t->get_markup_template($s, $root); - return $template; + } + $template = $t->get_markup_template($s, $newroot); } + $template = $t->get_markup_template($s, $root); + return $template; + } } /** @@ -1073,10 +1141,11 @@ function get_markup_template($s, $root = '') { * @param string $folder * @return bool|string */ -function folder_exists($folder) { - // Get canonicalized absolute pathname - $path = realpath($folder); +function folder_exists($folder) +{ + // Get canonicalized absolute pathname + $path = realpath($folder); - // If it exist, check if it's a directory - return (($path !== false) && is_dir($path)) ? $path : false; + // If it exist, check if it's a directory + return (($path !== false) && is_dir($path)) ? $path : false; } diff --git a/include/api.php b/include/api.php index ec95967db..35c669f0c 100644 --- a/include/api.php +++ b/include/api.php @@ -11,248 +11,250 @@ require_once('include/attach.php'); require_once('include/api_auth.php'); require_once('include/api_zot.php'); - /* - * - * Zot API. - * - */ + /* + * + * Zot API. + * + */ - $API = []; + $API = []; - $called_api = null; + $called_api = null; - // All commands which require authentication accept a "channel" parameter - // which is the left hand side of the channel address/nickname. - // If provided, the desired channel is selected before carrying out the command. - // If not provided, the default channel associated with the account is used. - // If channel selection fails, the API command requiring login will fail. + // All commands which require authentication accept a "channel" parameter + // which is the left hand side of the channel address/nickname. + // If provided, the desired channel is selected before carrying out the command. + // If not provided, the default channel associated with the account is used. + // If channel selection fails, the API command requiring login will fail. - function api_user() { - $aid = get_account_id(); - $channel = App::get_channel(); - - if ($aid && isset($_REQUEST['channel']) && $_REQUEST['channel']) { +function api_user() +{ + $aid = get_account_id(); + $channel = App::get_channel(); + + if ($aid && isset($_REQUEST['channel']) && $_REQUEST['channel']) { + // Only change channel if it is different than the current channel - // Only change channel if it is different than the current channel - - if ($channel && isset($channel['channel_address']) && $channel['channel_address'] !== $_REQUEST['channel']) { - $c = q("select channel_id from channel where channel_address = '%s' and channel_account_id = %d limit 1", - dbesc($_REQUEST['channel']), - intval($aid) - ); - if ((! $c) || (! change_channel($c[0]['channel_id']))) { - return false; - } - } - } - if (isset($_SESSION['allow_api']) && $_SESSION['allow_api']) { - return local_channel(); - } - return false; - } + if ($channel && isset($channel['channel_address']) && $channel['channel_address'] !== $_REQUEST['channel']) { + $c = q( + "select channel_id from channel where channel_address = '%s' and channel_account_id = %d limit 1", + dbesc($_REQUEST['channel']), + intval($aid) + ); + if ((! $c) || (! change_channel($c[0]['channel_id']))) { + return false; + } + } + } + if (isset($_SESSION['allow_api']) && $_SESSION['allow_api']) { + return local_channel(); + } + return false; +} - function api_date($str) { - // Wed May 23 06:01:13 +0000 2007 - return datetime_convert('UTC', 'UTC', $str, 'D M d H:i:s +0000 Y' ); - } +function api_date($str) +{ + // Wed May 23 06:01:13 +0000 2007 + return datetime_convert('UTC', 'UTC', $str, 'D M d H:i:s +0000 Y'); +} - function api_register_func($path, $func, $auth = false) { - Api_router::register($path,$func,$auth); - } +function api_register_func($path, $func, $auth = false) +{ + Api_router::register($path, $func, $auth); +} - - /************************** - * MAIN API ENTRY POINT * - **************************/ + + /************************** + * MAIN API ENTRY POINT * + **************************/ - function api_call() { +function api_call() +{ - $p = App::$cmd; - $type = null; + $p = App::$cmd; + $type = null; - if (strrpos($p,'.')) { - $type = substr($p,strrpos($p,'.')+1); - if (strpos($type,'/') === false) { - $p = substr($p,0,strrpos($p,'.')); - // recalculate App argc,argv since we just extracted the type from it - App::$argv = explode('/',$p); - App::$argc = count(App::$argv); - } - } + if (strrpos($p, '.')) { + $type = substr($p, strrpos($p, '.')+1); + if (strpos($type, '/') === false) { + $p = substr($p, 0, strrpos($p, '.')); + // recalculate App argc,argv since we just extracted the type from it + App::$argv = explode('/', $p); + App::$argc = count(App::$argv); + } + } - if ((! $type) || (! in_array($type, [ 'json', 'xml', 'rss', 'as', 'atom' ]))) { - $type = 'json'; - } + if ((! $type) || (! in_array($type, [ 'json', 'xml', 'rss', 'as', 'atom' ]))) { + $type = 'json'; + } - $info = Api_router::find($p); + $info = Api_router::find($p); - if (in_array($type, [ 'rss', 'atom', 'as' ])) { - // These types no longer supported. - $info = false; - } + if (in_array($type, [ 'rss', 'atom', 'as' ])) { + // These types no longer supported. + $info = false; + } - logger('API info: ' . $p . ' type: ' . $type . ' ' . print_r($info,true), LOGGER_DEBUG,LOG_INFO); + logger('API info: ' . $p . ' type: ' . $type . ' ' . print_r($info, true), LOGGER_DEBUG, LOG_INFO); - if ($info) { + if ($info) { + if ($info['auth'] === true && api_user() === false) { + api_login(); + } - if ($info['auth'] === true && api_user() === false) { - api_login(); - } + load_contact_links(api_user()); - load_contact_links(api_user()); + $channel = App::get_channel(); - $channel = App::get_channel(); + logger('API call for ' . ((isset($channel) && is_array($channel)) ? $channel['channel_name'] : '') . ': ' . App::$query_string); + logger('API parameters: ' . print_r($_REQUEST, true)); - logger('API call for ' . ((isset($channel) && is_array($channel)) ? $channel['channel_name'] : '') . ': ' . App::$query_string); - logger('API parameters: ' . print_r($_REQUEST,true)); + $r = call_user_func($info['func'], $type); - $r = call_user_func($info['func'],$type); + if ($r === false) { + return; + } - if ($r === false) { - return; - } - - switch ($type) { - case 'xml': - header ('Content-Type: text/xml'); - return $r; - break; - case 'json': - header ('Content-Type: application/json'); - // Lookup JSONP to understand these lines. They provide cross-domain AJAX ability. - if ($_GET['callback']) { - $r = $_GET['callback'] . '(' . $r . ')' ; - } - return $r; - break; - } - - } + switch ($type) { + case 'xml': + header('Content-Type: text/xml'); + return $r; + break; + case 'json': + header('Content-Type: application/json'); + // Lookup JSONP to understand these lines. They provide cross-domain AJAX ability. + if ($_GET['callback']) { + $r = $_GET['callback'] . '(' . $r . ')' ; + } + return $r; + break; + } + } - $x = [ 'path' => App::$query_string ]; - call_hooks('api_not_found',$x); + $x = [ 'path' => App::$query_string ]; + call_hooks('api_not_found', $x); - header('HTTP/1.1 404 Not Found'); - logger('API call not implemented: ' . App::$query_string . ' - ' . print_r($_REQUEST,true)); - $r = 'not implemented'; - switch ($type){ - case 'xml': - header ('Content-Type: text/xml'); - return '' . "\n" . $r; - break; - case "json": - header ('Content-Type: application/json'); - return json_encode(array('error' => 'not implemented')); - break; - case "rss": - header ('Content-Type: application/rss+xml'); - return '' . "\n" . $r; - break; - case "atom": - header ('Content-Type: application/atom+xml'); - return '' . "\n" . $r; - break; - } - } + header('HTTP/1.1 404 Not Found'); + logger('API call not implemented: ' . App::$query_string . ' - ' . print_r($_REQUEST, true)); + $r = 'not implemented'; + switch ($type) { + case 'xml': + header('Content-Type: text/xml'); + return '' . "\n" . $r; + break; + case "json": + header('Content-Type: application/json'); + return json_encode(array('error' => 'not implemented')); + break; + case "rss": + header('Content-Type: application/rss+xml'); + return '' . "\n" . $r; + break; + case "atom": + header('Content-Type: application/atom+xml'); + return '' . "\n" . $r; + break; + } +} - /** - * load api $templatename for $type and replace $data array - */ + /** + * load api $templatename for $type and replace $data array + */ - function api_apply_template($templatename, $type, $data){ +function api_apply_template($templatename, $type, $data) +{ - switch ($type) { - case 'xml': - if ($data) { - foreach ($data as $k => $v) { - $ret = arrtoxml(str_replace('$','',$k),$v); - } - } - break; - case 'json': - default: - if ($data) { - foreach ($data as $rv) { - $ret = json_encode($rv); - } - } - break; - } + switch ($type) { + case 'xml': + if ($data) { + foreach ($data as $k => $v) { + $ret = arrtoxml(str_replace('$', '', $k), $v); + } + } + break; + case 'json': + default: + if ($data) { + foreach ($data as $rv) { + $ret = json_encode($rv); + } + } + break; + } - return $ret; - } - + return $ret; +} + - function api_client_register($type) { +function api_client_register($type) +{ - logger('api_client_register: ' . print_r($_REQUEST,true)); - - $ret = []; - $key = random_string(16); - $secret = random_string(16); - $name = trim(escape_tags($_REQUEST['client_name'])); - if (! $name) { - json_return_and_die($ret); - } - if (is_array($_REQUEST['redirect_uris'])) { - $redirect = trim($_REQUEST['redirect_uris'][0]); - } - else { - $redirect = trim($_REQUEST['redirect_uris']); - } - $grant_types = trim($_REQUEST['grant_types']); - $scope = trim($_REQUEST['scopes']); - $icon = trim($_REQUEST['logo_uri']); + logger('api_client_register: ' . print_r($_REQUEST, true)); + + $ret = []; + $key = random_string(16); + $secret = random_string(16); + $name = trim(escape_tags($_REQUEST['client_name'])); + if (! $name) { + json_return_and_die($ret); + } + if (is_array($_REQUEST['redirect_uris'])) { + $redirect = trim($_REQUEST['redirect_uris'][0]); + } else { + $redirect = trim($_REQUEST['redirect_uris']); + } + $grant_types = trim($_REQUEST['grant_types']); + $scope = trim($_REQUEST['scopes']); + $icon = trim($_REQUEST['logo_uri']); - $r = q("INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id, client_name) + $r = q( + "INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id, client_name) VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", - dbesc($key), - dbesc($secret), - dbesc($redirect), - dbesc($grant_types), - dbesc($scope), - dbesc((string) api_user()), - dbesc($name) - ); + dbesc($key), + dbesc($secret), + dbesc($redirect), + dbesc($grant_types), + dbesc($scope), + dbesc((string) api_user()), + dbesc($name) + ); - $ret['client_id'] = $key; - $ret['client_secret'] = $secret; - $ret['expires_at'] = 0; - json_return_and_die($ret); - } - - function api_oauth_request_token($type) { - try { - $oauth = new ZotOAuth1(); - $req = OAuth1Request::from_request(); - logger('Req: ' . var_export($req,true),LOGGER_DATA); - $r = $oauth->fetch_request_token($req); - } - catch(Exception $e) { - logger('oauth_exception: ' . print_r($e->getMessage(),true)); - echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage()); - killme(); - } - echo $r; - killme(); - } - - function api_oauth_access_token($type) { - try { - $oauth = new ZotOAuth1(); - $req = OAuth1Request::from_request(); - $r = $oauth->fetch_access_token($req); - } - catch(Exception $e) { - echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage()); - killme(); - } - echo $r; - killme(); - } + $ret['client_id'] = $key; + $ret['client_secret'] = $secret; + $ret['expires_at'] = 0; + json_return_and_die($ret); +} +function api_oauth_request_token($type) +{ + try { + $oauth = new ZotOAuth1(); + $req = OAuth1Request::from_request(); + logger('Req: ' . var_export($req, true), LOGGER_DATA); + $r = $oauth->fetch_request_token($req); + } catch (Exception $e) { + logger('oauth_exception: ' . print_r($e->getMessage(), true)); + echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage()); + killme(); + } + echo $r; + killme(); +} +function api_oauth_access_token($type) +{ + try { + $oauth = new ZotOAuth1(); + $req = OAuth1Request::from_request(); + $r = $oauth->fetch_access_token($req); + } catch (Exception $e) { + echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage()); + killme(); + } + echo $r; + killme(); +} diff --git a/include/api_auth.php b/include/api_auth.php index 08d68f504..4d249d2a1 100644 --- a/include/api_auth.php +++ b/include/api_auth.php @@ -16,172 +16,171 @@ require_once('include/security.php'); * API Login via basic-auth or OAuth */ -function api_login() { +function api_login() +{ - $record = null; - $remote_auth = false; - $sigblock = null; + $record = null; + $remote_auth = false; + $sigblock = null; - if (array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) { - $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER']; - } + if (array_key_exists('REDIRECT_REMOTE_USER', $_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION', $_SERVER))) { + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER']; + } - // login with oauth + // login with oauth - try { - // OAuth 2.0 - $storage = new OAuth2Storage(DBA::$dba->db); - $server = new OAuth2Server($storage); - $request = Request::createFromGlobals(); - if ($server->verifyResourceRequest($request)) { - $token = $server->getAccessTokenData($request); - $uid = $token['user_id']; - $r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1", - intval($uid) - ); - if ($r) { - $record = $r[0]; - } - else { - header('HTTP/1.0 401 Unauthorized'); - echo('This api requires login'); - killme(); - } + try { + // OAuth 2.0 + $storage = new OAuth2Storage(DBA::$dba->db); + $server = new OAuth2Server($storage); + $request = Request::createFromGlobals(); + if ($server->verifyResourceRequest($request)) { + $token = $server->getAccessTokenData($request); + $uid = $token['user_id']; + $r = q( + "SELECT * FROM channel WHERE channel_id = %d LIMIT 1", + intval($uid) + ); + if ($r) { + $record = $r[0]; + } else { + header('HTTP/1.0 401 Unauthorized'); + echo('This api requires login'); + killme(); + } - $_SESSION['uid'] = $record['channel_id']; - $_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; + $_SESSION['uid'] = $record['channel_id']; + $_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; - $x = q("select * from account where account_id = %d LIMIT 1", - intval($record['channel_account_id']) - ); - if ($x) { - require_once('include/security.php'); - authenticate_success($x[0], null, true, false, true, true); - $_SESSION['allow_api'] = true; - call_hooks('logged_in', App::$user); - return; - } - } - else { - // OAuth 1.0 - $oauth = new ZotOAuth1(); - $req = OAuth1Request::from_request(); + $x = q( + "select * from account where account_id = %d LIMIT 1", + intval($record['channel_account_id']) + ); + if ($x) { + require_once('include/security.php'); + authenticate_success($x[0], null, true, false, true, true); + $_SESSION['allow_api'] = true; + call_hooks('logged_in', App::$user); + return; + } + } else { + // OAuth 1.0 + $oauth = new ZotOAuth1(); + $req = OAuth1Request::from_request(); - list($consumer, $token) = $oauth->verify_request($req); + list($consumer, $token) = $oauth->verify_request($req); - if (! is_null($token)) { - $oauth->loginUser($token->uid); + if (! is_null($token)) { + $oauth->loginUser($token->uid); - App::set_oauth_key($consumer->key); + App::set_oauth_key($consumer->key); - call_hooks('logged_in', App::$user); - return; - } - - killme(); - } - } - catch (Exception $e) { - logger($e->getMessage()); - } + call_hooks('logged_in', App::$user); + return; + } + + killme(); + } + } catch (Exception $e) { + logger($e->getMessage()); + } - if (array_key_exists('HTTP_AUTHORIZATION',$_SERVER)) { + if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) { + /* Basic authentication */ - /* Basic authentication */ + if (substr(trim($_SERVER['HTTP_AUTHORIZATION']), 0, 5) === 'Basic') { + // ignore base64 decoding errors caused by tricksters + $userpass = @base64_decode(substr(trim($_SERVER['HTTP_AUTHORIZATION']), 6)) ; + if (strlen($userpass)) { + list($name, $password) = explode(':', $userpass); + $_SERVER['PHP_AUTH_USER'] = $name; + $_SERVER['PHP_AUTH_PW'] = $password; + } + } - if (substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,5) === 'Basic') { - // ignore base64 decoding errors caused by tricksters - $userpass = @base64_decode(substr(trim($_SERVER['HTTP_AUTHORIZATION']),6)) ; - if (strlen($userpass)) { - list($name, $password) = explode(':', $userpass); - $_SERVER['PHP_AUTH_USER'] = $name; - $_SERVER['PHP_AUTH_PW'] = $password; - } - } + /* OpenWebAuth */ - /* OpenWebAuth */ + if (substr(trim($_SERVER['HTTP_AUTHORIZATION']), 0, 9) === 'Signature') { + $record = null; - if (substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') { + $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); + if ($sigblock) { + $keyId = str_replace('acct:', '', $sigblock['keyId']); + if ($keyId) { + $r = q( + "select * from hubloc where hubloc_addr = '%s' or hubloc_id_url = '%s'", + dbesc($keyId), + dbesc($keyId) + ); + if (! $r) { + HTTPSig::get_zotfinger_key($keyId); + $r = q( + "select * from hubloc where hubloc_addr = '%s' or hubloc_id_url = '%s'", + dbesc($keyId), + dbesc($keyId) + ); + } - $record = null; + if ($r) { + $r = Libzot::zot_record_preferred($r); + $c = channelx_by_hash($r['hubloc_hash']); + if ($c) { + $a = q( + "select * from account where account_id = %d limit 1", + intval($c['channel_account_id']) + ); + if ($a) { + $record = [ 'channel' => $c, 'account' => $a[0] ]; + $channel_login = $c['channel_id']; + } + } + } - $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); - if ($sigblock) { - $keyId = str_replace('acct:','',$sigblock['keyId']); - if ($keyId) { - $r = q("select * from hubloc where hubloc_addr = '%s' or hubloc_id_url = '%s'", - dbesc($keyId), - dbesc($keyId) - ); - if (! $r) { - HTTPSig::get_zotfinger_key($keyId); - $r = q("select * from hubloc where hubloc_addr = '%s' or hubloc_id_url = '%s'", - dbesc($keyId), - dbesc($keyId) - ); - } - - if ($r) { - $r = Libzot::zot_record_preferred($r); - $c = channelx_by_hash($r['hubloc_hash']); - if ($c) { - $a = q("select * from account where account_id = %d limit 1", - intval($c['channel_account_id']) - ); - if ($a) { - $record = [ 'channel' => $c, 'account' => $a[0] ]; - $channel_login = $c['channel_id']; - } - } - } - - if ($record) { - $verified = HTTPSig::verify(EMPTY_STR,$record['channel']['channel_pubkey']); - if (! ($verified && $verified['header_signed'] && $verified['header_valid'])) { - $record = null; - } - } - } - } - } - } + if ($record) { + $verified = HTTPSig::verify(EMPTY_STR, $record['channel']['channel_pubkey']); + if (! ($verified && $verified['header_signed'] && $verified['header_valid'])) { + $record = null; + } + } + } + } + } + } - // process normal login request + // process normal login request - if (isset($_SERVER['PHP_AUTH_USER']) && (! $record)) { - $channel_login = 0; - $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']); - if ($record && $record['channel']) { - $channel_login = $record['channel']['channel_id']; - } - } + if (isset($_SERVER['PHP_AUTH_USER']) && (! $record)) { + $channel_login = 0; + $record = account_verify_password($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + if ($record && $record['channel']) { + $channel_login = $record['channel']['channel_id']; + } + } - if (isset($record['account'])) { - authenticate_success($record['account']); + if (isset($record['account'])) { + authenticate_success($record['account']); - if($channel_login) { - change_channel($channel_login); - } - - $_SESSION['allow_api'] = true; - return true; - } - else { - $_SERVER['PHP_AUTH_PW'] = '*****'; - logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG); - log_failed_login('API login failure'); - retry_basic_auth(); - } + if ($channel_login) { + change_channel($channel_login); + } + $_SESSION['allow_api'] = true; + return true; + } else { + $_SERVER['PHP_AUTH_PW'] = '*****'; + logger('API_login failure: ' . print_r($_SERVER, true), LOGGER_DEBUG); + log_failed_login('API login failure'); + retry_basic_auth(); + } } -function retry_basic_auth($method = 'Basic') { - header('WWW-Authenticate: ' . $method . ' realm="' . System::get_platform_name() . '"'); - header('HTTP/1.0 401 Unauthorized'); - echo( t('This api method requires authentication')); - killme(); +function retry_basic_auth($method = 'Basic') +{ + header('WWW-Authenticate: ' . $method . ' realm="' . System::get_platform_name() . '"'); + header('HTTP/1.0 401 Unauthorized'); + echo( t('This api method requires authentication')); + killme(); } - diff --git a/include/api_zot.php b/include/api_zot.php index 023691bd7..361865e05 100644 --- a/include/api_zot.php +++ b/include/api_zot.php @@ -2,582 +2,641 @@ use Zotlabs\Lib\MastAPI; - - - function zot_api_init() { - // mastodon API specific endpoints - api_register_func('api/v1/apps','api_client_register', false); - api_register_func('api/v1/instance','api_mast_instance',false); - - api_register_func('api/z/1.0/verify','api_verify', true); - api_register_func('api/red/version','api_zot_version',false); - api_register_func('api/z/1.0/version','api_zot_version',false); - api_register_func('api/export/basic','api_export_basic', true); - api_register_func('api/red/channel/export/basic','api_export_basic', true); - api_register_func('api/z/1.0/channel/export/basic','api_export_basic', true); - api_register_func('api/red/item/export_page','api_item_export_page', true); - api_register_func('api/z/1.0/item/export_page','api_item_export_page', true); - api_register_func('api/red/channel/list','api_channel_list', true); - api_register_func('api/z/1.0/channel/list','api_channel_list', true); - api_register_func('api/red/channel/stream','api_channel_stream', true); - api_register_func('api/z/1.0/channel/stream','api_channel_stream', true); - api_register_func('api/red/files','api_attach_list', true); - api_register_func('api/z/1.0/files','api_attach_list', true); - api_register_func('api/red/filemeta', 'api_file_meta', true); - api_register_func('api/z/1.0/filemeta', 'api_file_meta', true); - api_register_func('api/red/filedata', 'api_file_data', true); - api_register_func('api/z/1.0/filedata', 'api_file_data', true); - api_register_func('api/red/file/export', 'api_file_export', true); - api_register_func('api/z/1.0/file/export', 'api_file_export', true); - api_register_func('api/red/file', 'api_file_detail', true); - api_register_func('api/z/1.0/file', 'api_file_detail', true); - api_register_func('api/red/albums','api_albums', true); - api_register_func('api/z/1.0/albums','api_albums', true); - api_register_func('api/red/photos','api_photos', true); - api_register_func('api/z/1.0/photos','api_photos', true); - api_register_func('api/red/photo', 'api_photo_detail', true); - api_register_func('api/z/1.0/photo', 'api_photo_detail', true); - api_register_func('api/red/group_members','api_group_members', true); - api_register_func('api/z/1.0/group_members','api_group_members', true); - api_register_func('api/red/group','api_group', true); - api_register_func('api/z/1.0/group','api_group', true); - api_register_func('api/red/xchan','api_red_xchan',true); - api_register_func('api/z/1.0/xchan','api_red_xchan',true); - api_register_func('api/red/item/update','zot_item_update', true); - api_register_func('api/z/1.0/item/update','zot_item_update', true); - api_register_func('api/red/item/full','red_item', true); - api_register_func('api/z/1.0/item/full','red_item', true); - - api_register_func('api/z/1.0/network/stream','api_network_stream', true); - api_register_func('api/z/1.0/abook','api_zot_abook_xchan',true); - api_register_func('api/z/1.0/abconfig','api_zot_abconfig',true); - api_register_func('api/z/1.0/perm_allowed','api_zot_perm_allowed',true); - - return; - } - - - function api_verify($type) { - if (api_user() === false) { - logger('no channel'); - return false; - } - $channel = channelx_by_n(api_user()); - // logger('channel: ' . print_r($channel,true)); - - json_return_and_die($channel); - } - - - function api_zot_version($type) { - - if($type === 'xml') { - header('Content-type: application/xml'); - echo '' . "\r\n" . '' . Zotlabs\Lib\System::get_project_version() . '' . "\r\n"; - killme(); - } - elseif($type === 'json') { - header('Content-type: application/json'); - echo '"' . Zotlabs\Lib\System::get_project_version() . '"'; - killme(); - } - } - - function api_mast_instance($type) { - json_return_and_die(MastAPI::format_site()); - } - - - - /* - * basic channel export - */ - - function api_export_basic($type) { - if(api_user() === false) { - logger('api_export_basic: no user'); - return false; - } - $sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : ''); - if($_REQUEST['posts']) { - $sections = get_default_export_sections(); - $sections[] = 'items'; - } - - json_return_and_die(identity_basic_export(api_user(),$sections)); - } - - function api_item_export_page($type) { - if(api_user() === false) { - logger('api_item_export_page: no user'); - return false; - } - $page = intval($_REQUEST['page']); - $records = intval($_REQUEST['records']); - if(! $records) { - $records = 50; - } - if(! $_REQUEST['since']) - $start = NULL_DATE; - else { - $start = datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['since']); - } - $finish = datetime_convert(date_default_timezone_get(),'UTC', (($_REQUEST['until']) ? $_REQUEST['until'] : 'now')); - - json_return_and_die(channel_export_items_page(api_user(),$start,$finish,$page,$records)); - } - - - function api_network_stream($type) { - if(api_user() === false) { - logger('api_channel_stream: no user'); - return false; - } - - $channel = channelx_by_n(api_user()); - if(! $channel) - return false; - - - if($_SERVER['REQUEST_METHOD'] == 'POST') { - // json_return_and_die(post_activity_item($_REQUEST)); - } - else { - if(array_key_exists('dbegin',$_REQUEST)) - $_REQUEST['datequery2'] = $_REQUEST['dbegin']; - if(array_key_exists('dend',$_REQUEST)) - $_REQUEST['datequery'] = $_REQUEST['dend']; - - $arr = $_REQUEST; - $ret = []; - $i = items_fetch($arr,App::get_channel(),get_observer_hash()); - if($i) { - foreach($i as $iv) { - $ret[] = encode_item($iv); - } - } - - json_return_and_die($ret); - } - } - - function api_channel_list($type) { - if(api_user() === false) { - logger('api_channel_stream: no user'); - return false; - } - - $channel = channelx_by_n(api_user()); - if(! $channel) - return false; - - $ret = []; - - $r = q("select channel_address from channel where channel_account_id = %d", - intval($channel['channel_account_id']) - ); - - if($r) { - foreach($r as $rv) { - $ret[] = $rv['channel_address']; - } - } - - json_return_and_die($ret); - - } - - - function api_channel_stream($type) { - if(api_user() === false) { - logger('api_channel_stream: no user'); - return false; - } - - $channel = channelx_by_n(api_user()); - if(! $channel) - return false; - - - if($_SERVER['REQUEST_METHOD'] == 'POST') { - json_return_and_die(post_activity_item($_REQUEST)); - } - else { - $mindate = (($_REQUEST['mindate']) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['mindate']) : ''); - if(! $mindate) - $mindate = datetime_convert(date_default_timezone_get(),'UTC', 'now - 14 days'); - - json_return_and_die(zot_feed($channel['channel_id'],$channel['channel_hash'],[ 'mindate' => $mindate ])); - } - } - - function api_attach_list($type) { - if(api_user() === false) - return false; - - logger('api_user: ' . api_user()); - $hash = ((array_key_exists('filehash',$_REQUEST)) ? $_REQUEST['filehash'] : ''); - $filename = ((array_key_exists('filename',$_REQUEST)) ? $_REQUEST['filename'] : ''); - $filetype = ((array_key_exists('filetype',$_REQUEST)) ? $_REQUEST['filetype'] : ''); - $start = ((array_key_exists('start',$_REQUEST)) ? intval($_REQUEST['start']) : 0); - $records = ((array_key_exists('records',$_REQUEST)) ? intval($_REQUEST['records']) : 0); - - $since = ((array_key_exists('since',$_REQUEST)) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['since']) : NULL_DATE); - $until = ((array_key_exists('until',$_REQUEST)) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['until']) : datetime_convert()); - - $x = attach_list_files(api_user(),get_observer_hash(),$hash,$filename,$filetype,'created asc',$start,$records, $since, $until); - - if($start || $records) { - $x['start'] = $start; - $x['records'] = count($x['results']); - } - - json_return_and_die($x); - } - - - function api_file_meta($type) { - if(api_user() === false) - return false; - if(! $_REQUEST['file_id']) return false; - $r = q("select * from attach where uid = %d and hash = '%s' limit 1", - intval(api_user()), - dbesc($_REQUEST['file_id']) - ); - if($r) { - unset($r[0]['content']); - $ret = array('attach' => $r[0]); - json_return_and_die($ret); - } - killme(); - } - - - - function api_file_data($type) { - if(api_user() === false) - return false; - if(! $_REQUEST['file_id']) return false; - $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0); - $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0); - - $r = q("select * from attach where uid = %d and hash like '%s' limit 1", - intval(api_user()), - dbesc($_REQUEST['file_id'] . '%') - ); - if($r) { - $ptr = $r[0]; - if($length === 0) - $length = intval($ptr['filesize']); - - if($ptr['is_dir']) - $ptr['content'] = ''; - elseif(! intval($r[0]['os_storage'])) { - $ptr['start'] = $start; - $x = substr(dbunescbin($ptr['content']),$start,$length); - $ptr['length'] = strlen($x); - $ptr['content'] = base64_encode($x); - } - else { - $fp = fopen(dbunescbin($ptr['content']),'r'); - if($fp) { - $seek = fseek($fp,$start,SEEK_SET); - $x = fread($fp,$length); - $ptr['start'] = $start; - $ptr['length'] = strlen($x); - $ptr['content'] = base64_encode($x); - } - } - - $ret = array('attach' => $ptr); - json_return_and_die($ret); - } - killme(); - } - - - function api_file_export($type) { - if(api_user() === false) - return false; - if(! $_REQUEST['file_id']) - return false; - - $channel = channelx_by_n(api_user()); - - $ret = attach_export_data($channel,$_REQUEST['file_id']); - - if($ret) { - json_return_and_die($ret); - } - killme(); - } - - - function api_file_detail($type) { - if(api_user() === false) - return false; - if(! $_REQUEST['file_id']) return false; - $r = q("select * from attach where uid = %d and hash = '%s' limit 1", - intval(api_user()), - dbesc($_REQUEST['file_id']) - ); - if($r) { - if($r[0]['is_dir']) - $r[0]['content'] = ''; - elseif(intval($r[0]['os_storage'])) - $r[0]['content'] = base64_encode(file_get_contents(dbunescbin($r[0]['content']))); - else - $r[0]['content'] = base64_encode(dbunescbin($r[0]['content'])); - - $ret = array('attach' => $r[0]); - json_return_and_die($ret); - } - killme(); - } - - - - function api_albums($type) { - if(api_user() === false) - return false; - json_return_and_die(photos_albums_list(App::get_channel(),App::get_observer())); - } - - function api_photos($type) { - if(api_user() === false) - return false; - $album = $_REQUEST['album']; - json_return_and_die(photos_list_photos(App::get_channel(),App::get_observer(),$album)); - } - - function api_photo_detail($type) { - if(api_user() === false) - return false; - if(! $_REQUEST['photo_id']) return false; - $scale = ((array_key_exists('scale',$_REQUEST)) ? intval($_REQUEST['scale']) : 0); - $r = q("select * from photo where uid = %d and resource_id = '%s' and imgscale = %d limit 1", - intval(local_channel()), - dbesc($_REQUEST['photo_id']), - intval($scale) - ); - if($r) { - $data = dbunescbin($r[0]['content']); - if(array_key_exists('os_storage',$r[0]) && intval($r[0]['os_storage'])) - $data = file_get_contents($data); - $r[0]['content'] = base64_encode($data); - $ret = array('photo' => $r[0]); - $i = q("select id from item where uid = %d and resource_type = 'photo' and resource_id = '%s' limit 1", - intval(local_channel()), - dbesc($_REQUEST['photo_id']) - ); - if($i) { - $ii = q("select * from item where parent = %d order by id", - intval($i[0]['id']) - ); - if($ii) { - xchan_query($ii,true,0); - $ii = fetch_post_tags($ii,true); - if($ii) { - $ret['item'] = []; - foreach($ii as $iii) - $ret['item'][] = encode_item($iii,true); - } - } - } - - json_return_and_die($ret); - } - killme(); - } - - function api_group_members($type) { - if(api_user() === false) - return false; - - $r = null; - - if($_REQUEST['group_id']) { - $r = q("select * from pgrp where uid = %d and id = %d limit 1", - intval(api_user()), - intval($_REQUEST['group_id']) - ); - } - elseif($_REQUEST['group_name']) { - $r = q("select * from pgrp where uid = %d and gname = '%s' limit 1", - intval(api_user()), - dbesc($_REQUEST['group_name']) - ); - } - - if($r) { - $x = q("select * from pgrp_member left join abook on abook_xchan = xchan and abook_channel = pgrp_member.uid left join xchan on pgrp_member.xchan = xchan.xchan_hash +function zot_api_init() +{ + // mastodon API specific endpoints + api_register_func('api/v1/apps', 'api_client_register', false); + api_register_func('api/v1/instance', 'api_mast_instance', false); + + api_register_func('api/z/1.0/verify', 'api_verify', true); + api_register_func('api/red/version', 'api_zot_version', false); + api_register_func('api/z/1.0/version', 'api_zot_version', false); + api_register_func('api/export/basic', 'api_export_basic', true); + api_register_func('api/red/channel/export/basic', 'api_export_basic', true); + api_register_func('api/z/1.0/channel/export/basic', 'api_export_basic', true); + api_register_func('api/red/item/export_page', 'api_item_export_page', true); + api_register_func('api/z/1.0/item/export_page', 'api_item_export_page', true); + api_register_func('api/red/channel/list', 'api_channel_list', true); + api_register_func('api/z/1.0/channel/list', 'api_channel_list', true); + api_register_func('api/red/channel/stream', 'api_channel_stream', true); + api_register_func('api/z/1.0/channel/stream', 'api_channel_stream', true); + api_register_func('api/red/files', 'api_attach_list', true); + api_register_func('api/z/1.0/files', 'api_attach_list', true); + api_register_func('api/red/filemeta', 'api_file_meta', true); + api_register_func('api/z/1.0/filemeta', 'api_file_meta', true); + api_register_func('api/red/filedata', 'api_file_data', true); + api_register_func('api/z/1.0/filedata', 'api_file_data', true); + api_register_func('api/red/file/export', 'api_file_export', true); + api_register_func('api/z/1.0/file/export', 'api_file_export', true); + api_register_func('api/red/file', 'api_file_detail', true); + api_register_func('api/z/1.0/file', 'api_file_detail', true); + api_register_func('api/red/albums', 'api_albums', true); + api_register_func('api/z/1.0/albums', 'api_albums', true); + api_register_func('api/red/photos', 'api_photos', true); + api_register_func('api/z/1.0/photos', 'api_photos', true); + api_register_func('api/red/photo', 'api_photo_detail', true); + api_register_func('api/z/1.0/photo', 'api_photo_detail', true); + api_register_func('api/red/group_members', 'api_group_members', true); + api_register_func('api/z/1.0/group_members', 'api_group_members', true); + api_register_func('api/red/group', 'api_group', true); + api_register_func('api/z/1.0/group', 'api_group', true); + api_register_func('api/red/xchan', 'api_red_xchan', true); + api_register_func('api/z/1.0/xchan', 'api_red_xchan', true); + api_register_func('api/red/item/update', 'zot_item_update', true); + api_register_func('api/z/1.0/item/update', 'zot_item_update', true); + api_register_func('api/red/item/full', 'red_item', true); + api_register_func('api/z/1.0/item/full', 'red_item', true); + + api_register_func('api/z/1.0/network/stream', 'api_network_stream', true); + api_register_func('api/z/1.0/abook', 'api_zot_abook_xchan', true); + api_register_func('api/z/1.0/abconfig', 'api_zot_abconfig', true); + api_register_func('api/z/1.0/perm_allowed', 'api_zot_perm_allowed', true); + + return; +} + + +function api_verify($type) +{ + if (api_user() === false) { + logger('no channel'); + return false; + } + $channel = channelx_by_n(api_user()); + // logger('channel: ' . print_r($channel,true)); + + json_return_and_die($channel); +} + + +function api_zot_version($type) +{ + + if ($type === 'xml') { + header('Content-type: application/xml'); + echo '' . "\r\n" . '' . Zotlabs\Lib\System::get_project_version() . '' . "\r\n"; + killme(); + } elseif ($type === 'json') { + header('Content-type: application/json'); + echo '"' . Zotlabs\Lib\System::get_project_version() . '"'; + killme(); + } +} + +function api_mast_instance($type) +{ + json_return_and_die(MastAPI::format_site()); +} + + + + /* + * basic channel export + */ + +function api_export_basic($type) +{ + if (api_user() === false) { + logger('api_export_basic: no user'); + return false; + } + $sections = (($_REQUEST['sections']) ? explode(',', $_REQUEST['sections']) : ''); + if ($_REQUEST['posts']) { + $sections = get_default_export_sections(); + $sections[] = 'items'; + } + + json_return_and_die(identity_basic_export(api_user(), $sections)); +} + +function api_item_export_page($type) +{ + if (api_user() === false) { + logger('api_item_export_page: no user'); + return false; + } + $page = intval($_REQUEST['page']); + $records = intval($_REQUEST['records']); + if (! $records) { + $records = 50; + } + if (! $_REQUEST['since']) { + $start = NULL_DATE; + } else { + $start = datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['since']); + } + $finish = datetime_convert(date_default_timezone_get(), 'UTC', (($_REQUEST['until']) ? $_REQUEST['until'] : 'now')); + + json_return_and_die(channel_export_items_page(api_user(), $start, $finish, $page, $records)); +} + + +function api_network_stream($type) +{ + if (api_user() === false) { + logger('api_channel_stream: no user'); + return false; + } + + $channel = channelx_by_n(api_user()); + if (! $channel) { + return false; + } + + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + // json_return_and_die(post_activity_item($_REQUEST)); + } else { + if (array_key_exists('dbegin', $_REQUEST)) { + $_REQUEST['datequery2'] = $_REQUEST['dbegin']; + } + if (array_key_exists('dend', $_REQUEST)) { + $_REQUEST['datequery'] = $_REQUEST['dend']; + } + + $arr = $_REQUEST; + $ret = []; + $i = items_fetch($arr, App::get_channel(), get_observer_hash()); + if ($i) { + foreach ($i as $iv) { + $ret[] = encode_item($iv); + } + } + + json_return_and_die($ret); + } +} + +function api_channel_list($type) +{ + if (api_user() === false) { + logger('api_channel_stream: no user'); + return false; + } + + $channel = channelx_by_n(api_user()); + if (! $channel) { + return false; + } + + $ret = []; + + $r = q( + "select channel_address from channel where channel_account_id = %d", + intval($channel['channel_account_id']) + ); + + if ($r) { + foreach ($r as $rv) { + $ret[] = $rv['channel_address']; + } + } + + json_return_and_die($ret); +} + + +function api_channel_stream($type) +{ + if (api_user() === false) { + logger('api_channel_stream: no user'); + return false; + } + + $channel = channelx_by_n(api_user()); + if (! $channel) { + return false; + } + + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + json_return_and_die(post_activity_item($_REQUEST)); + } else { + $mindate = (($_REQUEST['mindate']) ? datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['mindate']) : ''); + if (! $mindate) { + $mindate = datetime_convert(date_default_timezone_get(), 'UTC', 'now - 14 days'); + } + + json_return_and_die(zot_feed($channel['channel_id'], $channel['channel_hash'], [ 'mindate' => $mindate ])); + } +} + +function api_attach_list($type) +{ + if (api_user() === false) { + return false; + } + + logger('api_user: ' . api_user()); + $hash = ((array_key_exists('filehash', $_REQUEST)) ? $_REQUEST['filehash'] : ''); + $filename = ((array_key_exists('filename', $_REQUEST)) ? $_REQUEST['filename'] : ''); + $filetype = ((array_key_exists('filetype', $_REQUEST)) ? $_REQUEST['filetype'] : ''); + $start = ((array_key_exists('start', $_REQUEST)) ? intval($_REQUEST['start']) : 0); + $records = ((array_key_exists('records', $_REQUEST)) ? intval($_REQUEST['records']) : 0); + + $since = ((array_key_exists('since', $_REQUEST)) ? datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['since']) : NULL_DATE); + $until = ((array_key_exists('until', $_REQUEST)) ? datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['until']) : datetime_convert()); + + $x = attach_list_files(api_user(), get_observer_hash(), $hash, $filename, $filetype, 'created asc', $start, $records, $since, $until); + + if ($start || $records) { + $x['start'] = $start; + $x['records'] = count($x['results']); + } + + json_return_and_die($x); +} + + +function api_file_meta($type) +{ + if (api_user() === false) { + return false; + } + if (! $_REQUEST['file_id']) { + return false; + } + $r = q( + "select * from attach where uid = %d and hash = '%s' limit 1", + intval(api_user()), + dbesc($_REQUEST['file_id']) + ); + if ($r) { + unset($r[0]['content']); + $ret = array('attach' => $r[0]); + json_return_and_die($ret); + } + killme(); +} + + + +function api_file_data($type) +{ + if (api_user() === false) { + return false; + } + if (! $_REQUEST['file_id']) { + return false; + } + $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0); + $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0); + + $r = q( + "select * from attach where uid = %d and hash like '%s' limit 1", + intval(api_user()), + dbesc($_REQUEST['file_id'] . '%') + ); + if ($r) { + $ptr = $r[0]; + if ($length === 0) { + $length = intval($ptr['filesize']); + } + + if ($ptr['is_dir']) { + $ptr['content'] = ''; + } elseif (! intval($r[0]['os_storage'])) { + $ptr['start'] = $start; + $x = substr(dbunescbin($ptr['content']), $start, $length); + $ptr['length'] = strlen($x); + $ptr['content'] = base64_encode($x); + } else { + $fp = fopen(dbunescbin($ptr['content']), 'r'); + if ($fp) { + $seek = fseek($fp, $start, SEEK_SET); + $x = fread($fp, $length); + $ptr['start'] = $start; + $ptr['length'] = strlen($x); + $ptr['content'] = base64_encode($x); + } + } + + $ret = array('attach' => $ptr); + json_return_and_die($ret); + } + killme(); +} + + +function api_file_export($type) +{ + if (api_user() === false) { + return false; + } + if (! $_REQUEST['file_id']) { + return false; + } + + $channel = channelx_by_n(api_user()); + + $ret = attach_export_data($channel, $_REQUEST['file_id']); + + if ($ret) { + json_return_and_die($ret); + } + killme(); +} + + +function api_file_detail($type) +{ + if (api_user() === false) { + return false; + } + if (! $_REQUEST['file_id']) { + return false; + } + $r = q( + "select * from attach where uid = %d and hash = '%s' limit 1", + intval(api_user()), + dbesc($_REQUEST['file_id']) + ); + if ($r) { + if ($r[0]['is_dir']) { + $r[0]['content'] = ''; + } elseif (intval($r[0]['os_storage'])) { + $r[0]['content'] = base64_encode(file_get_contents(dbunescbin($r[0]['content']))); + } else { + $r[0]['content'] = base64_encode(dbunescbin($r[0]['content'])); + } + + $ret = array('attach' => $r[0]); + json_return_and_die($ret); + } + killme(); +} + + + +function api_albums($type) +{ + if (api_user() === false) { + return false; + } + json_return_and_die(photos_albums_list(App::get_channel(), App::get_observer())); +} + +function api_photos($type) +{ + if (api_user() === false) { + return false; + } + $album = $_REQUEST['album']; + json_return_and_die(photos_list_photos(App::get_channel(), App::get_observer(), $album)); +} + +function api_photo_detail($type) +{ + if (api_user() === false) { + return false; + } + if (! $_REQUEST['photo_id']) { + return false; + } + $scale = ((array_key_exists('scale', $_REQUEST)) ? intval($_REQUEST['scale']) : 0); + $r = q( + "select * from photo where uid = %d and resource_id = '%s' and imgscale = %d limit 1", + intval(local_channel()), + dbesc($_REQUEST['photo_id']), + intval($scale) + ); + if ($r) { + $data = dbunescbin($r[0]['content']); + if (array_key_exists('os_storage', $r[0]) && intval($r[0]['os_storage'])) { + $data = file_get_contents($data); + } + $r[0]['content'] = base64_encode($data); + $ret = array('photo' => $r[0]); + $i = q( + "select id from item where uid = %d and resource_type = 'photo' and resource_id = '%s' limit 1", + intval(local_channel()), + dbesc($_REQUEST['photo_id']) + ); + if ($i) { + $ii = q( + "select * from item where parent = %d order by id", + intval($i[0]['id']) + ); + if ($ii) { + xchan_query($ii, true, 0); + $ii = fetch_post_tags($ii, true); + if ($ii) { + $ret['item'] = []; + foreach ($ii as $iii) { + $ret['item'][] = encode_item($iii, true); + } + } + } + } + + json_return_and_die($ret); + } + killme(); +} + +function api_group_members($type) +{ + if (api_user() === false) { + return false; + } + + $r = null; + + if ($_REQUEST['group_id']) { + $r = q( + "select * from pgrp where uid = %d and id = %d limit 1", + intval(api_user()), + intval($_REQUEST['group_id']) + ); + } elseif ($_REQUEST['group_name']) { + $r = q( + "select * from pgrp where uid = %d and gname = '%s' limit 1", + intval(api_user()), + dbesc($_REQUEST['group_name']) + ); + } + + if ($r) { + $x = q( + "select * from pgrp_member left join abook on abook_xchan = xchan and abook_channel = pgrp_member.uid left join xchan on pgrp_member.xchan = xchan.xchan_hash where gid = %d", - intval($r[0]['id']) - ); - json_return_and_die($x); - } + intval($r[0]['id']) + ); + json_return_and_die($x); + } +} - } +function api_group($type) +{ + if (api_user() === false) { + return false; + } - function api_group($type) { - if(api_user() === false) - return false; - - $r = q("select * from pgrp where uid = %d", - intval(api_user()) - ); - json_return_and_die($r); - } + $r = q( + "select * from pgrp where uid = %d", + intval(api_user()) + ); + json_return_and_die($r); +} - function api_red_xchan($type) { - if(api_user() === false) - return false; - logger('api_xchan'); +function api_red_xchan($type) +{ + if (api_user() === false) { + return false; + } + logger('api_xchan'); - if($_SERVER['REQUEST_METHOD'] === 'POST') { - logger('xchan_store called by ' . api_user()); - $r = xchan_store($_REQUEST); - } - $r = xchan_fetch($_REQUEST); - json_return_and_die($r); - } + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + logger('xchan_store called by ' . api_user()); + $r = xchan_store($_REQUEST); + } + $r = xchan_fetch($_REQUEST); + json_return_and_die($r); +} -function api_zot_abook_xchan($type) { - logger('api_abook_xchan'); +function api_zot_abook_xchan($type) +{ + logger('api_abook_xchan'); - if(api_user() === false) - return false; + if (api_user() === false) { + return false; + } - $sql_extra = ((array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : ''); - if($_SERVER['REQUEST_METHOD'] === 'POST') { - // update - } - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $sql_extra ", - intval(api_user()) - ); + $sql_extra = ((array_key_exists('abook_id', $_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : ''); + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + // update + } + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $sql_extra ", + intval(api_user()) + ); - json_return_and_die($r); - } + json_return_and_die($r); +} -function api_zot_abconfig($type) { +function api_zot_abconfig($type) +{ - if(api_user() === false) - return false; + if (api_user() === false) { + return false; + } - $sql_extra = ((array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : ''); - if($_SERVER['REQUEST_METHOD'] === 'POST') { - // update - } - $r = q("select abconfig.* from abconfig left join abook on abook_xchan = abconfig.xchan and abook_channel = abconfig.chan where abconfig.chan = %d $sql_extra ", - intval(api_user()) - ); + $sql_extra = ((array_key_exists('abook_id', $_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : ''); + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + // update + } + $r = q( + "select abconfig.* from abconfig left join abook on abook_xchan = abconfig.xchan and abook_channel = abconfig.chan where abconfig.chan = %d $sql_extra ", + intval(api_user()) + ); - json_return_and_die($r); + json_return_and_die($r); +} - } +function api_zot_perm_allowed($type) +{ + if (api_user() === false) { + return false; + } - function api_zot_perm_allowed($type) { - if(api_user() === false) - return false; + $perm = ((array_key_exists('perm', $_REQUEST)) ? $_REQUEST['perm'] : ''); - $perm = ((array_key_exists('perm',$_REQUEST)) ? $_REQUEST['perm'] : ''); + if (array_key_exists('abook_id', $_REQUEST) && intval($_REQUEST['abook_id'])) { + $r = q( + "select abook_xchan as hash from abook where abook_id = %d and abook_channel = %d limit 1", + intval($_REQUEST['abook_id']), + intval(api_user()) + ); + } else { + $r = xchan_fetch($_REQUEST); + } - if(array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) { - $r = q("select abook_xchan as hash from abook where abook_id = %d and abook_channel = %d limit 1", - intval($_REQUEST['abook_id']), - intval(api_user()) - ); - } - else { - $r = xchan_fetch($_REQUEST); - } + $x = false; - $x = false; + if ($r) { + if ($perm) { + $x = [ [ 'perm' => $perm, 'allowed' => perm_is_allowed(api_user(), $r[0]['hash'], $perm)] ]; + } else { + $x = []; + $p = get_all_perms(api_user(), $r[0]['hash']); + if ($p) { + foreach ($p as $k => $v) { + $x[] = [ 'perm' => $k, 'allowed' => $v ]; + } + } + } + } + + json_return_and_die($x); +} - if($r) { - if($perm) - $x = [ [ 'perm' => $perm, 'allowed' => perm_is_allowed(api_user(), $r[0]['hash'], $perm)] ]; - else { - $x = []; - $p = get_all_perms(api_user(),$r[0]['hash']); - if($p) { - foreach($p as $k => $v) - $x[] = [ 'perm' => $k, 'allowed' => $v ]; - } - } - } - - json_return_and_die($x); +function zot_item_update($type) +{ - } + if (api_user() === false) { + logger('api_red_item_store: no user'); + return false; + } - function zot_item_update($type) { - - if (api_user() === false) { - logger('api_red_item_store: no user'); - return false; - } - - logger('api_red_item_store: REQUEST ' . print_r($_REQUEST,true)); - logger('api_red_item_store: FILES ' . print_r($_FILES,true)); + logger('api_red_item_store: REQUEST ' . print_r($_REQUEST, true)); + logger('api_red_item_store: FILES ' . print_r($_FILES, true)); - // set this so that the item_post() function is quiet and doesn't redirect or emit json + // set this so that the item_post() function is quiet and doesn't redirect or emit json - $_REQUEST['api_source'] = true; - $_REQUEST['profile_uid'] = api_user(); + $_REQUEST['api_source'] = true; + $_REQUEST['profile_uid'] = api_user(); - if(x($_FILES,'media')) { - $_FILES['userfile'] = $_FILES['media']; - // upload the image if we have one - $mod = new Zotlabs\Module\Wall_attach(); - $media = $mod->post(); - if($media) - $_REQUEST['body'] .= "\n\n" . $media; - } + if (x($_FILES, 'media')) { + $_FILES['userfile'] = $_FILES['media']; + // upload the image if we have one + $mod = new Zotlabs\Module\Wall_attach(); + $media = $mod->post(); + if ($media) { + $_REQUEST['body'] .= "\n\n" . $media; + } + } - $mod = new Zotlabs\Module\Item(); - $x = $mod->post(); - json_return_and_die($x); - } + $mod = new Zotlabs\Module\Item(); + $x = $mod->post(); + json_return_and_die($x); +} - function red_item($type) { +function red_item($type) +{ - if (api_user() === false) { - logger('api_red_item_full: no user'); - return false; - } + if (api_user() === false) { + logger('api_red_item_full: 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([]); + if ($_REQUEST['mid']) { + $arr = array('mid' => $_REQUEST['mid']); + } elseif ($_REQUEST['item_id']) { + $arr = array('item_id' => $_REQUEST['item_id']); + } else { + json_return_and_die([]); + } - $arr['start'] = 0; - $arr['records'] = 999999; - $arr['item_type'] = '*'; - - $i = items_fetch($arr,App::get_channel(),get_observer_hash()); - - if(! $i) - json_return_and_die([]); - - $ret = []; - $tmp = []; - foreach($i as $ii) { - $tmp[] = encode_item($ii,true); - } - $ret['item'] = $tmp; - - json_return_and_die($ret); - } + $arr['start'] = 0; + $arr['records'] = 999999; + $arr['item_type'] = '*'; + $i = items_fetch($arr, App::get_channel(), get_observer_hash()); + if (! $i) { + json_return_and_die([]); + } + $ret = []; + $tmp = []; + foreach ($i as $ii) { + $tmp[] = encode_item($ii, true); + } + $ret['item'] = $tmp; + + json_return_and_die($ret); +} diff --git a/include/attach.php b/include/attach.php index 9e78688e8..086d6c06c 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1,4 +1,5 @@ 'text/plain', - 'htm' => 'text/html', - 'html' => 'text/html', - 'css' => 'text/css', - 'md' => 'text/markdown', - 'bb' => 'text/bbcode', - 'abc' => 'text/vnd.abc', - 'csv' => 'text/csv', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'xml' => 'application/xml', - 'swf' => 'application/x-shockwave-flash', - 'flv' => 'video/x-flv', - 'epub' => 'application/epub+zip', - 'c' => 'text/plain', - 'h' => 'text/plain', - 'sh' => 'text/plain', - 'py' => 'text/plain', - 'php' => 'text/plain', - 'rb' => 'text/plain', - 'pdl' => 'text/plain', - 'ics' => 'text/calendar', + 'txt' => 'text/plain', + 'htm' => 'text/html', + 'html' => 'text/html', + 'css' => 'text/css', + 'md' => 'text/markdown', + 'bb' => 'text/bbcode', + 'abc' => 'text/vnd.abc', + 'csv' => 'text/csv', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'xml' => 'application/xml', + 'swf' => 'application/x-shockwave-flash', + 'flv' => 'video/x-flv', + 'epub' => 'application/epub+zip', + 'c' => 'text/plain', + 'h' => 'text/plain', + 'sh' => 'text/plain', + 'py' => 'text/plain', + 'php' => 'text/plain', + 'rb' => 'text/plain', + 'pdl' => 'text/plain', + 'ics' => 'text/calendar', - // images + // images - 'png' => 'image/png', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'webp' => 'image/webp', - 'ico' => 'image/vnd.microsoft.icon', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', + 'png' => 'image/png', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'webp' => 'image/webp', + 'ico' => 'image/vnd.microsoft.icon', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', - // archives - 'zip' => 'application/zip', - 'rar' => 'application/x-rar-compressed', - 'exe' => 'application/x-msdownload', - 'msi' => 'application/x-msdownload', - 'cab' => 'application/vnd.ms-cab-compressed', + // archives + 'zip' => 'application/zip', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', - // audio/video - 'mp3' => 'audio/mpeg', - 'wav' => 'audio/wav', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'flac' => 'audio/flac', - 'opus' => 'audio/ogg', - 'webm' => 'video/webm', - 'mp4' => 'video/mp4', - 'mkv' => 'video/x-matroska', + // audio/video + 'mp3' => 'audio/mpeg', + 'wav' => 'audio/wav', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'flac' => 'audio/flac', + 'opus' => 'audio/ogg', + 'webm' => 'video/webm', + 'mp4' => 'video/mp4', + 'mkv' => 'video/x-matroska', - // adobe - 'pdf' => 'application/pdf', - 'psd' => 'image/vnd.adobe.photoshop', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', + // adobe + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', - // ms office - 'doc' => 'application/msword', - 'rtf' => 'application/rtf', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', + // ms office + 'doc' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', - // open office - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odb' => 'application/vnd.oasis.opendocument.base', - 'odb' => 'application/vnd.oasis.opendocument.database', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', - 'otp' => 'application/vnd.oasis.opendocument.presentation-template', - 'otg' => 'application/vnd.oasis.opendocument.graphics-template', - 'otc' => 'application/vnd.oasis.opendocument.chart-template', - 'otf' => 'application/vnd.oasis.opendocument.formula-template', - 'oti' => 'application/vnd.oasis.opendocument.image-template', - 'oth' => 'application/vnd.oasis.opendocument.text-web' - ); + // open office + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odb' => 'application/vnd.oasis.opendocument.base', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web' + ); - $last_dot = strrpos($filename, '.'); - if ($last_dot !== false) { - $ext = strtolower(substr($filename, $last_dot + 1)); - if (array_key_exists($ext, $mime_types)) { - return $mime_types[$ext]; - } - } + $last_dot = strrpos($filename, '.'); + if ($last_dot !== false) { + $ext = strtolower(substr($filename, $last_dot + 1)); + if (array_key_exists($ext, $mime_types)) { + return $mime_types[$ext]; + } + } - return 'application/octet-stream'; + return 'application/octet-stream'; } /** @@ -149,35 +151,37 @@ function z_mime_content_type($filename) { * * \e int|boolean \b results amount of found results, or false * * \e string \b message with error messages if any */ -function attach_count_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '') { +function attach_count_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '') +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - if (! perm_is_allowed($channel_id, $observer, 'read_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($channel_id, $observer, 'read_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - require_once('include/security.php'); - $sql_extra = permissions_sql($channel_id); + require_once('include/security.php'); + $sql_extra = permissions_sql($channel_id); - if ($hash) { - $sql_extra .= protect_sprintf(" and hash = '" . dbesc($hash) . "' "); - } - if ($filename) { - $sql_extra .= protect_sprintf(" and filename like '@" . dbesc($filename) . "@' "); - } - if ($filetype) { - $sql_extra .= protect_sprintf(" and filetype like '@" . dbesc($filetype) . "@' "); - } - $r = q("select id, uid, folder from attach where uid = %d $sql_extra", - intval($channel_id) - ); + if ($hash) { + $sql_extra .= protect_sprintf(" and hash = '" . dbesc($hash) . "' "); + } + if ($filename) { + $sql_extra .= protect_sprintf(" and filename like '@" . dbesc($filename) . "@' "); + } + if ($filetype) { + $sql_extra .= protect_sprintf(" and filetype like '@" . dbesc($filetype) . "@' "); + } + $r = q( + "select id, uid, folder from attach where uid = %d $sql_extra", + intval($channel_id) + ); - $ret['success'] = ((is_array($r)) ? true : false); - $ret['results'] = ((is_array($r)) ? count($r) : false); + $ret['success'] = ((is_array($r)) ? true : false); + $ret['results'] = ((is_array($r)) ? count($r) : false); - return $ret; + return $ret; } /** @@ -196,50 +200,52 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '', * * \e array|boolean \b results array with results, or false * * \e string \b message with error messages if any */ -function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '', $orderby = 'created desc', $start = 0, $entries = 0, $since = '', $until = '') { +function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '', $orderby = 'created desc', $start = 0, $entries = 0, $since = '', $until = '') +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - if (! perm_is_allowed($channel_id,$observer, 'view_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($channel_id, $observer, 'view_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - require_once('include/security.php'); - $sql_extra = permissions_sql($channel_id); + require_once('include/security.php'); + $sql_extra = permissions_sql($channel_id); - if ($hash) { - $sql_extra .= protect_sprintf(" and hash = '" . dbesc($hash) . "' "); - } - if ($filename) { - $sql_extra .= protect_sprintf(" and filename like '%" . dbesc($filename) . "%' "); - } - if ($filetype) { - $sql_extra .= protect_sprintf(" and filetype like '%" . dbesc($filetype) . "%' "); - } - if ($entries) { - $limit = " limit " . intval($start) . ", " . intval($entries) . " "; - } - if (! $since) { - $since = NULL_DATE; - } - if (! $until) { - $until = datetime_convert(); - } - - $sql_extra .= " and created >= '" . dbesc($since) . "' and created <= '" . dbesc($until) . "' "; + if ($hash) { + $sql_extra .= protect_sprintf(" and hash = '" . dbesc($hash) . "' "); + } + if ($filename) { + $sql_extra .= protect_sprintf(" and filename like '%" . dbesc($filename) . "%' "); + } + if ($filetype) { + $sql_extra .= protect_sprintf(" and filetype like '%" . dbesc($filetype) . "%' "); + } + if ($entries) { + $limit = " limit " . intval($start) . ", " . intval($entries) . " "; + } + if (! $since) { + $since = NULL_DATE; + } + if (! $until) { + $until = datetime_convert(); + } - // Retrieve all columns except 'content' + $sql_extra .= " and created >= '" . dbesc($since) . "' and created <= '" . dbesc($until) . "' "; - $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_path, display_path, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit", - intval($channel_id) - ); + // Retrieve all columns except 'content' - $ret['success'] = ((is_array($r)) ? true : false); - $ret['results'] = ((is_array($r)) ? $r : []); + $r = q( + "select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_path, display_path, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit", + intval($channel_id) + ); - return $ret; + $ret['success'] = ((is_array($r)) ? true : false); + $ret['results'] = ((is_array($r)) ? $r : []); + + return $ret; } /** @@ -254,110 +260,115 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $ * @param int $rev (optional) Revision default 0 * @return array */ -function attach_by_hash($hash, $observer_hash, $rev = 0) { +function attach_by_hash($hash, $observer_hash, $rev = 0) +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - // Check for existence, which will also provide us the owner uid + // Check for existence, which will also provide us the owner uid - $sql_extra = ''; - if ($rev == (-1)) { - $sql_extra = " order by revision desc "; - } - elseif ($rev) { - $sql_extra = " and revision = " . intval($rev) . " "; - } - - $r = q("SELECT uid FROM attach WHERE hash = '%s' $sql_extra LIMIT 1", - dbesc($hash) - ); - if (! $r) { - $ret['message'] = t('Item was not found.'); - return $ret; - } + $sql_extra = ''; + if ($rev == (-1)) { + $sql_extra = " order by revision desc "; + } elseif ($rev) { + $sql_extra = " and revision = " . intval($rev) . " "; + } - if (! attach_can_view($r[0]['uid'], $observer_hash, $hash)) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + $r = q( + "SELECT uid FROM attach WHERE hash = '%s' $sql_extra LIMIT 1", + dbesc($hash) + ); + if (! $r) { + $ret['message'] = t('Item was not found.'); + return $ret; + } - // We've already checked for existence and permissions + if (! attach_can_view($r[0]['uid'], $observer_hash, $hash)) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - $r = q("SELECT * FROM attach WHERE hash = '%s' and uid = %d $sql_extra LIMIT 1", - dbesc($hash), - intval($r[0]['uid']) - ); + // We've already checked for existence and permissions - if (! $r) { - $ret['message'] = t('Unknown error.'); - return $ret; - } + $r = q( + "SELECT * FROM attach WHERE hash = '%s' and uid = %d $sql_extra LIMIT 1", + dbesc($hash), + intval($r[0]['uid']) + ); - $r[0]['content'] = dbunescbin($r[0]['content']); + if (! $r) { + $ret['message'] = t('Unknown error.'); + return $ret; + } - $ret['success'] = true; - $ret['data'] = array_shift($r); + $r[0]['content'] = dbunescbin($r[0]['content']); - return $ret; + $ret['success'] = true; + $ret['data'] = array_shift($r); + + return $ret; } -function attach_can_view($uid,$ob_hash,$resource,$token = EMPTY_STR) { +function attach_can_view($uid, $ob_hash, $resource, $token = EMPTY_STR) +{ - $sql_extra = permissions_sql($uid,$ob_hash,'',$token); - $hash = $resource; + $sql_extra = permissions_sql($uid, $ob_hash, '', $token); + $hash = $resource; - if (! $token) { - if (! perm_is_allowed($uid,$ob_hash,'view_storage')) { - return false; - } - } + if (! $token) { + if (! perm_is_allowed($uid, $ob_hash, 'view_storage')) { + return false; + } + } - $r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra", - dbesc($hash), - intval($uid) - ); + $r = q( + "select folder from attach where hash = '%s' and uid = %d $sql_extra", + dbesc($hash), + intval($uid) + ); - if (! $r) { - return false; - } + if (! $r) { + return false; + } - // don't perform recursive folder check when using OCAP. Only when using ACL access. - // For OCAP if the token is valid they can see the thing. - - if ($token) { - return true; - } + // don't perform recursive folder check when using OCAP. Only when using ACL access. + // For OCAP if the token is valid they can see the thing. - return attach_can_view_folder($uid,$ob_hash,$r[0]['folder'],$token); + if ($token) { + return true; + } + return attach_can_view_folder($uid, $ob_hash, $r[0]['folder'], $token); } -function attach_can_view_folder($uid,$ob_hash,$folder_hash,$token = EMPTY_STR) { +function attach_can_view_folder($uid, $ob_hash, $folder_hash, $token = EMPTY_STR) +{ - $sql_extra = permissions_sql($uid,$ob_hash,'',$token); - $hash = $folder_hash; - $result = false; + $sql_extra = permissions_sql($uid, $ob_hash, '', $token); + $hash = $folder_hash; + $result = false; - if ((! $folder_hash) && (! $token)) { - return perm_is_allowed($uid,$ob_hash,'view_storage'); - } + if ((! $folder_hash) && (! $token)) { + return perm_is_allowed($uid, $ob_hash, 'view_storage'); + } - do { - $r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra", - dbesc($hash), - intval($uid) - ); - if (! $r) { - return false; - } - $hash = $r[0]['folder']; - } while($hash); + do { + $r = q( + "select folder from attach where hash = '%s' and uid = %d $sql_extra", + dbesc($hash), + intval($uid) + ); + if (! $r) { + return false; + } + $hash = $r[0]['folder']; + } while ($hash); - return true; + return true; } @@ -375,59 +386,61 @@ function attach_can_view_folder($uid,$ob_hash,$folder_hash,$token = EMPTY_STR) { * * \e string \b message (optional) only when success is false * * \e array \b data array of attach DB entry without data component */ -function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) { +function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - // Check for existence, which will also provide us the owner uid + // Check for existence, which will also provide us the owner uid - $sql_extra = ''; - if ($rev == (-1)) { - $sql_extra = " order by revision desc "; - } - elseif ($rev) { - $sql_extra = " and revision = " . intval($rev) . " "; - } + $sql_extra = ''; + if ($rev == (-1)) { + $sql_extra = " order by revision desc "; + } elseif ($rev) { + $sql_extra = " and revision = " . intval($rev) . " "; + } - $r = q("SELECT uid FROM attach WHERE hash = '%s' $sql_extra LIMIT 1", - dbesc($hash) - ); - if (! $r) { - $ret['message'] = t('Item was not found.'); - return $ret; - } + $r = q( + "SELECT uid FROM attach WHERE hash = '%s' $sql_extra LIMIT 1", + dbesc($hash) + ); + if (! $r) { + $ret['message'] = t('Item was not found.'); + return $ret; + } - if (! perm_is_allowed($r[0]['uid'], $observer_hash, 'view_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($r[0]['uid'], $observer_hash, 'view_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - $sql_extra = permissions_sql($r[0]['uid'], $observer_hash); + $sql_extra = permissions_sql($r[0]['uid'], $observer_hash); - // Now we'll see if we can access the attachment + // Now we'll see if we can access the attachment - $a = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, os_path, display_path, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1", - intval($r[0]['uid']), - dbesc($hash) - ); + $a = q( + "select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, os_path, display_path, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1", + intval($r[0]['uid']), + dbesc($hash) + ); - if (! $a) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! $a) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - if ($a[0]['folder']) { - $x = attach_can_view_folder($a[0]['uid'], $observer_hash, $a[0]['folder']); - if (! $x) { - $ret['message'] = t('Permission denied.'); - return $ret; - } - } + if ($a[0]['folder']) { + $x = attach_can_view_folder($a[0]['uid'], $observer_hash, $a[0]['folder']); + if (! $x) { + $ret['message'] = t('Permission denied.'); + return $ret; + } + } - $ret['success'] = true; - $ret['data'] = array_shift($a); + $ret['success'] = true; + $ret['data'] = array_shift($a); - return $ret; + return $ret; } /** @@ -465,599 +478,633 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) { * @param array $arr (optional) associative array * @return void|array */ -function attach_store($channel, $observer_hash, $options = '', $arr = null) { - - require_once('include/photos.php'); - - /** - * @hooks photo_upload_begin - * Called when attempting to upload a photo. - */ - call_hooks('photo_upload_begin', $arr); - - $ret = array('success' => false); - $channel_id = $channel['channel_id']; - $sql_options = ''; - $source = (($arr) ? $arr['source'] : ''); - $album = (($arr) ? $arr['album'] : ''); - $newalbum = (($arr) ? $arr['newalbum'] : ''); - $hash = (($arr && $arr['hash']) ? $arr['hash'] : null); - $upload_path = (($arr && $arr['directory']) ? $arr['directory'] : ''); - $visible = (($arr && $arr['visible']) ? $arr['visible'] : ''); - $notify = (($arr && $arr['notify']) ? $arr['notify'] : ''); - $flags = (($arr && array_key_exists('flags',$arr)) ? intval($arr['flags']) : 0); - $observer = []; - - $dosync = ((array_key_exists('nosync',$arr) && $arr['nosync']) ? 0 : 1); - - if($observer_hash) { - $observer = xchan_match([ 'xchan_hash' => $observer_hash ]); - } - - logger('arr: ' . print_r($arr,true), LOGGER_DATA); - - if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } - - $str_group_allow = perms2str($arr['group_allow']); - $str_contact_allow = perms2str($arr['contact_allow']); - $str_group_deny = perms2str($arr['group_deny']); - $str_contact_deny = perms2str($arr['contact_deny']); - - - // The 'update' option sets db values without uploading a new attachment - // 'replace' replaces the existing uploaded data - // 'revision' creates a new revision with new upload data - // Default is to upload a new file - - // revise or update must provide $arr['hash'] of the thing to revise/update - - // By default remove $src when finished - - $remove_when_processed = true; - $import_replace = false; - - if($options === 'import') { - $src = $arr['src']; - $filename = $arr['filename']; - $filesize = @filesize($src); - - $hash = $arr['resource_id']; - - if(array_key_exists('hash',$arr)) - $hash = $arr['hash']; - if(array_key_exists('type',$arr)) - $type = $arr['type']; - - if($arr['preserve_original']) - $remove_when_processed = false; - - if($arr['replace']) - $import_replace = true; - - // if importing a directory, just do it now and go home - we're done. - - if(array_key_exists('is_dir',$arr) && intval($arr['is_dir'])) { - $x = attach_mkdir($channel,$observer_hash,$arr); - if($x['message']) - logger('import_directory: ' . $x['message']); - - return; - } - } - elseif($options !== 'update') { - $f = [ - 'src' => '', - 'filename' => '', - 'filesize' => 0, - 'type' => '' - ]; - - /** - * @hooks photo_upload_file - * Called to generate alternate filenames for an upload. - * * \e string \b src - return value, default empty - * * \e string \b filename - return value, default empty - * * \e number \b filesize - return value, default 0 - * * \e string \b type - return value, default empty - */ - call_hooks('photo_upload_file', $f); - /** - * @hooks attach_upload_file - * Called when uploading a file. - * * \e string \b src - return value, default empty - * * \e string \b filename - return value, default empty - * * \e number \b filesize - return value, default 0 - * * \e string \b type - return value, default empty - */ - 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')) { - logger('No source file'); - $ret['message'] = t('No source file.'); - return $ret; - } - - $src = $_FILES['userfile']['tmp_name']; - $filename = basename($_FILES['userfile']['name']); - $filesize = intval($_FILES['userfile']['size']); - } - } - - // AndStatus sends jpegs with a non-standard mimetype - if($type === 'image/jpg') - $type = 'image/jpeg'; - - $existing_size = 0; - - if($options === 'replace') { - $x = q("select id, hash, filesize from attach where id = %d and uid = %d limit 1", - intval($arr['id']), - intval($channel_id) - ); - if(! $x) { - $ret['message'] = t('Cannot locate file to replace'); - return $ret; - } - $existing_id = $x[0]['id']; - $existing_size = intval($x[0]['filesize']); - $hash = $x[0]['hash']; - } - - if($options === 'revise' || $options === 'update') { - $sql_options = " order by revision desc "; - if($options === 'update' && $arr && array_key_exists('revision',$arr)) - $sql_options = " and revision = " . intval($arr['revision']) . " "; - - $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, os_path, display_path, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1", - dbesc($arr['hash']), - intval($channel_id) - ); - if(! $x) { - logger('update file source not found'); - $ret['message'] = t('Cannot locate file to revise/update'); - return $ret; - } - $hash = $x[0]['hash']; - } - - $def_extension = ''; - $is_photo = 0; - $gis = false; - - if ($src) { - $gis = @getimagesize($src); - logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA); - } - - if(($gis) && in_array($gis[2], [ IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_WEBP ])) { - $is_photo = 1; - if($gis[2] === IMAGETYPE_GIF) - $def_extension = '.gif'; - if($gis[2] === IMAGETYPE_JPEG) - $def_extension = '.jpg'; - if($gis[2] === IMAGETYPE_PNG) - $def_extension = '.png'; - if($gis[2] === IMAGETYPE_WEBP) - $def_extension = '.webp'; - } - - // If we know it's a photo, over-ride the type in case the source system could not determine what it was - - if($is_photo) { - $type = $gis['mime']; - } - - $pathname = ''; - - - // If we were called from the Photos module there is a slightly different mechanism - // for setting the parent path than if we were called from the Files (cloud) module. - - if ($source === 'photos') { - if ($newalbum) { - $pathname = filepath_macro($newalbum); - } - elseif (array_key_exists('folder',$arr)) { - $x = q("select filename from attach where hash = '%s' and uid = %d limit 1", - dbesc($arr['folder']), - intval($channel['channel_id']) - ); - if ($x) { - $pathname = $x[0]['filename']; - } - } - else { - $pathname = filepath_macro($album); - } - } - - if (! $pathname) { - $pathname = filepath_macro($upload_path); - } - - $darr = array('pathname' => $pathname); - - // if we need to create a directory, use the channel default permissions. - - $darr['allow_cid'] = $channel['allow_cid']; - $darr['allow_gid'] = $channel['allow_gid']; - $darr['deny_cid'] = $channel['deny_cid']; - $darr['deny_gid'] = $channel['deny_gid']; - - - $direct = null; - - if ($pathname) { - $x = attach_mkdirp($channel, $observer_hash, $darr); - $folder_hash = (($x['success']) ? $x['data']['hash'] : ''); - $direct = (($x['success']) ? $x['data'] : null); - if ((! $str_contact_allow) && (! $str_group_allow) && (! $str_contact_deny) && (! $str_group_deny)) { - $str_contact_allow = $x['data']['allow_cid']; - $str_group_allow = $x['data']['allow_gid']; - $str_contact_deny = $x['data']['deny_cid']; - $str_group_deny = $x['data']['deny_gid']; - } - } - else { - $folder_hash = ((($arr) && array_key_exists('folder',$arr)) ? $arr['folder'] : ''); - } - - if((! $options) || ($options === 'import')) { - - // A freshly uploaded file. Check for duplicate and resolve with the channel's overwrite settings. - - $r = q("select filename, id, hash, filesize from attach where uid = %d and filename = '%s' and folder = '%s' ", - intval($channel_id), - dbesc($filename), - dbesc($folder_hash) - ); - if($r) { - $overwrite = (($import_replace || get_pconfig($channel_id,'system','overwrite_dup_files')) ? true : false); - if(($overwrite) || ($options === 'import')) { - if(! array_key_exists('edited',$arr)) - $arr['edited'] = datetime_convert(); - $options = 'replace'; - $existing_id = $x[0]['id']; - $existing_size = intval($x[0]['filesize']); - $hash = $x[0]['hash']; - } - else { - if(strpos($filename,'.') !== false) { - $basename = substr($filename,0,strrpos($filename,'.')); - $ext = substr($filename,strrpos($filename,'.')); - } - else { - $basename = $filename; - $ext = $def_extension; - } - - $r = q("select filename from attach where uid = %d and ( filename = '%s' OR filename like '%s' ) and folder = '%s' ", - intval($channel_id), - dbesc($basename . $ext), - dbesc($basename . '(%)' . $ext), - dbesc($folder_hash) - ); - - if($r) { - $x = 1; - - do { - $found = false; - foreach($r as $rr) { - if($rr['filename'] === $basename . '(' . $x . ')' . $ext) { - $found = true; - break; - } - } - if($found) - $x++; - } while($found); - $filename = $basename . '(' . $x . ')' . $ext; - } - else - $filename = $basename . $ext; - } - } - } - - if(! $hash) - $hash = new_uuid(); - - // Check storage limits - if($options !== 'update') { - $maxfilesize = get_config('system','maxfilesize'); - - if(($maxfilesize) && ($filesize > $maxfilesize)) { - logger('quota_exceeded'); - $ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize); - if($remove_when_processed) - @unlink($src); - - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - - return $ret; - } - - $limit = engr_units_to_bytes(service_class_fetch($channel_id, 'attach_upload_limit')); - - if($limit !== false) { - $r = q("select sum(filesize) as total from attach where aid = %d ", - intval($channel['channel_account_id']) - ); - if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) { - logger('service_class limit exceeded'); - $ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000); - if($remove_when_processed) - @unlink($src); - - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - - return $ret; - } - } - $mimetype = ((isset($type) && $type) ? $type : z_mime_content_type($filename)); - } - - $os_basepath = 'store/' . $channel['channel_address'] . '/' ; - $os_relpath = ''; - - if($folder_hash) { - $curr = find_folder_hash_by_attach_hash($channel_id,$folder_hash,true); - if($curr) - $os_relpath .= $curr . '/'; - $os_relpath .= $folder_hash . '/'; - } - - $os_relpath .= $hash; - $os_relpath = ltrim($os_relpath,'/'); - - $os_path = $os_relpath; - $display_path = ltrim($pathname . '/' . $filename,'/'); - - if($src) { - $istream = @fopen($src,'rb'); - $ostream = @fopen($os_basepath . $os_relpath,'wb'); - if($istream && $ostream) { - pipe_streams($istream,$ostream,65535); - fclose($istream); - fclose($ostream); - } - } - - if(array_key_exists('created', $arr)) - $created = $arr['created']; - else - $created = datetime_convert(); - - if(array_key_exists('edited', $arr)) - $edited = $arr['edited']; - 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, content = '%s', edited = '%s', os_path = '%s', display_path = '%s' where id = %d and uid = %d", - dbesc($filename), - dbesc($mimetype), - dbesc($folder_hash), - intval($filesize), - intval(1), - intval($is_photo), - dbescbin($os_basepath . $os_relpath), - dbesc($created), - dbesc($os_path), - dbesc($display_path), - intval($existing_id), - intval($channel_id) - ); - } - elseif($options === 'revise') { - $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid ) +function attach_store($channel, $observer_hash, $options = '', $arr = null) +{ + + require_once('include/photos.php'); + + /** + * @hooks photo_upload_begin + * Called when attempting to upload a photo. + */ + call_hooks('photo_upload_begin', $arr); + + $ret = array('success' => false); + $channel_id = $channel['channel_id']; + $sql_options = ''; + $source = (($arr) ? $arr['source'] : ''); + $album = (($arr) ? $arr['album'] : ''); + $newalbum = (($arr) ? $arr['newalbum'] : ''); + $hash = (($arr && $arr['hash']) ? $arr['hash'] : null); + $upload_path = (($arr && $arr['directory']) ? $arr['directory'] : ''); + $visible = (($arr && $arr['visible']) ? $arr['visible'] : ''); + $notify = (($arr && $arr['notify']) ? $arr['notify'] : ''); + $flags = (($arr && array_key_exists('flags', $arr)) ? intval($arr['flags']) : 0); + $observer = []; + + $dosync = ((array_key_exists('nosync', $arr) && $arr['nosync']) ? 0 : 1); + + if ($observer_hash) { + $observer = xchan_match([ 'xchan_hash' => $observer_hash ]); + } + + logger('arr: ' . print_r($arr, true), LOGGER_DATA); + + if (! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } + + $str_group_allow = perms2str($arr['group_allow']); + $str_contact_allow = perms2str($arr['contact_allow']); + $str_group_deny = perms2str($arr['group_deny']); + $str_contact_deny = perms2str($arr['contact_deny']); + + + // The 'update' option sets db values without uploading a new attachment + // 'replace' replaces the existing uploaded data + // 'revision' creates a new revision with new upload data + // Default is to upload a new file + + // revise or update must provide $arr['hash'] of the thing to revise/update + + // By default remove $src when finished + + $remove_when_processed = true; + $import_replace = false; + + if ($options === 'import') { + $src = $arr['src']; + $filename = $arr['filename']; + $filesize = @filesize($src); + + $hash = $arr['resource_id']; + + if (array_key_exists('hash', $arr)) { + $hash = $arr['hash']; + } + if (array_key_exists('type', $arr)) { + $type = $arr['type']; + } + + if ($arr['preserve_original']) { + $remove_when_processed = false; + } + + if ($arr['replace']) { + $import_replace = true; + } + + // if importing a directory, just do it now and go home - we're done. + + if (array_key_exists('is_dir', $arr) && intval($arr['is_dir'])) { + $x = attach_mkdir($channel, $observer_hash, $arr); + if ($x['message']) { + logger('import_directory: ' . $x['message']); + } + + return; + } + } elseif ($options !== 'update') { + $f = [ + 'src' => '', + 'filename' => '', + 'filesize' => 0, + 'type' => '' + ]; + + /** + * @hooks photo_upload_file + * Called to generate alternate filenames for an upload. + * * \e string \b src - return value, default empty + * * \e string \b filename - return value, default empty + * * \e number \b filesize - return value, default 0 + * * \e string \b type - return value, default empty + */ + call_hooks('photo_upload_file', $f); + /** + * @hooks attach_upload_file + * Called when uploading a file. + * * \e string \b src - return value, default empty + * * \e string \b filename - return value, default empty + * * \e number \b filesize - return value, default 0 + * * \e string \b type - return value, default empty + */ + 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')) { + logger('No source file'); + $ret['message'] = t('No source file.'); + return $ret; + } + + $src = $_FILES['userfile']['tmp_name']; + $filename = basename($_FILES['userfile']['name']); + $filesize = intval($_FILES['userfile']['size']); + } + } + + // AndStatus sends jpegs with a non-standard mimetype + if ($type === 'image/jpg') { + $type = 'image/jpeg'; + } + + $existing_size = 0; + + if ($options === 'replace') { + $x = q( + "select id, hash, filesize from attach where id = %d and uid = %d limit 1", + intval($arr['id']), + intval($channel_id) + ); + if (! $x) { + $ret['message'] = t('Cannot locate file to replace'); + return $ret; + } + $existing_id = $x[0]['id']; + $existing_size = intval($x[0]['filesize']); + $hash = $x[0]['hash']; + } + + if ($options === 'revise' || $options === 'update') { + $sql_options = " order by revision desc "; + if ($options === 'update' && $arr && array_key_exists('revision', $arr)) { + $sql_options = " and revision = " . intval($arr['revision']) . " "; + } + + $x = q( + "select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, os_path, display_path, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1", + dbesc($arr['hash']), + intval($channel_id) + ); + if (! $x) { + logger('update file source not found'); + $ret['message'] = t('Cannot locate file to revise/update'); + return $ret; + } + $hash = $x[0]['hash']; + } + + $def_extension = ''; + $is_photo = 0; + $gis = false; + + if ($src) { + $gis = @getimagesize($src); + logger('getimagesize: ' . print_r($gis, true), LOGGER_DATA); + } + + if (($gis) && in_array($gis[2], [ IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_WEBP ])) { + $is_photo = 1; + if ($gis[2] === IMAGETYPE_GIF) { + $def_extension = '.gif'; + } + if ($gis[2] === IMAGETYPE_JPEG) { + $def_extension = '.jpg'; + } + if ($gis[2] === IMAGETYPE_PNG) { + $def_extension = '.png'; + } + if ($gis[2] === IMAGETYPE_WEBP) { + $def_extension = '.webp'; + } + } + + // If we know it's a photo, over-ride the type in case the source system could not determine what it was + + if ($is_photo) { + $type = $gis['mime']; + } + + $pathname = ''; + + + // If we were called from the Photos module there is a slightly different mechanism + // for setting the parent path than if we were called from the Files (cloud) module. + + if ($source === 'photos') { + if ($newalbum) { + $pathname = filepath_macro($newalbum); + } elseif (array_key_exists('folder', $arr)) { + $x = q( + "select filename from attach where hash = '%s' and uid = %d limit 1", + dbesc($arr['folder']), + intval($channel['channel_id']) + ); + if ($x) { + $pathname = $x[0]['filename']; + } + } else { + $pathname = filepath_macro($album); + } + } + + if (! $pathname) { + $pathname = filepath_macro($upload_path); + } + + $darr = array('pathname' => $pathname); + + // if we need to create a directory, use the channel default permissions. + + $darr['allow_cid'] = $channel['allow_cid']; + $darr['allow_gid'] = $channel['allow_gid']; + $darr['deny_cid'] = $channel['deny_cid']; + $darr['deny_gid'] = $channel['deny_gid']; + + + $direct = null; + + if ($pathname) { + $x = attach_mkdirp($channel, $observer_hash, $darr); + $folder_hash = (($x['success']) ? $x['data']['hash'] : ''); + $direct = (($x['success']) ? $x['data'] : null); + if ((! $str_contact_allow) && (! $str_group_allow) && (! $str_contact_deny) && (! $str_group_deny)) { + $str_contact_allow = $x['data']['allow_cid']; + $str_group_allow = $x['data']['allow_gid']; + $str_contact_deny = $x['data']['deny_cid']; + $str_group_deny = $x['data']['deny_gid']; + } + } else { + $folder_hash = ((($arr) && array_key_exists('folder', $arr)) ? $arr['folder'] : ''); + } + + if ((! $options) || ($options === 'import')) { + // A freshly uploaded file. Check for duplicate and resolve with the channel's overwrite settings. + + $r = q( + "select filename, id, hash, filesize from attach where uid = %d and filename = '%s' and folder = '%s' ", + intval($channel_id), + dbesc($filename), + dbesc($folder_hash) + ); + if ($r) { + $overwrite = (($import_replace || get_pconfig($channel_id, 'system', 'overwrite_dup_files')) ? true : false); + if (($overwrite) || ($options === 'import')) { + if (! array_key_exists('edited', $arr)) { + $arr['edited'] = datetime_convert(); + } + $options = 'replace'; + $existing_id = $x[0]['id']; + $existing_size = intval($x[0]['filesize']); + $hash = $x[0]['hash']; + } else { + if (strpos($filename, '.') !== false) { + $basename = substr($filename, 0, strrpos($filename, '.')); + $ext = substr($filename, strrpos($filename, '.')); + } else { + $basename = $filename; + $ext = $def_extension; + } + + $r = q( + "select filename from attach where uid = %d and ( filename = '%s' OR filename like '%s' ) and folder = '%s' ", + intval($channel_id), + dbesc($basename . $ext), + dbesc($basename . '(%)' . $ext), + dbesc($folder_hash) + ); + + if ($r) { + $x = 1; + + do { + $found = false; + foreach ($r as $rr) { + if ($rr['filename'] === $basename . '(' . $x . ')' . $ext) { + $found = true; + break; + } + } + if ($found) { + $x++; + } + } while ($found); + $filename = $basename . '(' . $x . ')' . $ext; + } else { + $filename = $basename . $ext; + } + } + } + } + + if (! $hash) { + $hash = new_uuid(); + } + + // Check storage limits + if ($options !== 'update') { + $maxfilesize = get_config('system', 'maxfilesize'); + + if (($maxfilesize) && ($filesize > $maxfilesize)) { + logger('quota_exceeded'); + $ret['message'] = sprintf(t('File exceeds size limit of %d'), $maxfilesize); + if ($remove_when_processed) { + @unlink($src); + } + + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + + return $ret; + } + + $limit = engr_units_to_bytes(service_class_fetch($channel_id, 'attach_upload_limit')); + + if ($limit !== false) { + $r = q( + "select sum(filesize) as total from attach where aid = %d ", + intval($channel['channel_account_id']) + ); + if (($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) { + logger('service_class limit exceeded'); + $ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000); + if ($remove_when_processed) { + @unlink($src); + } + + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + + return $ret; + } + } + $mimetype = ((isset($type) && $type) ? $type : z_mime_content_type($filename)); + } + + $os_basepath = 'store/' . $channel['channel_address'] . '/' ; + $os_relpath = ''; + + if ($folder_hash) { + $curr = find_folder_hash_by_attach_hash($channel_id, $folder_hash, true); + if ($curr) { + $os_relpath .= $curr . '/'; + } + $os_relpath .= $folder_hash . '/'; + } + + $os_relpath .= $hash; + $os_relpath = ltrim($os_relpath, '/'); + + $os_path = $os_relpath; + $display_path = ltrim($pathname . '/' . $filename, '/'); + + if ($src) { + $istream = @fopen($src, 'rb'); + $ostream = @fopen($os_basepath . $os_relpath, 'wb'); + if ($istream && $ostream) { + pipe_streams($istream, $ostream, 65535); + fclose($istream); + fclose($ostream); + } + } + + if (array_key_exists('created', $arr)) { + $created = $arr['created']; + } else { + $created = datetime_convert(); + } + + if (array_key_exists('edited', $arr)) { + $edited = $arr['edited']; + } 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, content = '%s', edited = '%s', os_path = '%s', display_path = '%s' where id = %d and uid = %d", + dbesc($filename), + dbesc($mimetype), + dbesc($folder_hash), + intval($filesize), + intval(1), + intval($is_photo), + dbescbin($os_basepath . $os_relpath), + dbesc($created), + dbesc($os_path), + dbesc($display_path), + intval($existing_id), + intval($channel_id) + ); + } elseif ($options === 'revise') { + $r = q( + "insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, 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', '%s', '%s' ) ", - intval($x[0]['aid']), - intval($channel_id), - dbesc($x[0]['hash']), - dbesc($observer_hash), - dbesc($filename), - dbesc($mimetype), - dbesc($folder_hash), - intval($filesize), - intval($x[0]['revision'] + 1), - intval(1), - intval($is_photo), - dbescbin($os_basepath . $os_relpath), - dbesc($created), - dbesc($created), - dbesc($os_path), - dbesc($display_path), - dbesc($x[0]['allow_cid']), - dbesc($x[0]['allow_gid']), - dbesc($x[0]['deny_cid']), - dbesc($x[0]['deny_gid']) - ); - } - elseif($options === 'update') { - $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', edited = '%s', os_storage = %d, is_photo = %d, os_path = '%s', + intval($x[0]['aid']), + intval($channel_id), + dbesc($x[0]['hash']), + dbesc($observer_hash), + dbesc($filename), + dbesc($mimetype), + dbesc($folder_hash), + intval($filesize), + intval($x[0]['revision'] + 1), + intval(1), + intval($is_photo), + dbescbin($os_basepath . $os_relpath), + dbesc($created), + dbesc($created), + dbesc($os_path), + dbesc($display_path), + dbesc($x[0]['allow_cid']), + dbesc($x[0]['allow_gid']), + dbesc($x[0]['deny_cid']), + dbesc($x[0]['deny_gid']) + ); + } elseif ($options === 'update') { + $r = q( + "update attach set filename = '%s', filetype = '%s', folder = '%s', edited = '%s', os_storage = %d, is_photo = %d, os_path = '%s', display_path = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d", - dbesc((array_key_exists('filename',$arr)) ? $arr['filename'] : $x[0]['filename']), - dbesc((array_key_exists('filetype',$arr)) ? $arr['filetype'] : $x[0]['filetype']), - dbesc(($folder_hash) ? $folder_hash : $x[0]['folder']), - dbesc($created), - dbesc((array_key_exists('os_storage',$arr)) ? $arr['os_storage'] : $x[0]['os_storage']), - dbesc((array_key_exists('is_photo',$arr)) ? $arr['is_photo'] : $x[0]['is_photo']), - dbesc((array_key_exists('os_path',$arr)) ? $arr['os_path'] : $x[0]['os_path']), - dbesc((array_key_exists('display_path',$arr)) ? $arr['display_path'] : $x[0]['display_path']), - dbesc((array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $x[0]['allow_cid']), - dbesc((array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $x[0]['allow_gid']), - dbesc((array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $x[0]['deny_cid']), - dbesc((array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : $x[0]['deny_gid']), - intval($x[0]['id']), - intval($x[0]['uid']) - ); - } - else { - - $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, flags, content, created, edited, os_path, display_path, allow_cid, allow_gid,deny_cid, deny_gid ) + dbesc((array_key_exists('filename', $arr)) ? $arr['filename'] : $x[0]['filename']), + dbesc((array_key_exists('filetype', $arr)) ? $arr['filetype'] : $x[0]['filetype']), + dbesc(($folder_hash) ? $folder_hash : $x[0]['folder']), + dbesc($created), + dbesc((array_key_exists('os_storage', $arr)) ? $arr['os_storage'] : $x[0]['os_storage']), + dbesc((array_key_exists('is_photo', $arr)) ? $arr['is_photo'] : $x[0]['is_photo']), + dbesc((array_key_exists('os_path', $arr)) ? $arr['os_path'] : $x[0]['os_path']), + dbesc((array_key_exists('display_path', $arr)) ? $arr['display_path'] : $x[0]['display_path']), + dbesc((array_key_exists('allow_cid', $arr)) ? $arr['allow_cid'] : $x[0]['allow_cid']), + dbesc((array_key_exists('allow_gid', $arr)) ? $arr['allow_gid'] : $x[0]['allow_gid']), + dbesc((array_key_exists('deny_cid', $arr)) ? $arr['deny_cid'] : $x[0]['deny_cid']), + dbesc((array_key_exists('deny_gid', $arr)) ? $arr['deny_gid'] : $x[0]['deny_gid']), + intval($x[0]['id']), + intval($x[0]['uid']) + ); + } else { + $r = q( + "INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, flags, content, created, edited, os_path, display_path, allow_cid, allow_gid,deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", - intval($channel['channel_account_id']), - intval($channel_id), - dbesc($hash), - dbesc(get_observer_hash()), - dbesc($filename), - dbesc($mimetype), - dbesc($folder_hash), - intval($filesize), - intval(0), - intval(1), - intval($is_photo), - intval($flags), - dbescbin($os_basepath . $os_relpath), - dbesc($created), - dbesc($created), - dbesc($os_path), - dbesc($display_path), - dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $str_contact_allow), - dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $str_group_allow), - dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $str_contact_deny), - dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : $str_group_deny) - ); - } + intval($channel['channel_account_id']), + intval($channel_id), + dbesc($hash), + dbesc(get_observer_hash()), + dbesc($filename), + dbesc($mimetype), + dbesc($folder_hash), + intval($filesize), + intval(0), + intval(1), + intval($is_photo), + intval($flags), + dbescbin($os_basepath . $os_relpath), + dbesc($created), + dbesc($created), + dbesc($os_path), + dbesc($display_path), + dbesc(($arr && array_key_exists('allow_cid', $arr)) ? $arr['allow_cid'] : $str_contact_allow), + dbesc(($arr && array_key_exists('allow_gid', $arr)) ? $arr['allow_gid'] : $str_group_allow), + dbesc(($arr && array_key_exists('deny_cid', $arr)) ? $arr['deny_cid'] : $str_contact_deny), + dbesc(($arr && array_key_exists('deny_gid', $arr)) ? $arr['deny_gid'] : $str_group_deny) + ); + } - if ($is_photo) { - - // Call the photos library to generate all the standard thumbnails. - // This may fail if the image format isn't supported by the image library *or* memory is exhausted during the attempt. - // That's why this is called at the end of the upload when all the important work to store as a normal file has been accomplished. - - $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => $pathname, 'folder' => $folder_hash, 'os_syspath' => $os_basepath . $os_relpath, 'os_path' => $os_path, 'display_path' => $display_path, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options ); - if($arr['contact_allow']) - $args['contact_allow'] = $arr['contact_allow']; - if($arr['group_allow']) - $args['group_allow'] = $arr['group_allow']; - if($arr['contact_deny']) - $args['contact_deny'] = $arr['contact_deny']; - if($arr['group_deny']) - $args['group_deny'] = $arr['group_deny']; - if(array_key_exists('allow_cid',$arr)) - $args['allow_cid'] = $arr['allow_cid']; - if(array_key_exists('allow_gid',$arr)) - $args['allow_gid'] = $arr['allow_gid']; - if(array_key_exists('deny_cid',$arr)) - $args['deny_cid'] = $arr['deny_cid']; - if(array_key_exists('deny_gid',$arr)) - $args['deny_gid'] = $arr['deny_gid']; + if ($is_photo) { + // Call the photos library to generate all the standard thumbnails. + // This may fail if the image format isn't supported by the image library *or* memory is exhausted during the attempt. + // That's why this is called at the end of the upload when all the important work to store as a normal file has been accomplished. - $args['created'] = $created; - $args['edited'] = $edited; - if($arr['item']) - $args['item'] = $arr['item']; + $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => $pathname, 'folder' => $folder_hash, 'os_syspath' => $os_basepath . $os_relpath, 'os_path' => $os_path, 'display_path' => $display_path, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options ); + if ($arr['contact_allow']) { + $args['contact_allow'] = $arr['contact_allow']; + } + if ($arr['group_allow']) { + $args['group_allow'] = $arr['group_allow']; + } + if ($arr['contact_deny']) { + $args['contact_deny'] = $arr['contact_deny']; + } + if ($arr['group_deny']) { + $args['group_deny'] = $arr['group_deny']; + } + if (array_key_exists('allow_cid', $arr)) { + $args['allow_cid'] = $arr['allow_cid']; + } + if (array_key_exists('allow_gid', $arr)) { + $args['allow_gid'] = $arr['allow_gid']; + } + if (array_key_exists('deny_cid', $arr)) { + $args['deny_cid'] = $arr['deny_cid']; + } + if (array_key_exists('deny_gid', $arr)) { + $args['deny_gid'] = $arr['deny_gid']; + } - if($arr['description']) - $args['description'] = $arr['description']; + $args['created'] = $created; + $args['edited'] = $edited; + if ($arr['item']) { + $args['item'] = $arr['item']; + } - if($arr['title']) - $args['title'] = $arr['title']; + if ($arr['description']) { + $args['description'] = $arr['description']; + } - if($arr['body']) - $args['body'] = $arr['body']; + if ($arr['title']) { + $args['title'] = $arr['title']; + } + + if ($arr['body']) { + $args['body'] = $arr['body']; + } - $args['deliver'] = $dosync; + $args['deliver'] = $dosync; - $p = photo_upload($channel,$observer,$args); - if($p['success']) { - $ret['body'] = $p['body']; - } - } + $p = photo_upload($channel, $observer, $args); + if ($p['success']) { + $ret['body'] = $p['body']; + } + } - if(($options !== 'update') && ($remove_when_processed)) - @unlink($src); + if (($options !== 'update') && ($remove_when_processed)) { + @unlink($src); + } - if(! $r) { - $ret['message'] = t('File upload failed. Possible system limit or action terminated.'); + if (! $r) { + $ret['message'] = t('File upload failed. Possible system limit or action terminated.'); - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); - return $ret; - } + return $ret; + } - // Update the folder timestamp @todo recurse to the storage root folder + // Update the folder timestamp @todo recurse to the storage root folder - if($folder_hash) { - q("UPDATE attach set edited = '%s' where hash = '%s' and uid = %d and is_dir = 1", - dbesc($edited), - dbesc($folder_hash), - intval($channel_id) - ); - } + if ($folder_hash) { + q( + "UPDATE attach set edited = '%s' where hash = '%s' and uid = %d and is_dir = 1", + dbesc($edited), + dbesc($folder_hash), + intval($channel_id) + ); + } - // Caution: This re-uses $sql_options set further above + // Caution: This re-uses $sql_options set further above - $r = q("select * from attach where uid = %d and hash = '%s' $sql_options limit 1", - intval($channel_id), - dbesc($hash) - ); + $r = q( + "select * from attach where uid = %d and hash = '%s' $sql_options limit 1", + intval($channel_id), + dbesc($hash) + ); - if(! $r) { - $ret['message'] = t('Stored file could not be verified. Upload failed.'); + if (! $r) { + $ret['message'] = t('Stored file could not be verified. Upload failed.'); - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); - return $ret; - } + return $ret; + } - $ret['success'] = true; - $ret['data'] = $r[0]; - if(! $is_photo) { - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - * This would've been called already with a success result in photos_upload() if it was a photo. - */ - call_hooks('photo_upload_end', $ret); - } + $ret['success'] = true; + $ret['data'] = $r[0]; + if (! $is_photo) { + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + * This would've been called already with a success result in photos_upload() if it was a photo. + */ + call_hooks('photo_upload_end', $ret); + } - Run::Summon([ 'Thumbnail' , $hash ]); + Run::Summon([ 'Thumbnail' , $hash ]); - if($dosync) { - $sync = attach_export_data($channel,$hash); + if ($dosync) { + $sync = attach_export_data($channel, $hash); - if($sync) - Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync))); - } + if ($sync) { + Libsync::build_sync_packet($channel['channel_id'], array('file' => array($sync))); + } + } - if($notify) { - $cloudPath = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['0']['display_path']; - $object = get_file_activity_object($channel['channel_id'], $r['0']['hash'], $cloudPath); - file_activity($channel['channel_id'], $object, $r['0']['allow_cid'], $r['0']['allow_gid'], $r['0']['deny_cid'], $r['0']['deny_gid'], 'post', $notify); - } + if ($notify) { + $cloudPath = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['0']['display_path']; + $object = get_file_activity_object($channel['channel_id'], $r['0']['hash'], $cloudPath); + file_activity($channel['channel_id'], $object, $r['0']['allow_cid'], $r['0']['allow_gid'], $r['0']['deny_cid'], $r['0']['deny_gid'], 'post', $notify); + } - return $ret; + return $ret; } /** @@ -1075,49 +1122,51 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { * * \e string \b message error message if success is false * * \e array \b data array of attach DB entries without data component */ -function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { +function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - if (! perm_is_allowed($channel_id, $observer_hash, 'view_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($channel_id, $observer_hash, 'view_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - if (strpos($pathname, '/')) { - $paths = explode('/', $pathname); - if (count($paths) > 1) { - $curpath = array_shift($paths); + if (strpos($pathname, '/')) { + $paths = explode('/', $pathname); + if (count($paths) > 1) { + $curpath = array_shift($paths); - $r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id,$observer_hash) . " limit 1", - intval($channel_id), - dbesc($curpath) - ); - if (! $r) { - $ret['message'] = t('Path not available.'); - return $ret; - } - // recurse - return z_readdir($channel_id, $observer_hash, implode('/', $paths), $r[0]['hash']); - } - } - else { - $paths = array($pathname); - } - - $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_path, display_path, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id), - intval($channel_id), - dbesc($parent_hash), - dbesc($paths[0]) - ); - if (! $r) { - $ret['message'] = t('Path not available.'); - return $ret; - } - $ret['success'] = true; - $ret['data'] = $r; + $r = q( + "select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id, $observer_hash) . " limit 1", + intval($channel_id), + dbesc($curpath) + ); + if (! $r) { + $ret['message'] = t('Path not available.'); + return $ret; + } + // recurse + return z_readdir($channel_id, $observer_hash, implode('/', $paths), $r[0]['hash']); + } + } else { + $paths = array($pathname); + } - return $ret; + $r = q( + "select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_path, display_path, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id), + intval($channel_id), + dbesc($parent_hash), + dbesc($paths[0]) + ); + if (! $r) { + $ret['message'] = t('Path not available.'); + return $ret; + } + $ret['success'] = true; + $ret['data'] = $r; + + return $ret; } /** @@ -1137,159 +1186,161 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { * * \e string \b deny_gid * @return array */ -function attach_mkdir($channel, $observer_hash, $arr = null) { +function attach_mkdir($channel, $observer_hash, $arr = null) +{ - $ret = array('success' => false); - $channel_id = $channel['channel_id']; + $ret = array('success' => false); + $channel_id = $channel['channel_id']; - $sql_options = ''; + $sql_options = ''; - $os_basepath = 'store/' . $channel['channel_address']; + $os_basepath = 'store/' . $channel['channel_address']; - logger('basepath: ' . $os_basepath, LOGGER_DEBUG); + logger('basepath: ' . $os_basepath, LOGGER_DEBUG); - if (! is_dir($os_basepath)) { - os_mkdir($os_basepath,STORAGE_DEFAULT_PERMISSIONS, true); - } + if (! is_dir($os_basepath)) { + os_mkdir($os_basepath, STORAGE_DEFAULT_PERMISSIONS, true); + } - $os_basepath .= '/'; + $os_basepath .= '/'; - if (! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - if (! $arr['filename']) { - $ret['message'] = t('Empty pathname'); - return $ret; - } + if (! $arr['filename']) { + $ret['message'] = t('Empty pathname'); + return $ret; + } - $arr['hash'] = (($arr['hash']) ? $arr['hash'] : new_uuid()); + $arr['hash'] = (($arr['hash']) ? $arr['hash'] : new_uuid()); - // Check for duplicate name. - // Check both the filename and the hash as we will be making use of both. + // Check for duplicate name. + // Check both the filename and the hash as we will be making use of both. - $r = q("select id, hash, is_dir, flags from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1", - dbesc($arr['filename']), - dbesc($arr['hash']), - dbesc($arr['folder']), - intval($channel['channel_id']) - ); - if ($r) { - if (array_key_exists('force',$arr) && intval($arr['force']) && (intval($r[0]['is_dir']))) { - $ret['success'] = true; - $r = q("select * from attach where id = %d limit 1", - intval($r[0]['id']) - ); - if ($r) { - $ret['data'] = $r[0]; - } - return $ret; - } - $ret['message'] = t('duplicate filename or path'); - return $ret; - } + $r = q( + "select id, hash, is_dir, flags from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1", + dbesc($arr['filename']), + dbesc($arr['hash']), + dbesc($arr['folder']), + intval($channel['channel_id']) + ); + if ($r) { + if (array_key_exists('force', $arr) && intval($arr['force']) && (intval($r[0]['is_dir']))) { + $ret['success'] = true; + $r = q( + "select * from attach where id = %d limit 1", + intval($r[0]['id']) + ); + if ($r) { + $ret['data'] = $r[0]; + } + return $ret; + } + $ret['message'] = t('duplicate filename or path'); + return $ret; + } - if ($arr['folder']) { + if ($arr['folder']) { + // Walk the directory tree from parent back to root to make sure the parent is valid and name is unique and we + // have permission to see this path. This implies the root directory itself is public since we won't have permissions + // set on the psuedo-directory. We can however set permissions for anything and everything contained within it. - // Walk the directory tree from parent back to root to make sure the parent is valid and name is unique and we - // have permission to see this path. This implies the root directory itself is public since we won't have permissions - // set on the psuedo-directory. We can however set permissions for anything and everything contained within it. + $lpath = ''; + $lfile = $arr['folder']; + $dpath = ''; - $lpath = ''; - $lfile = $arr['folder']; - $dpath = ''; - - $sql_options = permissions_sql($channel['channel_id']); + $sql_options = permissions_sql($channel['channel_id']); - do { - $r = q("select filename, hash, flags, is_dir, folder, display_path from attach where uid = %d and hash = '%s' and is_dir = 1 + do { + $r = q( + "select filename, hash, flags, is_dir, folder, display_path from attach where uid = %d and hash = '%s' and is_dir = 1 $sql_options limit 1", - intval($channel['channel_id']), - dbesc($lfile) - ); - if (! $r) { - logger('attach_mkdir: hash ' . $lfile . ' not found in ' . $lpath); - $ret['message'] = t('Path not found.'); - return $ret; - } + intval($channel['channel_id']), + dbesc($lfile) + ); + if (! $r) { + logger('attach_mkdir: hash ' . $lfile . ' not found in ' . $lpath); + $ret['message'] = t('Path not found.'); + return $ret; + } - $dpath = $r[0]['filename'] . (($dpath) ? '/' . $dpath : ''); + $dpath = $r[0]['filename'] . (($dpath) ? '/' . $dpath : ''); - if ($lfile) { - $lpath = $r[0]['hash'] . (($lpath) ? '/' . $lpath : ''); - } + if ($lfile) { + $lpath = $r[0]['hash'] . (($lpath) ? '/' . $lpath : ''); + } - $lfile = $r[0]['folder']; + $lfile = $r[0]['folder']; + } while (($r[0]['folder']) && intval($r[0]['is_dir'])); - } while ( ($r[0]['folder']) && intval($r[0]['is_dir'])) ; + $path = $lpath; + } else { + $path = ''; + } - $path = $lpath; - } - else { - $path = ''; - } + $created = datetime_convert(); - $created = datetime_convert(); - - $os_path = ltrim($path . '/' . $arr['hash'],'/'); - $display_path = ltrim($dpath . '/' . $arr['filename'],'/'); + $os_path = ltrim($path . '/' . $arr['hash'], '/'); + $display_path = ltrim($dpath . '/' . $arr['filename'], '/'); - $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid ) + $r = q( + "INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", - intval($channel['channel_account_id']), - intval($channel_id), - dbesc($arr['hash']), - dbesc(get_observer_hash()), - dbesc($arr['filename']), - dbesc('multipart/mixed'), - intval(0), - intval(0), - dbesc($arr['folder']), - intval(1), - intval(1), - dbescbin($os_basepath . $os_path), - dbesc($created), - dbesc($created), - dbesc($os_path), - dbesc($display_path), - dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $channel['channel_allow_cid']), - dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $channel['channel_allow_gid']), - dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $channel['channel_deny_cid']), - dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : $channel['channel_deny_gid']) - ); + intval($channel['channel_account_id']), + intval($channel_id), + dbesc($arr['hash']), + dbesc(get_observer_hash()), + dbesc($arr['filename']), + dbesc('multipart/mixed'), + intval(0), + intval(0), + dbesc($arr['folder']), + intval(1), + intval(1), + dbescbin($os_basepath . $os_path), + dbesc($created), + dbesc($created), + dbesc($os_path), + dbesc($display_path), + dbesc(($arr && array_key_exists('allow_cid', $arr)) ? $arr['allow_cid'] : $channel['channel_allow_cid']), + dbesc(($arr && array_key_exists('allow_gid', $arr)) ? $arr['allow_gid'] : $channel['channel_allow_gid']), + dbesc(($arr && array_key_exists('deny_cid', $arr)) ? $arr['deny_cid'] : $channel['channel_deny_cid']), + dbesc(($arr && array_key_exists('deny_gid', $arr)) ? $arr['deny_gid'] : $channel['channel_deny_gid']) + ); - if ($r) { - if (os_mkdir($os_basepath . $os_path, STORAGE_DEFAULT_PERMISSIONS, true)) { - $ret['success'] = true; + if ($r) { + if (os_mkdir($os_basepath . $os_path, STORAGE_DEFAULT_PERMISSIONS, true)) { + $ret['success'] = true; - // update the parent folder's lastmodified timestamp - $e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", - dbesc($created), - dbesc($arr['folder']), - intval($channel_id) - ); + // update the parent folder's lastmodified timestamp + $e = q( + "UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", + dbesc($created), + dbesc($arr['folder']), + intval($channel_id) + ); - $z = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1", - dbesc($arr['hash']), - intval($channel_id) - ); - if ($z) { - $ret['data'] = $z[0]; - } - } - else { - logger('attach_mkdir: ' . mkdir . ' ' . $os_basepath . $os_path . ' failed.'); - $ret['message'] = t('mkdir failed.'); - } - } - else { - $ret['message'] = t('database storage failed.'); - } + $z = q( + "select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1", + dbesc($arr['hash']), + intval($channel_id) + ); + if ($z) { + $ret['data'] = $z[0]; + } + } else { + logger('attach_mkdir: ' . mkdir . ' ' . $os_basepath . $os_path . ' failed.'); + $ret['message'] = t('mkdir failed.'); + } + } else { + $ret['message'] = t('database storage failed.'); + } - return $ret; + return $ret; } /** @@ -1308,78 +1359,78 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { * * \e string \b deny_gid * @return array */ -function attach_mkdirp($channel, $observer_hash, $arr = null) { +function attach_mkdirp($channel, $observer_hash, $arr = null) +{ - $ret = [ 'success' => false ]; - $channel_id = $channel['channel_id']; + $ret = [ 'success' => false ]; + $channel_id = $channel['channel_id']; - $sql_options = ''; + $sql_options = ''; - $basepath = 'store/' . $channel['channel_address']; + $basepath = 'store/' . $channel['channel_address']; - logger('basepath: ' . $basepath, LOGGER_DEBUG); + logger('basepath: ' . $basepath, LOGGER_DEBUG); - if (! is_dir($basepath)) { - os_mkdir($basepath,STORAGE_DEFAULT_PERMISSIONS, true); - } + if (! is_dir($basepath)) { + os_mkdir($basepath, STORAGE_DEFAULT_PERMISSIONS, true); + } - if (! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } + if (! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } - if (! $arr['pathname']) { - $ret['message'] = t('Empty pathname'); - return $ret; - } + if (! $arr['pathname']) { + $ret['message'] = t('Empty pathname'); + return $ret; + } - $paths = explode('/',$arr['pathname']); - if (! $paths) { - $ret['message'] = t('Empty path'); - return $ret; - } + $paths = explode('/', $arr['pathname']); + if (! $paths) { + $ret['message'] = t('Empty path'); + return $ret; + } - $current_parent = ''; + $current_parent = ''; - foreach ($paths as $p) { - if (! $p) { - continue; - } + foreach ($paths as $p) { + if (! $p) { + continue; + } - $arx = [ - 'filename' => $p, - 'folder' => $current_parent, - 'force' => 1 - ]; - - if (array_key_exists('allow_cid',$arr)) { - $arx['allow_cid'] = $arr['allow_cid']; - } - if (array_key_exists('deny_cid',$arr)) { - $arx['deny_cid'] = $arr['deny_cid']; - } - if (array_key_exists('allow_gid',$arr)) { - $arx['allow_gid'] = $arr['allow_gid']; - } - if (array_key_exists('deny_gid',$arr)) { - $arx['deny_gid'] = $arr['deny_gid']; - } + $arx = [ + 'filename' => $p, + 'folder' => $current_parent, + 'force' => 1 + ]; - $x = attach_mkdir($channel, $observer_hash, $arx); - if ($x['success']) { - $current_parent = $x['data']['hash']; - } - else { - $ret['message'] = $x['message']; - return $ret; - } - } - if (isset($x)) { - $ret['success'] = true; - $ret['data'] = $x['data']; - } + if (array_key_exists('allow_cid', $arr)) { + $arx['allow_cid'] = $arr['allow_cid']; + } + if (array_key_exists('deny_cid', $arr)) { + $arx['deny_cid'] = $arr['deny_cid']; + } + if (array_key_exists('allow_gid', $arr)) { + $arx['allow_gid'] = $arr['allow_gid']; + } + if (array_key_exists('deny_gid', $arr)) { + $arx['deny_gid'] = $arr['deny_gid']; + } - return $ret; + $x = attach_mkdir($channel, $observer_hash, $arx); + if ($x['success']) { + $current_parent = $x['data']['hash']; + } else { + $ret['message'] = $x['message']; + return $ret; + } + } + if (isset($x)) { + $ret['success'] = true; + $ret['data'] = $x['data']; + } + + return $ret; } @@ -1396,88 +1447,93 @@ function attach_mkdirp($channel, $observer_hash, $arr = null) { * @param bool $recurse (optional) default false * @param bool $sync (optional) default false */ -function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse = false, $sync = false) { +function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse = false, $sync = false) +{ - $channel = channelx_by_n($channel_id); - if (! $channel) { - return; - } + $channel = channelx_by_n($channel_id); + if (! $channel) { + return; + } - $r = q("select hash, flags, is_dir, is_photo, allow_cid from attach where hash = '%s' and uid = %d limit 1", - dbesc($resource), - intval($channel_id) - ); + $r = q( + "select hash, flags, is_dir, is_photo, allow_cid from attach where hash = '%s' and uid = %d limit 1", + dbesc($resource), + intval($channel_id) + ); - if (! $r) { - return; - } + if (! $r) { + return; + } - $private = (($allow_cid || $allow_gid || $deny_cid || $deny_gid) ? true : false); + $private = (($allow_cid || $allow_gid || $deny_cid || $deny_gid) ? true : false); - // preserve any existing tokens that may have been set for this file - // @fixme - we need a way to unconditionally clear these if desired. - - if ($private) { - $token_matches = null; - if (preg_match_all('/\/',$r[0]['allow_cid'],$token_matches, PREG_SET_ORDER)) { - foreach ($token_matches as $m) { - $tok = ''; - if (strpos($allow_cid,$tok) === false) { - $allow_cid .= $tok; - } - } - } - } + // preserve any existing tokens that may have been set for this file + // @fixme - we need a way to unconditionally clear these if desired. - if (intval($r[0]['is_dir'])) { - if ($recurse) { - $r = q("select hash, flags, is_dir from attach where folder = '%s' and uid = %d", - dbesc($resource), - intval($channel_id) - ); - if ($r) { - foreach ($r as $rr) { - attach_change_permissions($channel_id, $rr['hash'], $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse, $sync); - } - } - } - } + if ($private) { + $token_matches = null; + if (preg_match_all('/\/', $r[0]['allow_cid'], $token_matches, PREG_SET_ORDER)) { + foreach ($token_matches as $m) { + $tok = ''; + if (strpos($allow_cid, $tok) === false) { + $allow_cid .= $tok; + } + } + } + } - $x = q("update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', flags = 0 where hash = '%s' and uid = %d", - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - dbesc($resource), - intval($channel_id) - ); - if ($r[0]['is_photo']) { - $x = q("update photo set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and uid = %d", - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - dbesc($resource), - intval($channel_id) - ); - $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and resource_type = 'photo' and uid = %d", - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - dbesc($resource), - intval($channel_id) - ); + if (intval($r[0]['is_dir'])) { + if ($recurse) { + $r = q( + "select hash, flags, is_dir from attach where folder = '%s' and uid = %d", + dbesc($resource), + intval($channel_id) + ); + if ($r) { + foreach ($r as $rr) { + attach_change_permissions($channel_id, $rr['hash'], $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse, $sync); + } + } + } + } - } + $x = q( + "update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', flags = 0 where hash = '%s' and uid = %d", + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid), + dbesc($resource), + intval($channel_id) + ); + if ($r[0]['is_photo']) { + $x = q( + "update photo set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and uid = %d", + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid), + dbesc($resource), + intval($channel_id) + ); + $x = q( + "update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and resource_type = 'photo' and uid = %d", + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid), + dbesc($resource), + intval($channel_id) + ); + } - if ($sync) { - $data = attach_export_data($channel,$resource); + if ($sync) { + $data = attach_export_data($channel, $resource); - if ($data) { - Libsync::build_sync_packet($channel['channel_id'], [ 'file' => [ $data ] ]); - } - } + if ($data) { + Libsync::build_sync_packet($channel['channel_id'], [ 'file' => [ $data ] ]); + } + } } /** @@ -1493,122 +1549,130 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi * @param int $is_photo (optional) default 0 * @return void */ -function attach_delete($channel_id, $resource, $is_photo = 0) { +function attach_delete($channel_id, $resource, $is_photo = 0) +{ - $c = q("SELECT channel_address FROM channel WHERE channel_id = %d LIMIT 1", - intval($channel_id) - ); + $c = q( + "SELECT channel_address FROM channel WHERE channel_id = %d LIMIT 1", + intval($channel_id) + ); - $channel_address = (($c) ? $c[0]['channel_address'] : 'notfound'); - $photo_sql = (($is_photo) ? " and is_photo = 1 " : ''); + $channel_address = (($c) ? $c[0]['channel_address'] : 'notfound'); + $photo_sql = (($is_photo) ? " and is_photo = 1 " : ''); - $r = q("SELECT hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1", - dbesc($resource), - intval($channel_id) - ); + $r = q( + "SELECT hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1", + dbesc($resource), + intval($channel_id) + ); - if (! $r) { - attach_drop_photo($channel_id,$resource); - $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo]; - call_hooks("attach_delete",$arr); - return; - } + if (! $r) { + attach_drop_photo($channel_id, $resource); + $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo' => $is_photo]; + call_hooks("attach_delete", $arr); + return; + } - $url = get_cloud_url($channel_id, $channel_address, $resource); - $object = get_file_activity_object($channel_id, $resource, $url); + $url = get_cloud_url($channel_id, $channel_address, $resource); + $object = get_file_activity_object($channel_id, $resource, $url); - // If resource is a directory delete everything in the directory recursive - if (intval($r[0]['is_dir'])) { - $x = q("SELECT hash, os_storage, is_dir, flags FROM attach WHERE folder = '%s' AND uid = %d", - dbesc($resource), - intval($channel_id) - ); - if ($x) { - foreach ($x as $xx) { - attach_delete($channel_id, $xx['hash']); - } - } - } + // If resource is a directory delete everything in the directory recursive + if (intval($r[0]['is_dir'])) { + $x = q( + "SELECT hash, os_storage, is_dir, flags FROM attach WHERE folder = '%s' AND uid = %d", + dbesc($resource), + intval($channel_id) + ); + if ($x) { + foreach ($x as $xx) { + attach_delete($channel_id, $xx['hash']); + } + } + } - // delete a file from filesystem - if (intval($r[0]['os_storage'])) { - $y = q("SELECT content FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", - dbesc($resource), - intval($channel_id) - ); + // delete a file from filesystem + if (intval($r[0]['os_storage'])) { + $y = q( + "SELECT content FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", + dbesc($resource), + intval($channel_id) + ); - if ($y) { - $y[0]['content'] = dbunescbin($y[0]['content']); - if (strpos($y[0]['content'],'store') === false) { - $f = 'store/' . $channel_address . '/' . $y[0]['content']; - } - else { - $f = $y[0]['content']; - } + if ($y) { + $y[0]['content'] = dbunescbin($y[0]['content']); + if (strpos($y[0]['content'], 'store') === false) { + $f = 'store/' . $channel_address . '/' . $y[0]['content']; + } else { + $f = $y[0]['content']; + } - if (is_dir($f)) { - @rmdir($f); - } - elseif (file_exists($f)) { - unlink($f); - } - } - } + if (is_dir($f)) { + @rmdir($f); + } elseif (file_exists($f)) { + unlink($f); + } + } + } - // delete from database - $z = q("DELETE FROM attach WHERE hash = '%s' AND uid = %d", - dbesc($resource), - intval($channel_id) - ); + // delete from database + $z = q( + "DELETE FROM attach WHERE hash = '%s' AND uid = %d", + dbesc($resource), + intval($channel_id) + ); - if ($r[0]['is_photo']) { - attach_drop_photo($channel_id,$resource); - } + if ($r[0]['is_photo']) { + attach_drop_photo($channel_id, $resource); + } - // update the parent folder's lastmodified timestamp - $e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", - dbesc(datetime_convert()), - dbesc($r[0]['folder']), - intval($channel_id) - ); + // update the parent folder's lastmodified timestamp + $e = q( + "UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", + dbesc(datetime_convert()), + dbesc($r[0]['folder']), + intval($channel_id) + ); - $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo]; - call_hooks("attach_delete",$arr); + $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo' => $is_photo]; + call_hooks("attach_delete", $arr); - file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', true); + file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', true); - return; + return; } -function attach_drop_photo($channel_id,$resource) { +function attach_drop_photo($channel_id, $resource) +{ - $x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d and item_deleted = 0", - dbesc($resource), - intval($channel_id) - ); - if ($x) { - drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true); - } - $r = q("select content from photo where uid = %d and resource_id = '%s' and os_storage = 1", - intval($channel_id), - dbesc($resource) - ); - if ($r) { - foreach ($r as $rv) { - $p = dbunescbin($rv['content']); - if ($p && file_exists($p)) { - @unlink($p); - } - } - } - - q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'", - intval($channel_id), - dbesc($resource) - ); + $x = q( + "select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d and item_deleted = 0", + dbesc($resource), + intval($channel_id) + ); + if ($x) { + drop_item($x[0]['id'], false, (($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1), true); + } + $r = q( + "select content from photo where uid = %d and resource_id = '%s' and os_storage = 1", + intval($channel_id), + dbesc($resource) + ); + if ($r) { + foreach ($r as $rv) { + $p = dbunescbin($rv['content']); + if ($p && file_exists($p)) { + @unlink($p); + } + } + } + q( + "DELETE FROM photo WHERE uid = %d AND resource_id = '%s'", + intval($channel_id), + dbesc($resource) + ); } @@ -1625,47 +1689,49 @@ function attach_drop_photo($channel_id,$resource) { * @return string * path to the file in cloud/ */ -function get_cloudpath($arr) { - $basepath = 'cloud/'; +function get_cloudpath($arr) +{ + $basepath = 'cloud/'; - if ($arr['uid']) { - $r = q("select channel_address from channel where channel_id = %d limit 1", - intval($arr['uid']) - ); - if ($r) { - $basepath .= $r[0]['channel_address'] . '/'; - } - } + if ($arr['uid']) { + $r = q( + "select channel_address from channel where channel_id = %d limit 1", + intval($arr['uid']) + ); + if ($r) { + $basepath .= $r[0]['channel_address'] . '/'; + } + } - $path = $basepath; + $path = $basepath; - if ($arr['folder']) { - $lpath = ''; - $lfile = $arr['folder']; + if ($arr['folder']) { + $lpath = ''; + $lfile = $arr['folder']; - do { - $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0 + do { + $r = q( + "select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0 limit 1", - intval($arr['uid']), - dbesc($lfile) - ); + intval($arr['uid']), + dbesc($lfile) + ); - if (! $r) { - break; - } + if (! $r) { + break; + } - if ($lfile) { - $lpath = $r[0]['filename'] . '/' . $lpath; - } - $lfile = $r[0]['folder']; + if ($lfile) { + $lpath = $r[0]['filename'] . '/' . $lpath; + } + $lfile = $r[0]['folder']; + } while (($r[0]['folder']) && intval($r[0]['is_dir'])); - } while ( ($r[0]['folder']) && intval($r[0]['is_dir'])); + $path .= $lpath; + } + $path .= $arr['filename']; - $path .= $lpath; - } - $path .= $arr['filename']; - - return $path; + return $path; } /** @@ -1679,21 +1745,22 @@ function get_cloudpath($arr) { * @param string $attachHash * @return string with the full folder path */ -function get_cloud_url($channel_id, $channel_name, $attachHash) { - $parentFullPath = ''; - // build directory tree - $parentHash = $attachHash; - do { - $parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash); - if ($parentHash) { - $parentName = find_filename_by_hash($channel_id, $parentHash); - $parentFullPath = $parentName . '/' . $parentFullPath; - } - } while ($parentHash); +function get_cloud_url($channel_id, $channel_name, $attachHash) +{ + $parentFullPath = ''; + // build directory tree + $parentHash = $attachHash; + do { + $parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash); + if ($parentHash) { + $parentName = find_filename_by_hash($channel_id, $parentHash); + $parentFullPath = $parentName . '/' . $parentFullPath; + } + } while ($parentHash); - $url = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath . find_filename_by_hash($channel_id, $attachHash); - return $url; + $url = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath . find_filename_by_hash($channel_id, $attachHash); + return $url; } /** @@ -1707,25 +1774,26 @@ function get_cloud_url($channel_id, $channel_name, $attachHash) { * (optional) default false * @return string */ -function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = false) { +function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = false) +{ - logger('attach_hash: ' . $attachHash); + logger('attach_hash: ' . $attachHash); - $r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", - intval($channel_id), - dbesc($attachHash) - ); - $hash = EMPTY_STR; - if ($r && $r[0]['folder']) { - if ($recurse) { - $hash = find_folder_hash_by_attach_hash($channel_id,$r[0]['folder'],true) . '/' . $r[0]['folder']; - } - else { - $hash = $r[0]['folder']; - } - } + $r = q( + "SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", + intval($channel_id), + dbesc($attachHash) + ); + $hash = EMPTY_STR; + if ($r && $r[0]['folder']) { + if ($recurse) { + $hash = find_folder_hash_by_attach_hash($channel_id, $r[0]['folder'], true) . '/' . $r[0]['folder']; + } else { + $hash = $r[0]['folder']; + } + } - return $hash; + return $hash; } /** @@ -1735,37 +1803,38 @@ function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = fa * @param string $path * @return string */ -function find_folder_hash_by_path($channel_id, $path) { +function find_folder_hash_by_path($channel_id, $path) +{ - if (! $path) { - return EMPTY_STR; - } - - $comps = explode('/',$path); - $errors = false; - $parent_hash = ''; + if (! $path) { + return EMPTY_STR; + } - for ($x = 0; $x < count($comps); $x ++) { - $element = $comps[$x]; - $r = q("SELECT hash FROM attach WHERE uid = %d AND filename = '%s' AND folder = '%s' LIMIT 1", - intval($channel_id), - dbesc($element), - dbesc($parent_hash) - ); - if ($r) { - $parent_hash = $r[0]['hash']; - } - else { - $errors ++; - break; - } - } + $comps = explode('/', $path); + $errors = false; + $parent_hash = ''; - if ($errors) { - return EMPTY_STR; - } + for ($x = 0; $x < count($comps); $x++) { + $element = $comps[$x]; + $r = q( + "SELECT hash FROM attach WHERE uid = %d AND filename = '%s' AND folder = '%s' LIMIT 1", + intval($channel_id), + dbesc($element), + dbesc($parent_hash) + ); + if ($r) { + $parent_hash = $r[0]['hash']; + } else { + $errors++; + break; + } + } - return $parent_hash; + if ($errors) { + return EMPTY_STR; + } + + return $parent_hash; } /** @@ -1778,17 +1847,19 @@ function find_folder_hash_by_path($channel_id, $path) { * @return string * The filename of the attachment */ -function find_filename_by_hash($channel_id, $attachHash) { - $r = q("SELECT filename FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", - intval($channel_id), - dbesc($attachHash) - ); - $filename = ''; - if ($r) { - $filename = $r[0]['filename']; - } +function find_filename_by_hash($channel_id, $attachHash) +{ + $r = q( + "SELECT filename FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", + intval($channel_id), + dbesc($attachHash) + ); + $filename = ''; + if ($r) { + $filename = $r[0]['filename']; + } - return $filename; + return $filename; } /** @@ -1799,12 +1870,13 @@ function find_filename_by_hash($channel_id, $attachHash) { * @param int $bufsize size of chunk, default 16384 * @return number with the size */ -function pipe_streams($in, $out, $bufsize = 16384) { - $size = 0; - while (!feof($in)) { - $size += fwrite($out, fread($in, $bufsize)); - } - return $size; +function pipe_streams($in, $out, $bufsize = 16384) +{ + $size = 0; + while (!feof($in)) { + $size += fwrite($out, fread($in, $bufsize)); + } + return $size; } /** @@ -1819,167 +1891,168 @@ function pipe_streams($in, $out, $bufsize = 16384) { * @param string $verb * @param bool $notify */ -function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $notify) { +function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $notify) +{ - $poster = App::get_observer(); + $poster = App::get_observer(); - // if we got no object something went wrong - if (!$object) { - return; - } + // if we got no object something went wrong + if (!$object) { + return; + } - // turn strings into arrays - $arr_allow_cid = expand_acl($allow_cid); - $arr_allow_gid = expand_acl($allow_gid); - $arr_deny_cid = expand_acl($deny_cid); - $arr_deny_gid = expand_acl($deny_gid); + // turn strings into arrays + $arr_allow_cid = expand_acl($allow_cid); + $arr_allow_gid = expand_acl($allow_gid); + $arr_deny_cid = expand_acl($deny_cid); + $arr_deny_gid = expand_acl($deny_gid); - // filter out receivers which do not have permission to view filestorage - $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage'); + // filter out receivers which do not have permission to view filestorage + $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage'); - $is_dir = (intval($object['is_dir']) ? true : false); + $is_dir = (intval($object['is_dir']) ? true : false); - // do not send activity for folders for now - if ($is_dir) { - return; - } + // do not send activity for folders for now + if ($is_dir) { + return; + } - // check for recursive perms if we are in a folder - if ($object['folder']) { + // check for recursive perms if we are in a folder + if ($object['folder']) { + $folder_hash = $object['folder']; - $folder_hash = $object['folder']; + $r_perms = attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash); - $r_perms = attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash); + if ($r_perms === false) { + // nobody has recursive perms - nobody must be notified + return; + } - if ($r_perms === false) { - // nobody has recursive perms - nobody must be notified - return; - } + // split up returned perms + $arr_allow_cid = $r_perms['allow_cid']; + $arr_allow_gid = $r_perms['allow_gid']; + $arr_deny_cid = $r_perms['deny_cid']; + $arr_deny_gid = $r_perms['deny_gid']; - // split up returned perms - $arr_allow_cid = $r_perms['allow_cid']; - $arr_allow_gid = $r_perms['allow_gid']; - $arr_deny_cid = $r_perms['deny_cid']; - $arr_deny_gid = $r_perms['deny_gid']; + // filter out receivers which do not have permission to view filestorage + $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage'); + } - // filter out receivers which do not have permission to view filestorage - $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage'); - } + $uuid = new_uuid(); + $mid = z_root() . '/item/' . $uuid; - $uuid = new_uuid(); - $mid = z_root() . '/item/' . $uuid; + $objtype = 'Document'; - $objtype = 'Document'; + $arr = []; + $arr['aid'] = get_account_id(); + $arr['uid'] = $channel_id; + $arr['uuid'] = $uuid; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_unseen'] = 1; + $arr['author_xchan'] = $poster['xchan_hash']; + $arr['owner_xchan'] = $poster['xchan_hash']; //?? + $arr['title'] = $object['filename']; + $arr['item_notshown'] = 1; + $arr['obj_type'] = $objtype; + $arr['resource_id'] = $object['hash']; + $arr['resource_type'] = 'attach'; - $arr = []; - $arr['aid'] = get_account_id(); - $arr['uid'] = $channel_id; - $arr['uuid'] = $uuid; - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_unseen'] = 1; - $arr['author_xchan'] = $poster['xchan_hash']; - $arr['owner_xchan'] = $poster['xchan_hash']; //?? - $arr['title'] = $object['filename']; - $arr['item_notshown'] = 1; - $arr['obj_type'] = $objtype; - $arr['resource_id'] = $object['hash']; - $arr['resource_type'] = 'attach'; + $private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0); - $private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0); + $obj = [ + 'type' => 'Document', + 'id' => z_root() . '/attach/' . $object['hash'], + 'name' => $object['filename'], + ]; - $obj= [ - 'type' => 'Document', - 'id' => z_root() . '/attach/' . $object['hash'], - 'name' => $object['filename'], - ]; - - $obj['url'] = array_merge($object['url'],[ - 'type' => 'Link', - 'mediaType' => $object['filetype'], - 'href' => z_root() . '/attach/' . $object['hash'] - ]); + $obj['url'] = array_merge($object['url'], [ + 'type' => 'Link', + 'mediaType' => $object['filetype'], + 'href' => z_root() . '/attach/' . $object['hash'] + ]); - $jsonobject = json_encode($obj); + $jsonobject = json_encode($obj); - //check if item for this object exists - $y = q("SELECT mid FROM item WHERE verb = '%s' AND obj_type = '%s' AND resource_id = '%s' AND uid = %d LIMIT 1", - dbesc(ACTIVITY_POST), - dbesc($objtype), - dbesc($object['hash']), - intval(local_channel()) - ); + //check if item for this object exists + $y = q( + "SELECT mid FROM item WHERE verb = '%s' AND obj_type = '%s' AND resource_id = '%s' AND uid = %d LIMIT 1", + dbesc(ACTIVITY_POST), + dbesc($objtype), + dbesc($object['hash']), + intval(local_channel()) + ); - if ($y) { - $update = true; - $object['d_mid'] = $y[0]['mid']; //attach mid of the old object - $u_jsonobject = json_encode($obj); + if ($y) { + $update = true; + $object['d_mid'] = $y[0]['mid']; //attach mid of the old object + $u_jsonobject = json_encode($obj); - // we have got the relevant info - delete the old item before we create the new one - $z = q("DELETE FROM item WHERE obj_type = '%s' AND verb = '%s' AND mid = '%s'", - dbesc(ACTIVITY_OBJ_FILE), - dbesc(ACTIVITY_POST), - dbesc($y[0]['mid']) - ); + // we have got the relevant info - delete the old item before we create the new one + $z = q( + "DELETE FROM item WHERE obj_type = '%s' AND verb = '%s' AND mid = '%s'", + dbesc(ACTIVITY_OBJ_FILE), + dbesc(ACTIVITY_POST), + dbesc($y[0]['mid']) + ); + } - } + // send update activity and create a new one + if ($update && $verb == 'post') { + //updates should be sent to everybody with recursive perms and all eventual former allowed members ($object['allow_cid'] etc.). + $u_arr_allow_cid = array_unique(array_merge($arr_allow_cid, expand_acl($object['allow_cid']))); + $u_arr_allow_gid = array_unique(array_merge($arr_allow_gid, expand_acl($object['allow_gid']))); + $u_arr_deny_cid = array_unique(array_merge($arr_deny_cid, expand_acl($object['deny_cid']))); + $u_arr_deny_gid = array_unique(array_merge($arr_deny_gid, expand_acl($object['deny_gid']))); - // send update activity and create a new one - if ($update && $verb == 'post' ) { - //updates should be sent to everybody with recursive perms and all eventual former allowed members ($object['allow_cid'] etc.). - $u_arr_allow_cid = array_unique(array_merge($arr_allow_cid, expand_acl($object['allow_cid']))); - $u_arr_allow_gid = array_unique(array_merge($arr_allow_gid, expand_acl($object['allow_gid']))); - $u_arr_deny_cid = array_unique(array_merge($arr_deny_cid, expand_acl($object['deny_cid']))); - $u_arr_deny_gid = array_unique(array_merge($arr_deny_gid, expand_acl($object['deny_gid']))); + $private = (($u_arr_allow_cid[0] || $u_arr_allow_gid[0] || $u_arr_deny_cid[0] || $u_arr_deny_gid[0]) ? 1 : 0); - $private = (($u_arr_allow_cid[0] || $u_arr_allow_gid[0] || $u_arr_deny_cid[0] || $u_arr_deny_gid[0]) ? 1 : 0); + $uuid = new_uuid(); + $u_mid = z_root() . '/item/' . $uuid; - $uuid = new_uuid(); - $u_mid = z_root() . '/item/' . $uuid; + $arr['uuid'] = $uuid; + $arr['mid'] = $u_mid; + $arr['parent_mid'] = $u_mid; + $arr['allow_cid'] = perms2str($u_arr_allow_cid); + $arr['allow_gid'] = perms2str($u_arr_allow_gid); + $arr['deny_cid'] = perms2str($u_arr_deny_cid); + $arr['deny_gid'] = perms2str($u_arr_deny_gid); + $arr['item_private'] = $private; + $arr['verb'] = ACTIVITY_UPDATE; + $arr['obj'] = $u_jsonobject; + $arr['body'] = ''; - $arr['uuid'] = $uuid; - $arr['mid'] = $u_mid; - $arr['parent_mid'] = $u_mid; - $arr['allow_cid'] = perms2str($u_arr_allow_cid); - $arr['allow_gid'] = perms2str($u_arr_allow_gid); - $arr['deny_cid'] = perms2str($u_arr_deny_cid); - $arr['deny_gid'] = perms2str($u_arr_deny_gid); - $arr['item_private'] = $private; - $arr['verb'] = ACTIVITY_UPDATE; - $arr['obj'] = $u_jsonobject; - $arr['body'] = ''; + post_activity_item($arr); - post_activity_item($arr); + $update = false; + } - $update = false; - } + // don't create new activity if notify was not enabled + if (! $notify) { + return; + } - // don't create new activity if notify was not enabled - if (! $notify) { - return; - } + //don't create new activity if we have an update request but there is no item to update + //this can e.g. happen when deleting images + if ((! $y) && ($verb == 'update')) { + return; + } - //don't create new activity if we have an update request but there is no item to update - //this can e.g. happen when deleting images - if ((! $y) && ($verb == 'update')) { - return; - } + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['allow_cid'] = perms2str($arr_allow_cid); + $arr['allow_gid'] = perms2str($arr_allow_gid); + $arr['deny_cid'] = perms2str($arr_deny_cid); + $arr['deny_gid'] = perms2str($arr_deny_gid); + $arr['item_private'] = $private; + $arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST); + $arr['obj'] = (($update) ? $u_jsonobject : $jsonobject); + $arr['body'] = ''; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['allow_cid'] = perms2str($arr_allow_cid); - $arr['allow_gid'] = perms2str($arr_allow_gid); - $arr['deny_cid'] = perms2str($arr_deny_cid); - $arr['deny_gid'] = perms2str($arr_deny_gid); - $arr['item_private'] = $private; - $arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST); - $arr['obj'] = (($update) ? $u_jsonobject : $jsonobject); - $arr['body'] = ''; + post_activity_item($arr); - post_activity_item($arr); - - return; + return; } /** @@ -1990,34 +2063,36 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, * @param string $url * @return array An associative array for the specified file. */ -function get_file_activity_object($channel_id, $hash, $url) { +function get_file_activity_object($channel_id, $hash, $url) +{ - $x = q("SELECT creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", - intval($channel_id), - dbesc($hash) - ); - if (! $x) { - return null; - } - - $url = rawurlencode($url); + $x = q( + "SELECT creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", + intval($channel_id), + dbesc($hash) + ); + if (! $x) { + return null; + } - $links = []; - $links[] = [ - 'rel' => 'alternate', - 'mediaType' => 'text/html', - 'href' => $url - ]; + $url = rawurlencode($url); - $object = array_merge( [ - 'type' => ACTIVITY_OBJ_FILE, - 'title' => $x[0]['filename'], - 'id' => $url, - 'url' => $links, - 'hash' => $hash, - ], $x[0]); + $links = []; + $links[] = [ + 'rel' => 'alternate', + 'mediaType' => 'text/html', + 'href' => $url + ]; - return $object; + $object = array_merge([ + 'type' => ACTIVITY_OBJ_FILE, + 'title' => $x[0]['filename'], + 'id' => $url, + 'url' => $links, + 'hash' => $hash, + ], $x[0]); + + return $object; } /** @@ -2029,228 +2104,236 @@ function get_file_activity_object($channel_id, $hash, $url) { * @param array $arr_deny_gid * @param string $folder_hash */ -function attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash) { +function attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash) +{ - $ret = []; - $parent_arr = []; - $count_values = []; - $poster = App::get_observer(); + $ret = []; + $parent_arr = []; + $count_values = []; + $poster = App::get_observer(); - //lookup all channels in sharee group and add them to sharee $arr_allow_cid - if ($arr_allow_gid) { - $in_group = AccessList::expand($arr_allow_gid); - $arr_allow_cid = array_unique(array_merge($arr_allow_cid, $in_group)); - } + //lookup all channels in sharee group and add them to sharee $arr_allow_cid + if ($arr_allow_gid) { + $in_group = AccessList::expand($arr_allow_gid); + $arr_allow_cid = array_unique(array_merge($arr_allow_cid, $in_group)); + } - //count existing parent folders - we will compare to that count later - $count = 0; - while ($folder_hash) { - $x = q("SELECT allow_cid, allow_gid, deny_cid, deny_gid, folder FROM attach WHERE hash = '%s' LIMIT 1", - dbesc($folder_hash) - ); + //count existing parent folders - we will compare to that count later + $count = 0; + while ($folder_hash) { + $x = q( + "SELECT allow_cid, allow_gid, deny_cid, deny_gid, folder FROM attach WHERE hash = '%s' LIMIT 1", + dbesc($folder_hash) + ); - //only process private folders - if ($x[0]['allow_cid'] || $x[0]['allow_gid'] || $x[0]['deny_cid'] || $x[0]['deny_gid']) { - $parent_arr['allow_cid'][] = expand_acl($x[0]['allow_cid']); - $parent_arr['allow_gid'][] = expand_acl($x[0]['allow_gid']); - $parent_arr['deny_cid'][] = expand_acl($x[0]['deny_cid']); - $parent_arr['deny_gid'][] = expand_acl($x[0]['deny_gid']); + //only process private folders + if ($x[0]['allow_cid'] || $x[0]['allow_gid'] || $x[0]['deny_cid'] || $x[0]['deny_gid']) { + $parent_arr['allow_cid'][] = expand_acl($x[0]['allow_cid']); + $parent_arr['allow_gid'][] = expand_acl($x[0]['allow_gid']); + $parent_arr['deny_cid'][] = expand_acl($x[0]['deny_cid']); + $parent_arr['deny_gid'][] = expand_acl($x[0]['deny_gid']); - //this is the number of all existing parent folders - we will compare to that count later - $count++; - } + //this is the number of all existing parent folders - we will compare to that count later + $count++; + } - $folder_hash = $x[0]['folder']; - } + $folder_hash = $x[0]['folder']; + } - //logger(EOL . 'parent_arr: ' . print_r($parent_arr,true)); + //logger(EOL . 'parent_arr: ' . print_r($parent_arr,true)); - //if none of the parent folders is private just return file perms - if (!$parent_arr['allow_cid'] && !$parent_arr['allow_gid'] && !$parent_arr['deny_cid'] && !$parent_arr['deny_gid']) { - $ret['allow_gid'] = $arr_allow_gid; - $ret['allow_cid'] = $arr_allow_cid; - $ret['deny_gid'] = $arr_deny_gid; - $ret['deny_cid'] = $arr_deny_cid; + //if none of the parent folders is private just return file perms + if (!$parent_arr['allow_cid'] && !$parent_arr['allow_gid'] && !$parent_arr['deny_cid'] && !$parent_arr['deny_gid']) { + $ret['allow_gid'] = $arr_allow_gid; + $ret['allow_cid'] = $arr_allow_cid; + $ret['deny_gid'] = $arr_deny_gid; + $ret['deny_cid'] = $arr_deny_cid; - return $ret; - } + return $ret; + } - //if there are no perms on the file we will work with the perms from the first parent folder - if (!$arr_allow_cid && !$arr_allow_gid && !$arr_deny_cid && !$arr_deny_gid) { - $arr_allow_cid = $parent_arr['allow_cid'][0]; - $arr_allow_gid = $parent_arr['allow_gid'][0]; - $arr_deny_cid = $parent_arr['deny_cid'][0]; - $arr_deny_gid = $parent_arr['deny_gid'][0]; - } + //if there are no perms on the file we will work with the perms from the first parent folder + if (!$arr_allow_cid && !$arr_allow_gid && !$arr_deny_cid && !$arr_deny_gid) { + $arr_allow_cid = $parent_arr['allow_cid'][0]; + $arr_allow_gid = $parent_arr['allow_gid'][0]; + $arr_deny_cid = $parent_arr['deny_cid'][0]; + $arr_deny_gid = $parent_arr['deny_gid'][0]; + } - /*** - * - * check if sharee has perms for all parent folders - * - ***/ + /*** + * + * check if sharee has perms for all parent folders + * + ***/ - $r_arr_allow_cid = []; + $r_arr_allow_cid = []; - if ($parent_arr['allow_cid']) { - //check sharee arr_allow_cid against allow_cid of all parent folders - foreach ($parent_arr['allow_cid'] as $folder_arr_allow_cid) { - foreach ($folder_arr_allow_cid as $ac_hash) { - $count_values[$ac_hash]++; - } - } - foreach ($arr_allow_cid as $fac_hash) { - if ($count_values[$fac_hash] == $count) { - $r_arr_allow_cid[] = $fac_hash; - } - } - //logger(EOL . 'r_arr_allow_cid: ' . print_r($r_arr_allow_cid,true)); - } + if ($parent_arr['allow_cid']) { + //check sharee arr_allow_cid against allow_cid of all parent folders + foreach ($parent_arr['allow_cid'] as $folder_arr_allow_cid) { + foreach ($folder_arr_allow_cid as $ac_hash) { + $count_values[$ac_hash]++; + } + } + foreach ($arr_allow_cid as $fac_hash) { + if ($count_values[$fac_hash] == $count) { + $r_arr_allow_cid[] = $fac_hash; + } + } + //logger(EOL . 'r_arr_allow_cid: ' . print_r($r_arr_allow_cid,true)); + } - if ($parent_arr['allow_gid']) { - //check sharee arr_allow_cid against members of allow_gid of all parent folders - foreach ($parent_arr['allow_gid'] as $folder_arr_allow_gid) { - //get the group members - $folder_arr_allow_cid = AccessList::expand($folder_arr_allow_gid); - foreach ($folder_arr_allow_cid as $ac_hash) { - $count_values[$ac_hash]++; - } - } - foreach ($arr_allow_cid as $fac_hash) { - if ($count_values[$fac_hash] == $count) { - $r_arr_allow_cid[] = $fac_hash; - } - } - //logger(EOL . 'groups - r_arr_allow_cid: ' . print_r($r_arr_allow_cid,true)); - } + if ($parent_arr['allow_gid']) { + //check sharee arr_allow_cid against members of allow_gid of all parent folders + foreach ($parent_arr['allow_gid'] as $folder_arr_allow_gid) { + //get the group members + $folder_arr_allow_cid = AccessList::expand($folder_arr_allow_gid); + foreach ($folder_arr_allow_cid as $ac_hash) { + $count_values[$ac_hash]++; + } + } + foreach ($arr_allow_cid as $fac_hash) { + if ($count_values[$fac_hash] == $count) { + $r_arr_allow_cid[] = $fac_hash; + } + } + //logger(EOL . 'groups - r_arr_allow_cid: ' . print_r($r_arr_allow_cid,true)); + } - /*** - * - * check if sharee is denied somewhere in parent folders and deny him if so - * - ***/ + /*** + * + * check if sharee is denied somewhere in parent folders and deny him if so + * + ***/ - //deny_cid - $r_arr_deny_cid = []; + //deny_cid + $r_arr_deny_cid = []; - if ($parent_arr['deny_cid']) { - foreach ($parent_arr['deny_cid'] as $folder_arr_deny_cid) { - $r_arr_deny_cid = array_merge($arr_deny_cid, $folder_arr_deny_cid); - } - $r_arr_deny_cid = array_unique($r_arr_deny_cid); - //logger(EOL . 'r_arr_deny_cid: ' . print_r($r_arr_deny_cid,true)); - } + if ($parent_arr['deny_cid']) { + foreach ($parent_arr['deny_cid'] as $folder_arr_deny_cid) { + $r_arr_deny_cid = array_merge($arr_deny_cid, $folder_arr_deny_cid); + } + $r_arr_deny_cid = array_unique($r_arr_deny_cid); + //logger(EOL . 'r_arr_deny_cid: ' . print_r($r_arr_deny_cid,true)); + } - //deny_gid - $r_arr_deny_gid = []; + //deny_gid + $r_arr_deny_gid = []; - if ($parent_arr['deny_cid']) { - foreach ($parent_arr['deny_gid'] as $folder_arr_deny_gid) { - $r_arr_deny_gid = array_merge($arr_deny_gid, $folder_arr_deny_gid); - } - $r_arr_deny_gid = array_unique($r_arr_deny_gid); - //logger(EOL . 'r_arr_deny_gid: ' . print_r($r_arr_dr_arr_deny_gideny_cid,true)); - } + if ($parent_arr['deny_cid']) { + foreach ($parent_arr['deny_gid'] as $folder_arr_deny_gid) { + $r_arr_deny_gid = array_merge($arr_deny_gid, $folder_arr_deny_gid); + } + $r_arr_deny_gid = array_unique($r_arr_deny_gid); + //logger(EOL . 'r_arr_deny_gid: ' . print_r($r_arr_dr_arr_deny_gideny_cid,true)); + } - //if no channel is allowed return false - if (! $r_arr_allow_cid) { - return false; - } + //if no channel is allowed return false + if (! $r_arr_allow_cid) { + return false; + } - $ret['allow_gid'] = []; // eventual group members are already collected in $r_arr_allow_cid - $ret['allow_cid'] = $r_arr_allow_cid; - $ret['deny_gid'] = $r_arr_deny_gid; - $ret['deny_cid'] = $r_arr_deny_cid; + $ret['allow_gid'] = []; // eventual group members are already collected in $r_arr_allow_cid + $ret['allow_cid'] = $r_arr_allow_cid; + $ret['deny_gid'] = $r_arr_deny_gid; + $ret['deny_cid'] = $r_arr_deny_cid; - return $ret; + return $ret; } -function filepath_macro($s) { - - return str_replace( - [ '%Y', '%m', '%d' ], - [ datetime_convert('UTC',date_default_timezone_get(),'now', 'Y'), - datetime_convert('UTC',date_default_timezone_get(),'now', 'm'), - datetime_convert('UTC',date_default_timezone_get(),'now', 'd') - ], $s); +function filepath_macro($s) +{ + return str_replace( + [ '%Y', '%m', '%d' ], + [ datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'), + datetime_convert('UTC', date_default_timezone_get(), 'now', 'm'), + datetime_convert('UTC', date_default_timezone_get(), 'now', 'd') + ], + $s + ); } -function attach_export_data($channel, $resource_id, $deleted = false) { +function attach_export_data($channel, $resource_id, $deleted = false) +{ - $ret = []; + $ret = []; - $paths = []; + $paths = []; - $hash_ptr = $resource_id; + $hash_ptr = $resource_id; - $ret['fetch_url'] = z_root() . '/getfile'; - $ret['original_channel'] = $channel['channel_address']; + $ret['fetch_url'] = z_root() . '/getfile'; + $ret['original_channel'] = $channel['channel_address']; - if ($deleted) { - $ret['attach'] = [ [ 'hash' => $resource_id, 'deleted' => 1 ] ]; - return $ret; - } + if ($deleted) { + $ret['attach'] = [ [ 'hash' => $resource_id, 'deleted' => 1 ] ]; + return $ret; + } - do { - $r = q("select * from attach where hash = '%s' and uid = %d limit 1", - dbesc($hash_ptr), - intval($channel['channel_id']) - ); - if (! $r) { - break; - } + do { + $r = q( + "select * from attach where hash = '%s' and uid = %d limit 1", + dbesc($hash_ptr), + intval($channel['channel_id']) + ); + if (! $r) { + break; + } - if ($hash_ptr === $resource_id) { - $attach_ptr = $r[0]; - } - $r[0]['content'] = dbunescbin($r[0]['content']); + if ($hash_ptr === $resource_id) { + $attach_ptr = $r[0]; + } + $r[0]['content'] = dbunescbin($r[0]['content']); - $hash_ptr = $r[0]['folder']; - $paths[] = $r[0]; - } while($hash_ptr); + $hash_ptr = $r[0]['folder']; + $paths[] = $r[0]; + } while ($hash_ptr); - $paths = array_reverse($paths); + $paths = array_reverse($paths); - $ret['attach'] = $paths; + $ret['attach'] = $paths; - if ($attach_ptr['is_photo']) { + if ($attach_ptr['is_photo']) { + $r = q( + "select * from photo where resource_id = '%s' and uid = %d order by imgscale asc", + dbesc($resource_id), + intval($channel['channel_id']) + ); + if ($r) { + for ($x = 0; $x < count($r); $x++) { + $r[$x]['content'] = base64_encode(dbunescbin($r[$x]['content'])); + } + $ret['photo'] = $r; + } - $r = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale asc", - dbesc($resource_id), - intval($channel['channel_id']) - ); - if ($r) { - for ($x = 0; $x < count($r); $x ++) { - $r[$x]['content'] = base64_encode(dbunescbin($r[$x]['content'])); - } - $ret['photo'] = $r; - } + $r = q( + "select * from item where resource_id = '%s' and resource_type = 'photo' and uid = %d ", + dbesc($resource_id), + intval($channel['channel_id']) + ); + if ($r) { + $ret['item'] = []; + $items = q( + "select item.*, item.id as item_id from item where item.parent = %d ", + intval($r[0]['id']) + ); + if ($items) { + xchan_query($items); + $items = fetch_post_tags($items, true); + foreach ($items as $rr) { + $ret['item'][] = encode_item($rr, true); + } + } + } + } - $r = q("select * from item where resource_id = '%s' and resource_type = 'photo' and uid = %d ", - dbesc($resource_id), - intval($channel['channel_id']) - ); - if ($r) { - $ret['item'] = []; - $items = q("select item.*, item.id as item_id from item where item.parent = %d ", - intval($r[0]['id']) - ); - if ($items) { - xchan_query($items); - $items = fetch_post_tags($items,true); - foreach ($items as $rr) { - $ret['item'][] = encode_item($rr,true); - } - } - } - } - - return $ret; + return $ret; } @@ -2260,80 +2343,81 @@ function attach_export_data($channel, $resource_id, $deleted = false) { * @param string $s * @return string */ -function get_attach_binname($s) { - $p = $s; - if (strpos($s, 'store/') === 0) { - $p = substr($s, 6); - $p = substr($p, strpos($p, '/') + 1); - } +function get_attach_binname($s) +{ + $p = $s; + if (strpos($s, 'store/') === 0) { + $p = substr($s, 6); + $p = substr($p, strpos($p, '/') + 1); + } - return $p; + return $p; } -function get_dirpath_by_cloudpath($channel, $path) { +function get_dirpath_by_cloudpath($channel, $path) +{ - $path = notags(trim($path)); + $path = notags(trim($path)); - $h = @parse_url($path); + $h = @parse_url($path); - if (! $h || !x($h, 'path')) { - return null; - } - if (substr($h['path'], -1, 1) === '/') { - $h['path'] = substr($h['path'], 0, -1); - } - if (substr($h['path'],0,1) === '/') { - $h['path'] = substr($h['path'], 1); - } - $folders = explode('/', $h['path']); - $f = array_shift($folders); + if (! $h || !x($h, 'path')) { + return null; + } + if (substr($h['path'], -1, 1) === '/') { + $h['path'] = substr($h['path'], 0, -1); + } + if (substr($h['path'], 0, 1) === '/') { + $h['path'] = substr($h['path'], 1); + } + $folders = explode('/', $h['path']); + $f = array_shift($folders); - $nick = $channel['channel_address']; - //check to see if the absolute path was provided (/cloud/channelname/path/to/folder) - if ($f === 'cloud' ) { - $g = array_shift($folders); - if ($g !== $nick) { - // if nick does not follow "cloud", then the top level folder must be called "cloud" - // and the given path must be relative to "/cloud/channelname/". - $folders = array_unshift(array_unshift($folders, $g), $f); - } - } - else { - array_unshift($folders, $f); - } - $clouddir = 'store/' . $nick . '/' ; - $subdir = '/'; - $valid = true; - while ($folders && $valid && is_dir($clouddir . $subdir) && is_readable($clouddir . $subdir)) { - $valid = false; - $f = array_shift($folders); - $items = array_diff(scandir($clouddir . $subdir), array('.', '..')); // hashed names - foreach ($items as $item) { - $filename = find_filename_by_hash($channel['channel_id'], $item); - if ($filename === $f) { - $subdir .= $item . '/'; - $valid = true; - } - } - } - if (! $valid) { - return null; - } - else { - return $clouddir . $subdir; - } + $nick = $channel['channel_address']; + //check to see if the absolute path was provided (/cloud/channelname/path/to/folder) + if ($f === 'cloud') { + $g = array_shift($folders); + if ($g !== $nick) { + // if nick does not follow "cloud", then the top level folder must be called "cloud" + // and the given path must be relative to "/cloud/channelname/". + $folders = array_unshift(array_unshift($folders, $g), $f); + } + } else { + array_unshift($folders, $f); + } + $clouddir = 'store/' . $nick . '/' ; + $subdir = '/'; + $valid = true; + while ($folders && $valid && is_dir($clouddir . $subdir) && is_readable($clouddir . $subdir)) { + $valid = false; + $f = array_shift($folders); + $items = array_diff(scandir($clouddir . $subdir), array('.', '..')); // hashed names + foreach ($items as $item) { + $filename = find_filename_by_hash($channel['channel_id'], $item); + if ($filename === $f) { + $subdir .= $item . '/'; + $valid = true; + } + } + } + if (! $valid) { + return null; + } else { + return $clouddir . $subdir; + } } -function get_filename_by_cloudname($cloudname, $channel, $storepath) { - $items = array_diff(scandir($storepath), array('.', '..')); // hashed names - foreach ($items as $item) { - $filename = find_filename_by_hash($channel['channel_id'], $item); - if ($filename === $cloudname) { - return $item; - } - } - return null; +function get_filename_by_cloudname($cloudname, $channel, $storepath) +{ + $items = array_diff(scandir($storepath), array('.', '..')); // hashed names + foreach ($items as $item) { + $filename = find_filename_by_hash($channel['channel_id'], $item); + if ($filename === $cloudname) { + return $item; + } + } + return null; } /** @@ -2345,49 +2429,48 @@ function get_filename_by_cloudname($cloudname, $channel, $storepath) { * @param string $cloudpath * @return bool */ -function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpath) { - if (!is_dir($srcpath) || !is_readable($srcpath)) { - logger('Error reading source path: ' . $srcpath, LOGGER_NORMAL); - return false; - } - $nodes = array_diff(scandir($srcpath), array('.', '..')); - foreach ($nodes as $node) { - $clouddir = $cloudpath . '/' . $node; // Sub-folder in cloud files destination - $nodepath = $srcpath . '/' . $node; // Sub-folder in source path - if (is_dir($nodepath)) { - $x = attach_mkdirp($channel, $observer_hash, array('pathname' => $clouddir)); - if (!$x['success']) { - logger('Error creating cloud path: ' . $clouddir, LOGGER_NORMAL); - return false; - } - // Recursively call this function where the source and destination are the subfolders - $success = copy_folder_to_cloudfiles($channel, $observer_hash, $nodepath, $clouddir); - if (! $success) { - logger('Error copying contents of folder: ' . $nodepath, LOGGER_NORMAL); - return false; - } - } - elseif (is_file($nodepath) && is_readable($nodepath)) { - $x = attach_store($channel, $observer_hash, 'import', [ - 'directory' => $cloudpath, - 'src' => $nodepath, - 'filename' => $node, - 'filesize' => @filesize($nodepath), - 'preserve_original' => true - ]); - if (! $x['success']) { - logger('Error copying file: ' . $nodepath, LOGGER_NORMAL); - logger('Return value: ' . json_encode($x), LOGGER_NORMAL); - return false; - } - } - else { - logger('Error scanning source path', LOGGER_NORMAL); - return false; - } - } +function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpath) +{ + if (!is_dir($srcpath) || !is_readable($srcpath)) { + logger('Error reading source path: ' . $srcpath, LOGGER_NORMAL); + return false; + } + $nodes = array_diff(scandir($srcpath), array('.', '..')); + foreach ($nodes as $node) { + $clouddir = $cloudpath . '/' . $node; // Sub-folder in cloud files destination + $nodepath = $srcpath . '/' . $node; // Sub-folder in source path + if (is_dir($nodepath)) { + $x = attach_mkdirp($channel, $observer_hash, array('pathname' => $clouddir)); + if (!$x['success']) { + logger('Error creating cloud path: ' . $clouddir, LOGGER_NORMAL); + return false; + } + // Recursively call this function where the source and destination are the subfolders + $success = copy_folder_to_cloudfiles($channel, $observer_hash, $nodepath, $clouddir); + if (! $success) { + logger('Error copying contents of folder: ' . $nodepath, LOGGER_NORMAL); + return false; + } + } elseif (is_file($nodepath) && is_readable($nodepath)) { + $x = attach_store($channel, $observer_hash, 'import', [ + 'directory' => $cloudpath, + 'src' => $nodepath, + 'filename' => $node, + 'filesize' => @filesize($nodepath), + 'preserve_original' => true + ]); + if (! $x['success']) { + logger('Error copying file: ' . $nodepath, LOGGER_NORMAL); + logger('Return value: ' . json_encode($x), LOGGER_NORMAL); + return false; + } + } else { + logger('Error scanning source path', LOGGER_NORMAL); + return false; + } + } - return true; + return true; } /** @@ -2406,232 +2489,238 @@ function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpat * @return void|bool */ -function attach_move($channel_id, $resource_id, $new_folder_hash, $newname = '') { +function attach_move($channel_id, $resource_id, $new_folder_hash, $newname = '') +{ - $c = channelx_by_n($channel_id); - if (! ($c && $resource_id)) { - return false; - } + $c = channelx_by_n($channel_id); + if (! ($c && $resource_id)) { + return false; + } - // find the resource to be moved + // find the resource to be moved - $r = q("select * from attach where hash = '%s' and uid = %d limit 1", - dbesc($resource_id), - intval($channel_id) - ); - if (! $r) { - logger('resource_id not found'); - return false; - } + $r = q( + "select * from attach where hash = '%s' and uid = %d limit 1", + dbesc($resource_id), + intval($channel_id) + ); + if (! $r) { + logger('resource_id not found'); + return false; + } - $oldstorepath = dbunescbin($r[0]['content']); + $oldstorepath = dbunescbin($r[0]['content']); - // find the resource we are moving to + // find the resource we are moving to - if ($new_folder_hash) { - $n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1", - dbesc($new_folder_hash), - intval($channel_id) - ); - if (! $n) { - return false; - } + if ($new_folder_hash) { + $n = q( + "select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1", + dbesc($new_folder_hash), + intval($channel_id) + ); + if (! $n) { + return false; + } - $newdirname = $n[0]['filename']; - $newalbumname = $n[0]['display_path']; - $newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id; - } - else { + $newdirname = $n[0]['filename']; + $newalbumname = $n[0]['display_path']; + $newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id; + } else { + // root directory - // root directory + $newdirname = EMPTY_STR; + $newalbumname = EMPTY_STR; + $newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id; + } - $newdirname = EMPTY_STR; - $newalbumname = EMPTY_STR; - $newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id; - } + rename($oldstorepath, $newstorepath); - rename($oldstorepath,$newstorepath); + // duplicate detection. If 'overwrite' is specified, return false because we can't yet do that. - // duplicate detection. If 'overwrite' is specified, return false because we can't yet do that. + $oldfilename = $r[0]['filename']; + $newfilename = (($newname) ? basename($newname) : $oldfilename); - $oldfilename = $r[0]['filename']; - $newfilename = (($newname) ? basename($newname) : $oldfilename); + // don't do duplicate check unless our parent folder has changed. - // don't do duplicate check unless our parent folder has changed. + if ($r[0]['folder'] !== $new_folder_hash) { + $s = q( + "select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ", + dbesc($newfilename), + dbesc($new_folder_hash) + ); - if ($r[0]['folder'] !== $new_folder_hash) { + if ($s) { + $overwrite = get_pconfig($channel_id, 'system', 'overwrite_dup_files'); + if ($overwrite) { + /// @fixme + return; + } else { + if (strpos($newfilename, '.') !== false) { + $basename = substr($newfilename, 0, strrpos($newfilename, '.')); + $ext = substr($newfilename, strrpos($newfilename, '.')); + } else { + $basename = $newfilename; + $ext = ''; + } - $s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ", - dbesc($newfilename), - dbesc($new_folder_hash) - ); + $matches = false; + if (preg_match('/(.*?)\([0-9]{1,}\)$/', $basename, $matches)) { + $basename = $matches[1]; + } - if ($s) { - $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files'); - if ($overwrite) { - /// @fixme - return; - } - else { - if (strpos($newfilename,'.') !== false) { - $basename = substr($newfilename,0,strrpos($newfilename,'.')); - $ext = substr($newfilename,strrpos($newfilename,'.')); - } - else { - $basename = $newfilename; - $ext = ''; - } + $v = q( + "select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ", + dbesc($basename . $ext), + dbesc($basename . '(%)' . $ext), + dbesc($new_folder_hash) + ); - $matches = false; - if (preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches)) { - $basename = $matches[1]; - } + if ($v) { + $x = 1; - $v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ", - dbesc($basename . $ext), - dbesc($basename . '(%)' . $ext), - dbesc($new_folder_hash) - ); + do { + $found = false; + foreach ($v as $vv) { + if ($vv['filename'] === $basename . '(' . $x . ')' . $ext) { + $found = true; + break; + } + } + if ($found) { + $x++; + } + } while ($found); - if ($v) { - $x = 1; + $newfilename = $basename . '(' . $x . ')' . $ext; + } else { + $newfilename = $basename . $ext; + } + } + } + } - do { - $found = false; - foreach ($v as $vv) { - if ($vv['filename'] === $basename . '(' . $x . ')' . $ext) { - $found = true; - break; - } - } - if ($found) { - $x++; - } - } while ($found); - - $newfilename = $basename . '(' . $x . ')' . $ext; - } - else { - $newfilename = $basename . $ext; - } - } - } - } - - $t = q("update attach set content = '%s', folder = '%s', filename = '%s' where id = %d", - dbescbin($newstorepath), - dbesc($new_folder_hash), - dbesc($newfilename), - intval($r[0]['id']) - ); + $t = q( + "update attach set content = '%s', folder = '%s', filename = '%s' where id = %d", + dbescbin($newstorepath), + dbesc($new_folder_hash), + dbesc($newfilename), + intval($r[0]['id']) + ); - $x = attach_syspaths($channel_id,$resource_id); + $x = attach_syspaths($channel_id, $resource_id); - $t1 = q("update attach set os_path = '%s', display_path = '%s' where id = %d", - dbesc($x['os_path']), - dbesc($x['path']), - intval($r[0]['id']) - ); + $t1 = q( + "update attach set os_path = '%s', display_path = '%s' where id = %d", + dbesc($x['os_path']), + dbesc($x['path']), + intval($r[0]['id']) + ); - if ($r[0]['is_photo']) { - $t = q("update photo set album = '%s', filename = '%s', os_path = '%s', display_path = '%s' + if ($r[0]['is_photo']) { + $t = q( + "update photo set album = '%s', filename = '%s', os_path = '%s', display_path = '%s' where resource_id = '%s' and uid = %d", - dbesc($newalbumname), - dbesc($newfilename), - dbesc($x['os_path']), - dbesc($x['path']), - dbesc($resource_id), - intval($channel_id) - ); + dbesc($newalbumname), + dbesc($newfilename), + dbesc($x['os_path']), + dbesc($x['path']), + dbesc($resource_id), + intval($channel_id) + ); - $t = q("update photo set content = '%s' where resource_id = '%s' and uid = %d and imgscale = 0", - dbescbin($newstorepath), - dbesc($resource_id), - intval($channel_id) - ); - } + $t = q( + "update photo set content = '%s' where resource_id = '%s' and uid = %d and imgscale = 0", + dbescbin($newstorepath), + dbesc($resource_id), + intval($channel_id) + ); + } - if ($r[0]['is_dir']) { - $move_success = true; - $x = q("select hash from attach where folder = '%s' and uid = %d", - dbesc($r[0]['hash']), - intval($channel_id) - ); - if ($x) { - foreach ($x as $xv) { - $rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']); - if (! $rs) { - $move_success = false; - break; - } - } - } - return $move_success; - } + if ($r[0]['is_dir']) { + $move_success = true; + $x = q( + "select hash from attach where folder = '%s' and uid = %d", + dbesc($r[0]['hash']), + intval($channel_id) + ); + if ($x) { + foreach ($x as $xv) { + $rs = attach_move($channel_id, $xv['hash'], $r[0]['hash']); + if (! $rs) { + $move_success = false; + break; + } + } + } + return $move_success; + } - return true; + return true; } /** - * Used to generate a select input box of all your folders + * Used to generate a select input box of all your folders */ -function attach_folder_select_list($channel_id) { +function attach_folder_select_list($channel_id) +{ - $r = q("select * from attach where is_dir = 1 and uid = %d", - intval($channel_id) - ); + $r = q( + "select * from attach where is_dir = 1 and uid = %d", + intval($channel_id) + ); - $out = []; - $out[''] = '/'; + $out = []; + $out[''] = '/'; - if ($r) { - foreach ($r as $rv) { - $x = attach_folder_rpaths($r,$rv); - if ($x) { - $out[$x[0]] = $x[1]; - } - } - } + if ($r) { + foreach ($r as $rv) { + $x = attach_folder_rpaths($r, $rv); + if ($x) { + $out[$x[0]] = $x[1]; + } + } + } - return $out; + return $out; } -function attach_folder_rpaths($all_folders,$that_folder) { +function attach_folder_rpaths($all_folders, $that_folder) +{ - $path = '/' . $that_folder['filename']; - $current_hash = $that_folder['hash']; - $parent_hash = $that_folder['folder']; - $error = false; - $found = false; + $path = '/' . $that_folder['filename']; + $current_hash = $that_folder['hash']; + $parent_hash = $that_folder['folder']; + $error = false; + $found = false; - if ($parent_hash) { - do { - foreach ($all_folders as $selected) { - if (! $selected['is_dir']) { - continue; - } - if ($selected['hash'] == $parent_hash) { - $path = '/' . $selected['filename'] . $path; - $parent_hash = $selected['folder']; - $found = true; - break; - } - } - if (! $found) { - $error = true; - } - } - while ((! $found) && (! $error) && ($parent_hash != '')); - } + if ($parent_hash) { + do { + foreach ($all_folders as $selected) { + if (! $selected['is_dir']) { + continue; + } + if ($selected['hash'] == $parent_hash) { + $path = '/' . $selected['filename'] . $path; + $parent_hash = $selected['folder']; + $found = true; + break; + } + } + if (! $found) { + $error = true; + } + } while ((! $found) && (! $error) && ($parent_hash != '')); + } - return (($error) ? false : [ $current_hash , $path ]); + return (($error) ? false : [ $current_hash , $path ]); } /** @@ -2639,61 +2728,65 @@ function attach_folder_rpaths($all_folders,$that_folder) { */ -function attach_syspaths($channel_id,$attach_hash) { +function attach_syspaths($channel_id, $attach_hash) +{ - $os_path = ''; - $path = ''; - do { + $os_path = ''; + $path = ''; + do { + $r = q( + "select folder, filename, hash from attach where hash = '%s' and uid = %d", + dbesc($attach_hash), + intval($channel_id) + ); + if (! $r) { + break; + } - $r = q("select folder, filename, hash from attach where hash = '%s' and uid = %d", - dbesc($attach_hash), - intval($channel_id) - ); - if (! $r) { - break; - } + $os_path = $r[0]['hash'] . (($os_path) ? '/' . $os_path : ''); + $path = $r[0]['filename'] . (($path) ? '/' . $path : ''); + $attach_hash = $r[0]['folder']; + } while ($attach_hash); - $os_path = $r[0]['hash'] . (($os_path) ? '/' . $os_path : ''); - $path = $r[0]['filename'] . (($path) ? '/' . $path : ''); - $attach_hash = $r[0]['folder']; - } while ($attach_hash); - - return [ 'os_path' => $os_path, 'path' => $path ]; + return [ 'os_path' => $os_path, 'path' => $path ]; } /** * in earlier releases we did not fill in os_path and display_path in the attach DB structure. - * (It was not needed or used). Going forward we intend to make use of these fields. + * (It was not needed or used). Going forward we intend to make use of these fields. * A cron task checks for empty values (as older attachments may have arrived at our site - * in a clone operation) and executes attach_syspaths() to generate these field values and correct - * the attach table entry. The operation is limited to 100 DB entries at a time so as not to + * in a clone operation) and executes attach_syspaths() to generate these field values and correct + * the attach table entry. The operation is limited to 100 DB entries at a time so as not to * overload the system in any cron run. Eventually it will catch up with old attach structures * and switch into maintenance mode to correct any that might arrive in clone packets from older * sites. */ -function attach_upgrade() { +function attach_upgrade() +{ - $r = q("select id, uid, hash from attach where os_path = '' and display_path = '' limit 100"); - if ($r) { - foreach ($r as $rv) { - $x = attach_syspaths($rv['uid'],$rv['hash']); - if ($x) { - $w = q("update attach set os_path = '%s', display_path = '%s' where id = %d", - dbesc($x['os_path']), - dbesc($x['path']), - intval($rv['id']) - ); - $y = q("update photo set os_path = '%s', display_path = '%s' where uid = %d and resource_id = '%s'", - dbesc($x['os_path']), - dbesc($x['path']), - intval($rv['uid']), - dbesc($rv['hash']) - ); - } - } - } + $r = q("select id, uid, hash from attach where os_path = '' and display_path = '' limit 100"); + if ($r) { + foreach ($r as $rv) { + $x = attach_syspaths($rv['uid'], $rv['hash']); + if ($x) { + $w = q( + "update attach set os_path = '%s', display_path = '%s' where id = %d", + dbesc($x['os_path']), + dbesc($x['path']), + intval($rv['id']) + ); + $y = q( + "update photo set os_path = '%s', display_path = '%s' where uid = %d and resource_id = '%s'", + dbesc($x['os_path']), + dbesc($x['path']), + intval($rv['uid']), + dbesc($rv['hash']) + ); + } + } + } } @@ -2703,52 +2796,50 @@ function attach_upgrade() { */ -function save_chunk($channel,$start,$end,$len) { +function save_chunk($channel, $start, $end, $len) +{ - $result = []; + $result = []; - $tmp_path = $_FILES['files']['tmp_name']; - $new_base = 'cache/' . $channel['channel_address'] . '/tmp'; + $tmp_path = $_FILES['files']['tmp_name']; + $new_base = 'cache/' . $channel['channel_address'] . '/tmp'; - os_mkdir($new_base,STORAGE_DEFAULT_PERMISSIONS,true); + os_mkdir($new_base, STORAGE_DEFAULT_PERMISSIONS, true); - if (! is_dir($new_base)) { - logger('directory create failed for ' . $new_base); - } + if (! is_dir($new_base)) { + logger('directory create failed for ' . $new_base); + } - $new_path = $new_base . '/' . $_FILES['files']['name'] . '.ftmp'; + $new_path = $new_base . '/' . $_FILES['files']['name'] . '.ftmp'; - if (file_exists($new_path) && intval($start) === 0) { - $result['partial'] = true; - $result['length'] = intval(filesize($new_path)); - return $result; - } + if (file_exists($new_path) && intval($start) === 0) { + $result['partial'] = true; + $result['length'] = intval(filesize($new_path)); + return $result; + } - if (! file_exists($new_path)) { - rename($tmp_path,$new_path); - } - else { - $istream = fopen($tmp_path,'rb'); - $ostream = fopen($new_path,'ab'); - if ($istream && $ostream) { - pipe_streams($istream,$ostream); - fclose($istream); - fclose($ostream); - } - } - if (($len - 1) == $end) { - unlink($tmp_path); - $result['name'] = $_FILES['files']['name']; - $result['type'] = $_FILES['files']['type']; - $result['tmp_name'] = $new_path; - $result['error'] = 0; - $result['size'] = $len; - $result['complete'] = true; - return $result; - } - $result['partial'] = true; - $result['length'] = intval(filesize($new_path)); - return $result; + if (! file_exists($new_path)) { + rename($tmp_path, $new_path); + } else { + $istream = fopen($tmp_path, 'rb'); + $ostream = fopen($new_path, 'ab'); + if ($istream && $ostream) { + pipe_streams($istream, $ostream); + fclose($istream); + fclose($ostream); + } + } + if (($len - 1) == $end) { + unlink($tmp_path); + $result['name'] = $_FILES['files']['name']; + $result['type'] = $_FILES['files']['type']; + $result['tmp_name'] = $new_path; + $result['error'] = 0; + $result['size'] = $len; + $result['complete'] = true; + return $result; + } + $result['partial'] = true; + $result['length'] = intval(filesize($new_path)); + return $result; } - - diff --git a/include/auth.php b/include/auth.php index 49813ada5..36fb9a02d 100644 --- a/include/auth.php +++ b/include/auth.php @@ -1,6 +1,5 @@ null, 'channel' => null, 'xchan' => null ]; - $login = punify($login); + $ret = [ 'account' => null, 'channel' => null, 'xchan' => null ]; + $login = punify($login); - $email_verify = get_config('system', 'verify_email'); - $register_policy = get_config('system', 'register_policy'); + $email_verify = get_config('system', 'verify_email'); + $register_policy = get_config('system', 'register_policy'); - if(! $login) - return null; + if (! $login) { + return null; + } - $account = null; - $channel = null; - $xchan = null; + $account = null; + $channel = null; + $xchan = null; - $addon_auth = [ - 'username' => $login, - 'password' => trim($pass), - 'authenticated' => 0, - 'user_record' => null - ]; + $addon_auth = [ + 'username' => $login, + 'password' => trim($pass), + 'authenticated' => 0, + 'user_record' => null + ]; - /** - * - * A plugin indicates successful login by setting 'authenticated' to non-zero value and returning a user record - * Plugins should never set 'authenticated' except to indicate success - as hooks may be chained - * and later plugins should not interfere with an earlier one that succeeded. - * - */ + /** + * + * A plugin indicates successful login by setting 'authenticated' to non-zero value and returning a user record + * Plugins should never set 'authenticated' except to indicate success - as hooks may be chained + * and later plugins should not interfere with an earlier one that succeeded. + * + */ - call_hooks('authenticate', $addon_auth); + call_hooks('authenticate', $addon_auth); - if(($addon_auth['authenticated']) && is_array($addon_auth['user_record']) && (! empty($addon_auth['user_record']))) { - $ret['account'] = $addon_auth['user_record']; - return $ret; - } - else { - if(! strpos($login,'@')) { - $channel = channelx_by_nick($login); - if(! $channel) { - $x = q("select * from atoken where atoken_name = '%s' and atoken_token = '%s' limit 1", - dbesc($login), - dbesc($pass) - ); - if($x) { - $ret['xchan'] = atoken_xchan($x[0]); - atoken_create_xchan($ret['xchan']); - return $ret; - } - } - } - if($channel) { - $where = " where account_id = " . intval($channel['channel_account_id']) . " "; - } - else { - $where = " where account_email = '" . dbesc($login) . "' "; - } + if (($addon_auth['authenticated']) && is_array($addon_auth['user_record']) && (! empty($addon_auth['user_record']))) { + $ret['account'] = $addon_auth['user_record']; + return $ret; + } else { + if (! strpos($login, '@')) { + $channel = channelx_by_nick($login); + if (! $channel) { + $x = q( + "select * from atoken where atoken_name = '%s' and atoken_token = '%s' limit 1", + dbesc($login), + dbesc($pass) + ); + if ($x) { + $ret['xchan'] = atoken_xchan($x[0]); + atoken_create_xchan($ret['xchan']); + return $ret; + } + } + } + if ($channel) { + $where = " where account_id = " . intval($channel['channel_account_id']) . " "; + } else { + $where = " where account_email = '" . dbesc($login) . "' "; + } - $a = q("select * from account $where"); - if(! $a) { - return null; - } + $a = q("select * from account $where"); + if (! $a) { + return null; + } - $account = $a[0]; + $account = $a[0]; - // Currently we only verify email address if there is an open registration policy. - // This isn't because of any policy - it's because the workflow gets too complicated if - // you have to verify the email and then go through the account approval workflow before - // letting them login. + // Currently we only verify email address if there is an open registration policy. + // This isn't because of any policy - it's because the workflow gets too complicated if + // you have to verify the email and then go through the account approval workflow before + // letting them login. - if(($email_verify) && ($register_policy == REGISTER_OPEN) && ($account['account_flags'] & ACCOUNT_UNVERIFIED)) { - logger('email verification required for ' . $login); - return ( [ 'reason' => 'unvalidated' ] ); - } + if (($email_verify) && ($register_policy == REGISTER_OPEN) && ($account['account_flags'] & ACCOUNT_UNVERIFIED)) { + logger('email verification required for ' . $login); + return ( [ 'reason' => 'unvalidated' ] ); + } - if($channel) { - // Try the authentication plugin again since weve determined we are using the channel login instead of account login - $addon_auth = [ - 'username' => $account['account_email'], - 'password' => trim($pass), - 'authenticated' => 0, - 'user_record' => null - ]; + if ($channel) { + // Try the authentication plugin again since weve determined we are using the channel login instead of account login + $addon_auth = [ + 'username' => $account['account_email'], + 'password' => trim($pass), + 'authenticated' => 0, + 'user_record' => null + ]; - call_hooks('authenticate', $addon_auth); + call_hooks('authenticate', $addon_auth); - if(($addon_auth['authenticated']) && is_array($addon_auth['user_record']) && (! empty($addon_auth['user_record']))) { - $ret['account'] = $addon_auth['user_record']; - return $ret; - } - } + if (($addon_auth['authenticated']) && is_array($addon_auth['user_record']) && (! empty($addon_auth['user_record']))) { + $ret['account'] = $addon_auth['user_record']; + return $ret; + } + } - if(($account['account_flags'] == ACCOUNT_OK) - && (hash('whirlpool',$account['account_salt'] . $pass) === $account['account_password'])) { - logger('password verified for ' . $login); - $ret['account'] = $account; - if($channel) - $ret['channel'] = $channel; - return $ret; - } - } + if ( + ($account['account_flags'] == ACCOUNT_OK) + && (hash('whirlpool', $account['account_salt'] . $pass) === $account['account_password']) + ) { + logger('password verified for ' . $login); + $ret['account'] = $account; + if ($channel) { + $ret['channel'] = $channel; + } + return $ret; + } + } - $error = 'password failed for ' . $login; - logger($error); + $error = 'password failed for ' . $login; + logger($error); - if($account['account_flags'] & ACCOUNT_UNVERIFIED) - logger('Account is unverified. account_flags = ' . $account['account_flags']); - if($account['account_flags'] & ACCOUNT_BLOCKED) - logger('Account is blocked. account_flags = ' . $account['account_flags']); - if($account['account_flags'] & ACCOUNT_EXPIRED) - logger('Account is expired. account_flags = ' . $account['account_flags']); - if($account['account_flags'] & ACCOUNT_REMOVED) - logger('Account is removed. account_flags = ' . $account['account_flags']); - if($account['account_flags'] & ACCOUNT_PENDING) - logger('Account is pending. account_flags = ' . $account['account_flags']); + if ($account['account_flags'] & ACCOUNT_UNVERIFIED) { + logger('Account is unverified. account_flags = ' . $account['account_flags']); + } + if ($account['account_flags'] & ACCOUNT_BLOCKED) { + logger('Account is blocked. account_flags = ' . $account['account_flags']); + } + if ($account['account_flags'] & ACCOUNT_EXPIRED) { + logger('Account is expired. account_flags = ' . $account['account_flags']); + } + if ($account['account_flags'] & ACCOUNT_REMOVED) { + logger('Account is removed. account_flags = ' . $account['account_flags']); + } + if ($account['account_flags'] & ACCOUNT_PENDING) { + logger('Account is pending. account_flags = ' . $account['account_flags']); + } - log_failed_login($error); + log_failed_login($error); - return null; + return null; } /** @@ -168,10 +176,12 @@ function account_verify_password($login, $pass) { * @param string $errormsg * Error message to display for failed login. */ -function log_failed_login($errormsg) { - $authlog = get_config('system', 'authlog'); - if ($authlog) - @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $errormsg . PHP_EOL, FILE_APPEND); +function log_failed_login($errormsg) +{ + $authlog = get_config('system', 'authlog'); + if ($authlog) { + @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $errormsg . PHP_EOL, FILE_APPEND); + } } /** @@ -180,178 +190,174 @@ function log_failed_login($errormsg) { * also handles logout */ -if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && - ((! (x($_POST, 'auth-params'))) || ($_POST['auth-params'] !== 'login'))) { +if ( + (isset($_SESSION)) && (x($_SESSION, 'authenticated')) && + ((! (x($_POST, 'auth-params'))) || ($_POST['auth-params'] !== 'login')) +) { + // process a logout request - // process a logout request - - if(((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || (App::$module === 'logout')) { - // process logout request - $args = array('channel_id' => local_channel()); - call_hooks('logging_out', $args); + if (((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || (App::$module === 'logout')) { + // process logout request + $args = array('channel_id' => local_channel()); + call_hooks('logging_out', $args); - if($_SESSION['delegate'] && $_SESSION['delegate_push']) { - $_SESSION = $_SESSION['delegate_push']; - info( t('Delegation session ended.') . EOL); - } - else { - App::$session->nuke(); - info( t('Logged out.') . EOL); - } + if ($_SESSION['delegate'] && $_SESSION['delegate_push']) { + $_SESSION = $_SESSION['delegate_push']; + info(t('Delegation session ended.') . EOL); + } else { + App::$session->nuke(); + info(t('Logged out.') . EOL); + } - goaway(z_root()); - } + goaway(z_root()); + } - // re-validate a visitor, optionally invoke "su" if permitted to do so + // re-validate a visitor, optionally invoke "su" if permitted to do so - if(x($_SESSION, 'visitor_id') && (! x($_SESSION, 'uid'))) { - // if our authenticated guest is allowed to take control of the admin channel, make it so. - $admins = get_config('system', 'remote_admin'); - if($admins && is_array($admins) && in_array($_SESSION['visitor_id'], $admins)) { - $x = q("select * from account where account_email = '%s' and account_email != '' and ( account_flags & %d ) > 0 limit 1", - dbesc(get_config('system', 'admin_email')), - intval(ACCOUNT_ROLE_ADMIN) - ); - if($x) { - App::$session->new_cookie(60 * 60 * 24); // one day - $_SESSION['last_login_date'] = datetime_convert(); - unset($_SESSION['visitor_id']); // no longer a visitor - authenticate_success($x[0], null, true, true); - } - } - if(array_key_exists('atoken',$_SESSION)) { - $y = q("select * from atoken where atoken_id = %d limit 1", - intval($_SESSION['atoken']) - ); - if($y) - $r = array(atoken_xchan($y[0])); - } - else { - $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' ", - dbesc($_SESSION['visitor_id']) - ); - } - if($r) { - $r = Libzot::zot_record_preferred($r); - App::set_observer($r); - } - else { - unset($_SESSION['visitor_id']); - unset($_SESSION['authenticated']); - } - App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); - } + if (x($_SESSION, 'visitor_id') && (! x($_SESSION, 'uid'))) { + // if our authenticated guest is allowed to take control of the admin channel, make it so. + $admins = get_config('system', 'remote_admin'); + if ($admins && is_array($admins) && in_array($_SESSION['visitor_id'], $admins)) { + $x = q( + "select * from account where account_email = '%s' and account_email != '' and ( account_flags & %d ) > 0 limit 1", + dbesc(get_config('system', 'admin_email')), + intval(ACCOUNT_ROLE_ADMIN) + ); + if ($x) { + App::$session->new_cookie(60 * 60 * 24); // one day + $_SESSION['last_login_date'] = datetime_convert(); + unset($_SESSION['visitor_id']); // no longer a visitor + authenticate_success($x[0], null, true, true); + } + } + if (array_key_exists('atoken', $_SESSION)) { + $y = q( + "select * from atoken where atoken_id = %d limit 1", + intval($_SESSION['atoken']) + ); + if ($y) { + $r = array(atoken_xchan($y[0])); + } + } else { + $r = q( + "select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' ", + dbesc($_SESSION['visitor_id']) + ); + } + if ($r) { + $r = Libzot::zot_record_preferred($r); + App::set_observer($r); + } else { + unset($_SESSION['visitor_id']); + unset($_SESSION['authenticated']); + } + App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); + } - // already logged in user returning + // already logged in user returning - if(x($_SESSION, 'uid') || x($_SESSION, 'account_id')) { + if (x($_SESSION, 'uid') || x($_SESSION, 'account_id')) { + App::$session->return_check(); - App::$session->return_check(); + $r = q( + "select * from account where account_id = %d limit 1", + intval($_SESSION['account_id']) + ); - $r = q("select * from account where account_id = %d limit 1", - intval($_SESSION['account_id']) - ); + if (($r) && (($r[0]['account_flags'] == ACCOUNT_OK) || ($r[0]['account_flags'] == ACCOUNT_UNVERIFIED))) { + App::$account = $r[0]; + $login_refresh = false; + if (! x($_SESSION, 'last_login_date')) { + $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC'); + } + if (strcmp(datetime_convert('UTC', 'UTC', 'now - 12 hours'), $_SESSION['last_login_date']) > 0) { + $_SESSION['last_login_date'] = datetime_convert(); + App::$session->extend_cookie(); + $login_refresh = true; + } + $ch = (($_SESSION['uid']) ? channelx_by_n($_SESSION['uid']) : null); + authenticate_success($r[0], null, $ch, false, false, $login_refresh); + } else { + $_SESSION['account_id'] = 0; + App::$session->nuke(); + goaway(z_root()); + } + } // end logged in user returning +} else { + if (isset($_SESSION)) { + App::$session->nuke(); + } - if(($r) && (($r[0]['account_flags'] == ACCOUNT_OK) || ($r[0]['account_flags'] == ACCOUNT_UNVERIFIED))) { - App::$account = $r[0]; - $login_refresh = false; - if(! x($_SESSION,'last_login_date')) { - $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); - } - if(strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0 ) { - $_SESSION['last_login_date'] = datetime_convert(); - App::$session->extend_cookie(); - $login_refresh = true; - } - $ch = (($_SESSION['uid']) ? channelx_by_n($_SESSION['uid']) : null); - authenticate_success($r[0], null, $ch, false, false, $login_refresh); - } - else { - $_SESSION['account_id'] = 0; - App::$session->nuke(); - goaway(z_root()); - } - } // end logged in user returning -} -else { + // handle a fresh login request - if(isset($_SESSION)) { - App::$session->nuke(); - } + if ((x($_POST, 'password')) && strlen($_POST['password'])) { + $encrypted = hash('whirlpool', trim($_POST['password'])); + } - // handle a fresh login request + if ((x($_POST, 'auth-params')) && $_POST['auth-params'] === 'login') { + $atoken = null; + $account = null; + $channel = null; - if((x($_POST, 'password')) && strlen($_POST['password'])) - $encrypted = hash('whirlpool', trim($_POST['password'])); + $verify = account_verify_password($_POST['username'], $_POST['password']); + if ($verify && array_key_exists('reason', $verify) && $verify['reason'] === 'unvalidated') { + notice(t('Email validation is incomplete. Please check your email.')); + goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($_POST['username']))))); + } elseif ($verify) { + $atoken = $verify['xchan']; + $channel = $verify['channel']; + $account = App::$account = $verify['account']; + } - if((x($_POST, 'auth-params')) && $_POST['auth-params'] === 'login') { + if (App::$account) { + $_SESSION['account_id'] = App::$account['account_id']; + } elseif ($atoken) { + atoken_login($atoken); + } else { + notice(t('Failed authentication') . EOL); + } - $atoken = null; - $account = null; - $channel = null; + if (! ($account || $atoken)) { + $error = 'authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']; + logger($error); + // Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention + $authlog = get_config('system', 'authlog'); + if ($authlog) { + @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $error . "\n", FILE_APPEND); + } + notice(t('Login failed.') . EOL); + goaway(z_root() . '/login'); + } - $verify = account_verify_password($_POST['username'], $_POST['password']); - if($verify && array_key_exists('reason',$verify) && $verify['reason'] === 'unvalidated') { - notice( t('Email validation is incomplete. Please check your email.')); - goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($_POST['username']))))); - } - elseif($verify) { - $atoken = $verify['xchan']; - $channel = $verify['channel']; - $account = App::$account = $verify['account']; - } + // If the user specified to remember the authentication, then change the cookie + // to expire after one year (the default is when the browser is closed). + // If the user did not specify to remember, change the cookie to expire when the + // browser is closed. The reason this is necessary is because if the user + // specifies to remember, then logs out and logs back in without specifying to + // remember, the old "remember" cookie may remain and prevent the session from + // expiring when the browser is closed. + // + // It seems like I should be able to test for the old cookie, but for some reason when + // I read the lifetime value from session_get_cookie_params(), I always get '0' + // (i.e. expire when the browser is closed), even when there's a time expiration + // on the cookie - if(App::$account) { - $_SESSION['account_id'] = App::$account['account_id']; - } - elseif($atoken) { - atoken_login($atoken); - } - else { - notice( t('Failed authentication') . EOL); - } + if (($_POST['remember_me']) || ($_POST['remember'])) { + $_SESSION['remember_me'] = 1; + App::$session->new_cookie(31449600); // one year + } else { + $_SESSION['remember_me'] = 0; + App::$session->new_cookie(0); // 0 means delete on browser exit + } - if(! ($account || $atoken)) { - $error = 'authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']; - logger($error); - // Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention - $authlog = get_config('system', 'authlog'); - if ($authlog) - @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $error . "\n", FILE_APPEND); - notice( t('Login failed.') . EOL ); - goaway(z_root() . '/login'); - } + // if we haven't failed up this point, log them in. - // If the user specified to remember the authentication, then change the cookie - // to expire after one year (the default is when the browser is closed). - // If the user did not specify to remember, change the cookie to expire when the - // browser is closed. The reason this is necessary is because if the user - // specifies to remember, then logs out and logs back in without specifying to - // remember, the old "remember" cookie may remain and prevent the session from - // expiring when the browser is closed. - // - // It seems like I should be able to test for the old cookie, but for some reason when - // I read the lifetime value from session_get_cookie_params(), I always get '0' - // (i.e. expire when the browser is closed), even when there's a time expiration - // on the cookie - - if(($_POST['remember_me']) || ($_POST['remember'])) { - $_SESSION['remember_me'] = 1; - App::$session->new_cookie(31449600); // one year - } - else { - $_SESSION['remember_me'] = 0; - App::$session->new_cookie(0); // 0 means delete on browser exit - } - - // if we haven't failed up this point, log them in. - - $_SESSION['last_login_date'] = datetime_convert(); - if(! $atoken) { - authenticate_success($account,$channel,true, true); - } - } + $_SESSION['last_login_date'] = datetime_convert(); + if (! $atoken) { + authenticate_success($account, $channel, true, true); + } + } } @@ -362,19 +368,22 @@ else { * and returns the corresponding channel_id. * * @fixme How do we prevent that an OpenID identity is used more than once? - * + * * @param string $authid * The given openid_identity * @return int|bool * Return channel_id from pconfig or false. */ -function match_openid($authid) { - // Query the uid/channel_id from pconfig for a given value. - $r = q("SELECT uid FROM pconfig WHERE cat = 'system' AND k = 'openid' AND v = '%s' LIMIT 1", - dbesc($authid) - ); - if($r) - return $r[0]['uid']; - return false; +function match_openid($authid) +{ + // Query the uid/channel_id from pconfig for a given value. + $r = q( + "SELECT uid FROM pconfig WHERE cat = 'system' AND k = 'openid' AND v = '%s' LIMIT 1", + dbesc($authid) + ); + if ($r) { + return $r[0]['uid']; + } + return false; } diff --git a/include/bbcode.php b/include/bbcode.php index 7d6d0b35b..0a8390f2c 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -14,136 +14,157 @@ require_once('include/oembed.php'); require_once('include/event.php'); require_once('include/html2plain.php'); -function get_bb_tag_pos($s, $name, $occurance = 1) { +function get_bb_tag_pos($s, $name, $occurance = 1) +{ - if($occurance < 1) - $occurance = 1; + if ($occurance < 1) { + $occurance = 1; + } - $start_open = -1; - for($i = 1; $i <= $occurance; $i++) { - if( $start_open !== false) - $start_open = strpos($s, '[' . $name, $start_open + 1); // allow [name= type tags - } + $start_open = -1; + for ($i = 1; $i <= $occurance; $i++) { + if ($start_open !== false) { + $start_open = strpos($s, '[' . $name, $start_open + 1); // allow [name= type tags + } + } - if( $start_open === false) - return false; + if ($start_open === false) { + return false; + } - $start_equal = strpos($s, '=', $start_open); - $start_close = strpos($s, ']', $start_open); + $start_equal = strpos($s, '=', $start_open); + $start_close = strpos($s, ']', $start_open); - if( $start_close === false) - return false; + if ($start_close === false) { + return false; + } - $start_close++; + $start_close++; - $end_open = strpos($s, '[/' . $name . ']', $start_close); + $end_open = strpos($s, '[/' . $name . ']', $start_close); - if( $end_open === false) - return false; + if ($end_open === false) { + return false; + } - $res = array( 'start' => array('open' => $start_open, 'close' => $start_close), - 'end' => array('open' => $end_open, 'close' => $end_open + strlen('[/' . $name . ']')) ); - if( $start_equal !== false) - $res['start']['equal'] = $start_equal + 1; + $res = array( 'start' => array('open' => $start_open, 'close' => $start_close), + 'end' => array('open' => $end_open, 'close' => $end_open + strlen('[/' . $name . ']')) ); + if ($start_equal !== false) { + $res['start']['equal'] = $start_equal + 1; + } - return $res; + return $res; } -function bb_tag_preg_replace($pattern, $replace, $name, $s) { +function bb_tag_preg_replace($pattern, $replace, $name, $s) +{ - $string = $s; + $string = $s; - $occurance = 1; - $pos = get_bb_tag_pos($string, $name, $occurance); - while($pos !== false && $occurance < 1000) { + $occurance = 1; + $pos = get_bb_tag_pos($string, $name, $occurance); + while ($pos !== false && $occurance < 1000) { + $start = substr($string, 0, $pos['start']['open']); + $subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']); + $end = substr($string, $pos['end']['close']); + if ($end === false) { + $end = ''; + } - $start = substr($string, 0, $pos['start']['open']); - $subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']); - $end = substr($string, $pos['end']['close']); - if($end === false) - $end = ''; + $subject = preg_replace($pattern, $replace, $subject); + $string = $start . $subject . $end; - $subject = preg_replace($pattern, $replace, $subject); - $string = $start . $subject . $end; + $occurance++; + $pos = get_bb_tag_pos($string, $name, $occurance); + } - $occurance++; - $pos = get_bb_tag_pos($string, $name, $occurance); - } - - return $string; + return $string; } -function tryoembed($match) { - $url = ((count($match) == 2) ? $match[1] : $match[2]); +function tryoembed($match) +{ + $url = ((count($match) == 2) ? $match[1] : $match[2]); - $o = oembed_fetch_url($url); + $o = oembed_fetch_url($url); - if ($o['type'] == 'error') - return $match[0]; + if ($o['type'] == 'error') { + return $match[0]; + } - $html = oembed_format_object($o); - return $html; + $html = oembed_format_object($o); + return $html; } -function nakedoembed($match) { - $url = ((count($match) == 2) ? $match[1] : $match[2]); +function nakedoembed($match) +{ + $url = ((count($match) == 2) ? $match[1] : $match[2]); - $strip_url = strip_escaped_zids($url); + $strip_url = strip_escaped_zids($url); - // this function no longer performs oembed on naked links - // because they author may have created naked links intentionally. - // Now it just strips zids on naked links. - - return str_replace($url,$strip_url,$match[0]); + // this function no longer performs oembed on naked links + // because they author may have created naked links intentionally. + // Now it just strips zids on naked links. + + return str_replace($url, $strip_url, $match[0]); } -function tryzrlaudio($match) { - $link = $match[1]; - $zrl = is_matrix_url($link); - if($zrl) - $link = zid($link); +function tryzrlaudio($match) +{ + $link = $match[1]; + $zrl = is_matrix_url($link); + if ($zrl) { + $link = zid($link); + } - return ''; + return ''; } -function tryzrlvideo($match) { - $link = $match[1]; - $zrl = is_matrix_url($link); - if($zrl) - $link = zid($link); +function tryzrlvideo($match) +{ + $link = $match[1]; + $zrl = is_matrix_url($link); + if ($zrl) { + $link = zid($link); + } - $static_link = get_config('system','video_default_poster','images/video_poster.jpg'); - if($static_link) - $poster = 'poster="' . escape_tags($static_link) . '" ' ; + $static_link = get_config('system', 'video_default_poster', 'images/video_poster.jpg'); + if ($static_link) { + $poster = 'poster="' . escape_tags($static_link) . '" ' ; + } - return ''; + return ''; } -function videowithopts($match) { - $link = $match[2]; - $zrl = is_matrix_url($link); - if($zrl) - $link = zid($link); +function videowithopts($match) +{ + $link = $match[2]; + $zrl = is_matrix_url($link); + if ($zrl) { + $link = zid($link); + } - $attributes = $match[1]; + $attributes = $match[1]; - $poster = ""; + $poster = ""; - preg_match("/poster='(.*?)'/ism", $attributes, $matches); - if (isset($matches[1]) && $matches[1] != "") - $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + preg_match("/poster='(.*?)'/ism", $attributes, $matches); + if (isset($matches[1]) && $matches[1] != "") { + $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + } - preg_match("/poster=\"\;(.*?)\"\;/ism", $attributes, $matches); - if (isset($matches[1]) && $matches[1] != "") - $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + preg_match("/poster=\"\;(.*?)\"\;/ism", $attributes, $matches); + if (isset($matches[1]) && $matches[1] != "") { + $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + } - preg_match("/poster=\\\"(.*?)\\\"/ism", $attributes, $matches); - if (isset($matches[1]) && $matches[1] != "") - $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + preg_match("/poster=\\\"(.*?)\\\"/ism", $attributes, $matches); + if (isset($matches[1]) && $matches[1] != "") { + $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; + } - return ''; + return ''; } @@ -153,87 +174,92 @@ function videowithopts($match) { // [noparse][ i ]italic[ /i ][/noparse], // to hide them from parser. -function bb_spacefy($st) { - $whole_match = $st[0]; - $captured = $st[1]; - $spacefied = preg_replace("/\[(.*?)\]/", "[ $1 ]", $captured); - $new_str = str_replace($captured, $spacefied, $whole_match); +function bb_spacefy($st) +{ + $whole_match = $st[0]; + $captured = $st[1]; + $spacefied = preg_replace("/\[(.*?)\]/", "[ $1 ]", $captured); + $new_str = str_replace($captured, $spacefied, $whole_match); - return $new_str; + return $new_str; } // The previously spacefied [noparse][ i ]italic[ /i ][/noparse], // now turns back and the [noparse] tags are trimmed // returning [i]italic[/i] -function bb_unspacefy_and_trim($st) { - //$whole_match = $st[0]; - $captured = $st[1]; - $unspacefied = preg_replace("/\[ (.*?)\ ]/", "[$1]", $captured); +function bb_unspacefy_and_trim($st) +{ + //$whole_match = $st[0]; + $captured = $st[1]; + $unspacefied = preg_replace("/\[ (.*?)\ ]/", "[$1]", $captured); - return $unspacefied; + return $unspacefied; } -function bb_extract_images($body) { +function bb_extract_images($body) +{ - $saved_image = []; - $orig_body = $body; - $new_body = ''; + $saved_image = []; + $orig_body = $body; + $new_body = ''; - $cnt = 0; - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - while(($img_st_close !== false) && ($img_end !== false)) { + $cnt = 0; + $img_start = strpos($orig_body, '[img'); + $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); + $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); + while (($img_st_close !== false) && ($img_end !== false)) { + $img_st_close++; // make it point to AFTER the closing bracket + $img_end += $img_start; - $img_st_close++; // make it point to AFTER the closing bracket - $img_end += $img_start; + if (! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { + // This is an embedded image - if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { - // This is an embedded image + $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close)); + $new_body = $new_body . substr($orig_body, 0, $img_start) . '[$#saved_image' . $cnt . '#$]'; - $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close)); - $new_body = $new_body . substr($orig_body, 0, $img_start) . '[$#saved_image' . $cnt . '#$]'; + $cnt++; + } else { + $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]')); + } - $cnt++; - } - else - $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]')); + $orig_body = substr($orig_body, $img_end + strlen('[/img]')); - $orig_body = substr($orig_body, $img_end + strlen('[/img]')); + if ($orig_body === false) { // in case the body ends on a closing image tag + $orig_body = ''; + } - if($orig_body === false) // in case the body ends on a closing image tag - $orig_body = ''; + $img_start = strpos($orig_body, '[img'); + $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); + $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); + } - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - } + $new_body = $new_body . $orig_body; - $new_body = $new_body . $orig_body; - - return array('body' => $new_body, 'images' => $saved_image); + return array('body' => $new_body, 'images' => $saved_image); } -function bb_replace_images($body, $images) { +function bb_replace_images($body, $images) +{ - $newbody = $body; - $cnt = 0; + $newbody = $body; + $cnt = 0; - if(! $images) - return $newbody; + if (! $images) { + return $newbody; + } - foreach($images as $image) { - // We're depending on the property of 'foreach' (specified on the PHP website) that - // it loops over the array starting from the first element and going sequentially - // to the last element - $newbody = str_replace('[$#saved_image' . $cnt . '#$]', '' . t('Image/photo') . '', $newbody); - $cnt++; - } -// logger('replace_images: ' . $newbody); - return $newbody; + foreach ($images as $image) { + // We're depending on the property of 'foreach' (specified on the PHP website) that + // it loops over the array starting from the first element and going sequentially + // to the last element + $newbody = str_replace('[$#saved_image' . $cnt . '#$]', '' . t('Image/photo') . '', $newbody); + $cnt++; + } +// logger('replace_images: ' . $newbody); + return $newbody; } /** @@ -243,48 +269,55 @@ function bb_replace_images($body, $images) { * @return string HTML code */ -function bb_parse_crypt($match) { +function bb_parse_crypt($match) +{ - $matches = []; - $attributes = $match[1]; + $matches = []; + $attributes = $match[1]; - $algorithm = ""; + $algorithm = ""; - preg_match("/alg='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $algorithm = $matches[1]; + preg_match("/alg='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $algorithm = $matches[1]; + } - preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($matches[1] != "") - $algorithm = $matches[1]; + preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($matches[1] != "") { + $algorithm = $matches[1]; + } - preg_match("/alg=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($matches[1] != "") - $algorithm = $matches[1]; + preg_match("/alg=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($matches[1] != "") { + $algorithm = $matches[1]; + } - $hint = ""; - $matches = []; - - preg_match("/hint='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $hint = $matches[1]; - preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($matches[1] != "") - $hint = $matches[1]; - preg_match("/hint=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($matches[1] != "") - $hint = $matches[1]; + $hint = ""; + $matches = []; - $x = random_string(); + preg_match("/hint='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $hint = $matches[1]; + } + preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($matches[1] != "") { + $hint = $matches[1]; + } + preg_match("/hint=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($matches[1] != "") { + $hint = $matches[1]; + } - $f = 'hz_decrypt'; + $x = random_string(); - $onclick = 'onclick="' . $f . '(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $match[2] . '\',\'#' . $x . '\');"'; - $label = t('Encrypted content'); + $f = 'hz_decrypt'; - $Text = '
' . $label . '


' . bb_parse_b64_crypt($match); + $onclick = 'onclick="' . $f . '(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $match[2] . '\',\'#' . $x . '\');"'; + $label = t('Encrypted content'); - return $Text; + $Text = '
' . $label . '


' . bb_parse_b64_crypt($match); + + return $Text; } /** @@ -293,357 +326,376 @@ function bb_parse_crypt($match) { * @param array $match * @return string */ -function bb_parse_b64_crypt($match) { +function bb_parse_b64_crypt($match) +{ - if(empty($match[2])) - return; + if (empty($match[2])) { + return; + } - $r .= '----- ENCRYPTED CONTENT -----' . "\n"; - $r .= base64_encode($match[1]) . "." . $match[2] . "\n"; - $r .= '----- END ENCRYPTED CONTENT -----' . "\n"; + $r .= '----- ENCRYPTED CONTENT -----' . "\n"; + $r .= base64_encode($match[1]) . "." . $match[2] . "\n"; + $r .= '----- END ENCRYPTED CONTENT -----' . "\n"; - $r = '' . str_replace("\n",'
',wordwrap($r,75,"\n",true)) . '
'; - - return $r; + $r = '' . str_replace("\n", '
', wordwrap($r, 75, "\n", true)) . '
'; + return $r; } -function bb_parse_app($match) { +function bb_parse_app($match) +{ - $app = Apps::app_decode($match[1]); - if ($app) { - return Apps::app_render($app); - } + $app = Apps::app_decode($match[1]); + if ($app) { + return Apps::app_render($app); + } } -function bb_parse_app_ap($match) { +function bb_parse_app_ap($match) +{ - $app = Apps::app_decode($match[1]); - if ($app) { - return sprintf( t('(Embedded app \'%s\' could not be displayed).'), $app['name']); - } + $app = Apps::app_decode($match[1]); + if ($app) { + return sprintf(t('(Embedded app \'%s\' could not be displayed).'), $app['name']); + } } -function bb_svg($match) { +function bb_svg($match) +{ - $params = str_replace(['
', '"'], [ '', '"'],$match[1]); - $Text = str_replace([ '[',']' ], [ '<','>' ], $match[2]); - - $output = '' . str_replace(['
', '"', ' '], [ '', '"', ' '],$Text) . ''; + $params = str_replace(['
', '"'], [ '', '"'], $match[1]); + $Text = str_replace([ '[',']' ], [ '<','>' ], $match[2]); - $purify = new SvgSanitizer(); - $purify->loadXML($output); - $purify->sanitize(); - $output = $purify->saveSVG(); - $output = preg_replace("/\<\?xml(.*?)\?\>/",'',$output); - return $output; + $output = '' . str_replace(['
', '"', ' '], [ '', '"', ' '], $Text) . ''; + + $purify = new SvgSanitizer(); + $purify->loadXML($output); + $purify->sanitize(); + $output = $purify->saveSVG(); + $output = preg_replace("/\<\?xml(.*?)\?\>/", '', $output); + return $output; } -function bb_svg_export($match) { +function bb_svg_export($match) +{ - $params = str_replace(['
', '"'], [ '', '"'],$match[1]); - $Text = str_replace([ '[',']' ], [ '<','>' ], $match[2]); - - $output = '' . str_replace(['
', '"', ' '], [ '', '"', ' '],$Text) . ''; + $params = str_replace(['
', '"'], [ '', '"'], $match[1]); + $Text = str_replace([ '[',']' ], [ '<','>' ], $match[2]); - $purify = new SvgSanitizer(); - $purify->loadXML($output); - $purify->sanitize(); - $output = $purify->saveSVG(); - $output = preg_replace("/\<\?xml(.*?)\?\>/",'',$output); - $output = 'svg'; - return $output; + $output = '' . str_replace(['
', '"', ' '], [ '', '"', ' '], $Text) . ''; + + $purify = new SvgSanitizer(); + $purify->loadXML($output); + $purify->sanitize(); + $output = $purify->saveSVG(); + $output = preg_replace("/\<\?xml(.*?)\?\>/", '', $output); + $output = 'svg'; + return $output; } -function bb_parse_element($match) { - $j = json_decode(base64url_decode($match[1]),true); +function bb_parse_element($match) +{ + $j = json_decode(base64url_decode($match[1]), true); - if ($j && local_channel()) { - $text = sprintf( t('Install %1$s element %2$s'), translate_design_element($j['type']), $j['pagetitle']); - $o = EOL . '' . EOL; - } - else { - $text = sprintf( t('This post contains an installable %s element, however you lack permissions to install it on this site.' ), translate_design_element($j['type'])) . $j['pagetitle']; - $o = EOL . $text . EOL; - } + if ($j && local_channel()) { + $text = sprintf(t('Install %1$s element %2$s'), translate_design_element($j['type']), $j['pagetitle']); + $o = EOL . '' . EOL; + } else { + $text = sprintf(t('This post contains an installable %s element, however you lack permissions to install it on this site.'), translate_design_element($j['type'])) . $j['pagetitle']; + $o = EOL . $text . EOL; + } - return $o; + return $o; } -function translate_design_element($type) { - switch($type) { - case 'webpage': - $ret = t('webpage'); - break; - case 'layout': - $ret = t('layout'); - break; - case 'block': - $ret = t('block'); - break; - case 'menu': - $ret = t('menu'); - break; - } +function translate_design_element($type) +{ + switch ($type) { + case 'webpage': + $ret = t('webpage'); + break; + case 'layout': + $ret = t('layout'); + break; + case 'block': + $ret = t('block'); + break; + case 'menu': + $ret = t('menu'); + break; + } - return $ret; + return $ret; } -function bb_format_attachdata($body) { +function bb_format_attachdata($body) +{ - $data = getAttachmentData($body); - - - if($data) { - $txt = ''; - if($data['url'] && $data['title']) { - $txt .= "\n\n" . '[url=' . $data['url'] . ']' . $data['title'] . '[/url]'; - } - else { - if($data['url']) { - $txt .= "\n\n" . $data['url']; - } - if($data['title']) { - $txt .= "\n\n" . $data['title']; - } - } - if($data['preview']) { - $txt .= "\n\n" . '[img]' . $data['preview'] . '[/img]'; - } - if($data['image']) { - $txt .= "\n\n" . '[img]' . $data['image'] . '[/img]'; - } + $data = getAttachmentData($body); - $txt .= "\n\n" . $data['text']; - return preg_replace('/\[attachment(.*?)\](.*?)\[\/attachment\]/ism',$txt,$body); - } - return $body; + if ($data) { + $txt = ''; + if ($data['url'] && $data['title']) { + $txt .= "\n\n" . '[url=' . $data['url'] . ']' . $data['title'] . '[/url]'; + } else { + if ($data['url']) { + $txt .= "\n\n" . $data['url']; + } + if ($data['title']) { + $txt .= "\n\n" . $data['title']; + } + } + if ($data['preview']) { + $txt .= "\n\n" . '[img]' . $data['preview'] . '[/img]'; + } + if ($data['image']) { + $txt .= "\n\n" . '[img]' . $data['image'] . '[/img]'; + } + + + $txt .= "\n\n" . $data['text']; + return preg_replace('/\[attachment(.*?)\](.*?)\[\/attachment\]/ism', $txt, $body); + } + return $body; } -function getAttachmentData($body) { - $data = []; +function getAttachmentData($body) +{ + $data = []; - if (! preg_match("/\[attachment(.*?)\](.*?)\[\/attachment\]/ism", $body, $match)) { - return null; - } + if (! preg_match("/\[attachment(.*?)\](.*?)\[\/attachment\]/ism", $body, $match)) { + return null; + } - $attributes = $match[1]; + $attributes = $match[1]; - $data["text"] = trim($match[2]); + $data["text"] = trim($match[2]); - $type = ""; - preg_match("/type='(.*?)'/ism", $attributes, $matches); + $type = ""; + preg_match("/type='(.*?)'/ism", $attributes, $matches); - if (x($matches, 1)) { - $type = strtolower($matches[1]); - } + if (x($matches, 1)) { + $type = strtolower($matches[1]); + } - preg_match('/type=\"\;(.*?)\"\;/ism', $attributes, $matches); - if (x($matches, 1)) { - $type = strtolower($matches[1]); - } + preg_match('/type=\"\;(.*?)\"\;/ism', $attributes, $matches); + if (x($matches, 1)) { + $type = strtolower($matches[1]); + } - preg_match('/type=\\\"(.*?)\\\"/ism', $attributes, $matches); - if (x($matches, 1)) { - $type = strtolower($matches[1]); - } + preg_match('/type=\\\"(.*?)\\\"/ism', $attributes, $matches); + if (x($matches, 1)) { + $type = strtolower($matches[1]); + } - if ($type == "") { - return []; - } + if ($type == "") { + return []; + } - if (!in_array($type, ["link", "audio", "photo", "video"])) { - return []; - } + if (!in_array($type, ["link", "audio", "photo", "video"])) { + return []; + } - if ($type != "") { - $data["type"] = $type; - } - $url = ""; - preg_match("/url='(.*?)'/ism", $attributes, $matches); - if (x($matches, 1)) { - $url = $matches[1]; - } + if ($type != "") { + $data["type"] = $type; + } + $url = ""; + preg_match("/url='(.*?)'/ism", $attributes, $matches); + if (x($matches, 1)) { + $url = $matches[1]; + } - preg_match('/url=\"\;(.*?)\"\;/ism', $attributes, $matches); - if (x($matches, 1)) { - $url = $matches[1]; - } + preg_match('/url=\"\;(.*?)\"\;/ism', $attributes, $matches); + if (x($matches, 1)) { + $url = $matches[1]; + } - preg_match('/url=\\\"(.*?)\\\"/ism', $attributes, $matches); - if (x($matches, 1)) { - $url = $matches[1]; - } + preg_match('/url=\\\"(.*?)\\\"/ism', $attributes, $matches); + if (x($matches, 1)) { + $url = $matches[1]; + } - if ($url != "") { - $data["url"] = html_entity_decode($url, ENT_QUOTES, 'UTF-8'); - } + if ($url != "") { + $data["url"] = html_entity_decode($url, ENT_QUOTES, 'UTF-8'); + } - $title = ""; - preg_match("/title='(.*?)'/ism", $attributes, $matches); - if (x($matches, 1)) { - $title = $matches[1]; - } + $title = ""; + preg_match("/title='(.*?)'/ism", $attributes, $matches); + if (x($matches, 1)) { + $title = $matches[1]; + } - preg_match('/title=\"\;(.*?)\"\;/ism', $attributes, $matches); - if (x($matches, 1)) { - $title = $matches[1]; - } + preg_match('/title=\"\;(.*?)\"\;/ism', $attributes, $matches); + if (x($matches, 1)) { + $title = $matches[1]; + } - preg_match('/title=\\\"(.*?)\\\"/ism', $attributes, $matches); - if (x($matches, 1)) { - $title = $matches[1]; - } + preg_match('/title=\\\"(.*?)\\\"/ism', $attributes, $matches); + if (x($matches, 1)) { + $title = $matches[1]; + } - if ($title != "") { - $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); - $title = str_replace(["[", "]"], ["[", "]"], $title); - $data["title"] = $title; - } + if ($title != "") { + $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); + $title = str_replace(["[", "]"], ["[", "]"], $title); + $data["title"] = $title; + } - $image = ""; - preg_match("/image='(.*?)'/ism", $attributes, $matches); - if (x($matches, 1)) { - $image = $matches[1]; - } + $image = ""; + preg_match("/image='(.*?)'/ism", $attributes, $matches); + if (x($matches, 1)) { + $image = $matches[1]; + } - preg_match('/image=\"\;(.*?)\"\;/ism', $attributes, $matches); - if (x($matches, 1)) { - $image = $matches[1]; - } + preg_match('/image=\"\;(.*?)\"\;/ism', $attributes, $matches); + if (x($matches, 1)) { + $image = $matches[1]; + } - preg_match('/image=\\\"(.*?)\\\"/ism', $attributes, $matches); - if (x($matches, 1)) { - $image = $matches[1]; - } + preg_match('/image=\\\"(.*?)\\\"/ism', $attributes, $matches); + if (x($matches, 1)) { + $image = $matches[1]; + } - if ($image != "") { - $data["image"] = html_entity_decode($image, ENT_QUOTES, 'UTF-8'); - } + if ($image != "") { + $data["image"] = html_entity_decode($image, ENT_QUOTES, 'UTF-8'); + } - $preview = ""; - preg_match("/preview='(.*?)'/ism", $attributes, $matches); - if (x($matches, 1)) { - $preview = $matches[1]; - } + $preview = ""; + preg_match("/preview='(.*?)'/ism", $attributes, $matches); + if (x($matches, 1)) { + $preview = $matches[1]; + } - preg_match('/preview=\"\;(.*?)\"\;/ism', $attributes, $matches); - if (x($matches, 1)) { - $preview = $matches[1]; - } + preg_match('/preview=\"\;(.*?)\"\;/ism', $attributes, $matches); + if (x($matches, 1)) { + $preview = $matches[1]; + } - preg_match('/preview=\\\"(.*?)\\\"/ism', $attributes, $matches); - if (x($matches, 1)) { - $preview = $matches[1]; - } + preg_match('/preview=\\\"(.*?)\\\"/ism', $attributes, $matches); + if (x($matches, 1)) { + $preview = $matches[1]; + } - if ($preview != "") { - $data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8'); - } + if ($preview != "") { + $data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8'); + } - $data["description"] = trim($match[3]); + $data["description"] = trim($match[3]); - $data["after"] = trim($match[4]); + $data["after"] = trim($match[4]); - return $data; + return $data; } -function bb_ShareAttributes($match) { +function bb_ShareAttributes($match) +{ - $matches = []; - $attributes = $match[1]; + $matches = []; + $attributes = $match[1]; - $author = ""; - preg_match("/author='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $author = urldecode($matches[1]); + $author = ""; + preg_match("/author='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $author = urldecode($matches[1]); + } - $link = ""; - preg_match("/link='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $link = $matches[1]; + $link = ""; + preg_match("/link='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $link = $matches[1]; + } - $avatar = ""; - preg_match("/avatar='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $avatar = $matches[1]; + $avatar = ""; + preg_match("/avatar='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $avatar = $matches[1]; + } - $profile = ""; - preg_match("/profile='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $profile = $matches[1]; + $profile = ""; + preg_match("/profile='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $profile = $matches[1]; + } - $posted = ""; - preg_match("/posted='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $posted = $matches[1]; + $posted = ""; + preg_match("/posted='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $posted = $matches[1]; + } - $auth = ""; - preg_match("/auth='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { - if($matches[1] === 'true') - $auth = true; - else - $auth = false; - } + $auth = ""; + preg_match("/auth='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + if ($matches[1] === 'true') { + $auth = true; + } else { + $auth = false; + } + } - if($auth === EMPTY_STR) { - $auth = is_matrix_url($profile); - } + if ($auth === EMPTY_STR) { + $auth = is_matrix_url($profile); + } - // message_id is never used, do we still need it? - $message_id = ""; - preg_match("/message_id='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $message_id = $matches[1]; + // message_id is never used, do we still need it? + $message_id = ""; + preg_match("/message_id='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $message_id = $matches[1]; + } - if(! $message_id) { - preg_match("/guid='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $message_id = $matches[1]; - } + if (! $message_id) { + preg_match("/guid='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $message_id = $matches[1]; + } + } - $reldate = '' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . ''; + $reldate = '' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . ''; - $headline = '
'; + $headline = '
'; - if ($avatar != "") { - $headline .= '' . htmlspecialchars($author,ENT_COMPAT,'UTF-8',false) . ''; - } - - if(strpos($link,'/cards/')) - $type = t('card'); - elseif(strpos($link,'/articles/')) - $type = t('article'); - else - $type = t('post'); + if ($avatar != "") { + $headline .= '' . htmlspecialchars($author, ENT_COMPAT, 'UTF-8', false) . ''; + } - // Bob Smith wrote the following post 2 hours ago + if (strpos($link, '/cards/')) { + $type = t('card'); + } elseif (strpos($link, '/articles/')) { + $type = t('article'); + } else { + $type = t('post'); + } - $fmt = sprintf( t('%1$s wrote the following %2$s %3$s'), - '' . $author . '', - '' . $type . '', - $reldate - ); + // Bob Smith wrote the following post 2 hours ago - $headline .= '' . $fmt . '
'; + $fmt = sprintf( + t('%1$s wrote the following %2$s %3$s'), + '' . $author . '', + '' . $type . '', + $reldate + ); - $text = $headline . '
' . trim($match[2]) . '
'; + $headline .= '' . $fmt . '
'; - return $text; + $text = $headline . '
' . trim($match[2]) . '
'; + + return $text; } -function bb_location($match) { - // not yet implemented +function bb_location($match) +{ + // not yet implemented } /** @@ -652,135 +704,164 @@ function bb_location($match) { * @param array $match * @return string HTML iframe with content of $match[1] */ -function bb_iframe($match) { +function bb_iframe($match) +{ - $sandbox = ((strpos($match[1], App::get_hostname())) ? ' sandbox="allow-scripts" ' : ''); + $sandbox = ((strpos($match[1], App::get_hostname())) ? ' sandbox="allow-scripts" ' : ''); - return ''; + return ''; } -function bb_ShareAttributesSimple($match) { +function bb_ShareAttributesSimple($match) +{ - $matches = []; - $attributes = $match[1]; + $matches = []; + $attributes = $match[1]; - $author = ""; - preg_match("/author='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8'); + $author = ""; + preg_match("/author='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $author = html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8'); + } - preg_match('/author="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") - $author = $matches[1]; + preg_match('/author="(.*?)"/ism', $attributes, $matches); + if ($matches[1] != "") { + $author = $matches[1]; + } - $profile = ""; - preg_match("/profile='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $profile = $matches[1]; + $profile = ""; + preg_match("/profile='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") { + $profile = $matches[1]; + } - preg_match('/profile="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") - $profile = $matches[1]; + preg_match('/profile="(.*?)"/ism', $attributes, $matches); + if ($matches[1] != "") { + $profile = $matches[1]; + } - $text = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' ' . $author . ':
' . $match[2] . '
'; + $text = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' ' . $author . ':
' . $match[2] . '
'; - return($text); + return($text); } -function rpost_callback($match) { - if ($match[2]) { - return str_replace($match[0], Libzot::get_rpost_path(App::get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]); - } else { - return str_replace($match[0], Libzot::get_rpost_path(App::get_observer()) . '&body=' . urlencode($match[3]), $match[0]); - } +function rpost_callback($match) +{ + if ($match[2]) { + return str_replace($match[0], Libzot::get_rpost_path(App::get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]); + } else { + return str_replace($match[0], Libzot::get_rpost_path(App::get_observer()) . '&body=' . urlencode($match[3]), $match[0]); + } } -function bb_map_coords($match) { - // the extra space in the following line is intentional - return str_replace($match[0],'
' . generate_map(str_replace('/',' ',$match[1])) . '
', $match[0]); +function bb_map_coords($match) +{ + // the extra space in the following line is intentional + return str_replace($match[0], '
' . generate_map(str_replace('/', ' ', $match[1])) . '
', $match[0]); } -function bb_map_location($match) { - // the extra space in the following line is intentional - return str_replace($match[0],'
' . generate_named_map($match[1]) . '
', $match[0]); +function bb_map_location($match) +{ + // the extra space in the following line is intentional + return str_replace($match[0], '
' . generate_named_map($match[1]) . '
', $match[0]); } -function bb_opentag($match) { - $openclose = (($match[2]) ? '' . $match[1] . '' : t('Click to open/close')); - $text = (($match[2]) ? $match[2] : $match[1]); - $rnd = mt_rand(); +function bb_opentag($match) +{ + $openclose = (($match[2]) ? '' . $match[1] . '' : t('Click to open/close')); + $text = (($match[2]) ? $match[2] : $match[1]); + $rnd = mt_rand(); - return ''; + return ''; } -function bb_spoilertag($match) { - $openclose = (($match[2]) ? '' . $match[1] . ' ' . t('spoiler') . '' : t('Click to open/close')); - $text = (($match[2]) ? $match[2] : $match[1]); - $rnd = mt_rand(); +function bb_spoilertag($match) +{ + $openclose = (($match[2]) ? '' . $match[1] . ' ' . t('spoiler') . '' : t('Click to open/close')); + $text = (($match[2]) ? $match[2] : $match[1]); + $rnd = mt_rand(); - return ''; + return ''; } -function bb_summary($match) { - $rnd1 = mt_rand(); - $rnd2 = mt_rand(); - $rnd3 = mt_rand(); - $rnd4 = mt_rand(); +function bb_summary($match) +{ + $rnd1 = mt_rand(); + $rnd2 = mt_rand(); + $rnd3 = mt_rand(); + $rnd4 = mt_rand(); - return $match[1] . $match[2] . EOL . EOL . $match[3]; + return $match[1] . $match[2] . EOL . EOL . $match[3]; -// return $match[1] . '
' . $match[2] . '
' . t('View article') . '
'; +// return $match[1] . '
' . $match[2] . '
' . t('View article') . '
'; } -function bb_definitionList($match) { - // $match[1] is the markup styles for the "terms" in the definition list. - // $match[2] is the content between the [dl]...[/dl] tags +function bb_definitionList($match) +{ + // $match[1] is the markup styles for the "terms" in the definition list. + // $match[2] is the content between the [dl]...[/dl] tags - $classes = ''; - if (stripos($match[1], "b") !== false) $classes .= 'dl-terms-bold '; - if (stripos($match[1], "i") !== false) $classes .= 'dl-terms-italic '; - if (stripos($match[1], "u") !== false) $classes .= 'dl-terms-underline '; - if (stripos($match[1], "l") !== false) $classes .= 'dl-terms-large '; - if (stripos($match[1], "m") !== false) $classes .= 'dl-terms-monospace '; - if (stripos($match[1], "h") !== false) $classes .= 'dl-horizontal '; // dl-horizontal is already provided by bootstrap - if (strlen($classes) === 0) $classes = "dl-terms-plain"; + $classes = ''; + if (stripos($match[1], "b") !== false) { + $classes .= 'dl-terms-bold '; + } + if (stripos($match[1], "i") !== false) { + $classes .= 'dl-terms-italic '; + } + if (stripos($match[1], "u") !== false) { + $classes .= 'dl-terms-underline '; + } + if (stripos($match[1], "l") !== false) { + $classes .= 'dl-terms-large '; + } + if (stripos($match[1], "m") !== false) { + $classes .= 'dl-terms-monospace '; + } + if (stripos($match[1], "h") !== false) { + $classes .= 'dl-horizontal '; // dl-horizontal is already provided by bootstrap + } + if (strlen($classes) === 0) { + $classes = "dl-terms-plain"; + } - // The bbcode transformation will be: - // [*=term-text] description-text =>
term-text
description-text - // then after all replacements have been made, the extra
at the start of the - // first line can be removed. HTML5 allows the tag to be missing from the end of the last line. - // Using '(?\n"; - $eatLeadingSpaces = '(?: |[ \t])*'; // prevent spaces infront of [*= from adding another line to the previous element - $listElements = preg_replace('/^(\n|
)/', '', $match[2]); // ltrim the first newline - $listElements = preg_replace( - '/' . $eatLeadingSpaces . '\[\*=([[:print:]]*?)(?$1
', - $listElements - ); - // Unescape any \] inside the
tags - $listElements = preg_replace_callback('/
(.*?)<\/dt>/ism', 'bb_definitionList_unescapeBraces', $listElements); - - // Remove the extra at the start of the string, if there is one. - $firstOpenTag = strpos($listElements, '
'); - $firstCloseTag = strpos($listElements, $closeDescriptionTag); - if ($firstCloseTag !== false && ($firstOpenTag === false || ($firstCloseTag < $firstOpenTag))) { - $listElements = preg_replace( '/<\/dd>/ism', '', $listElements, 1); - } + // The bbcode transformation will be: + // [*=term-text] description-text =>
term-text
description-text + // then after all replacements have been made, the extra
at the start of the + // first line can be removed. HTML5 allows the tag to be missing from the end of the last line. + // Using '(?\n"; + $eatLeadingSpaces = '(?: |[ \t])*'; // prevent spaces infront of [*= from adding another line to the previous element + $listElements = preg_replace('/^(\n|
)/', '', $match[2]); // ltrim the first newline + $listElements = preg_replace( + '/' . $eatLeadingSpaces . '\[\*=([[:print:]]*?)(?$1
', + $listElements + ); + // Unescape any \] inside the
tags + $listElements = preg_replace_callback('/
(.*?)<\/dt>/ism', 'bb_definitionList_unescapeBraces', $listElements); - return '
' . $listElements . '
'; + // Remove the extra at the start of the string, if there is one. + $firstOpenTag = strpos($listElements, '
'); + $firstCloseTag = strpos($listElements, $closeDescriptionTag); + if ($firstCloseTag !== false && ($firstOpenTag === false || ($firstCloseTag < $firstOpenTag))) { + $listElements = preg_replace('/<\/dd>/ism', '', $listElements, 1); + } + + return '
' . $listElements . '
'; } -function bb_definitionList_unescapeBraces($match) { - return '
' . str_replace('\]', ']', $match[1]) . '
'; +function bb_definitionList_unescapeBraces($match) +{ + return '
' . str_replace('\]', ']', $match[1]) . '
'; } -function bb_checklist($match) { - $str = $match[1]; - $str = str_replace("[]", "
  • ", $str); - $str = str_replace("[x]", "
  • ", $str); - return '
      ' . $str . '
    '; +function bb_checklist($match) +{ + $str = $match[1]; + $str = str_replace("[]", "
  • ", $str); + $str = str_replace("[x]", "
  • ", $str); + return '
      ' . $str . '
    '; } @@ -790,1295 +871,1316 @@ function bb_checklist($match) { * @param array|string $input * @return string A HTML span tag with the styles. */ -function bb_sanitize_style($input) { - // whitelist array: property => limits (0 = no limitation) - $w = array( - // color properties - "color" => 0, - "background-color" => 0, - // box properties - "padding" => array("px"=>100, "%"=>0, "em"=>2, "ex"=>2, "mm"=>0, "cm"=>0, "in"=>0, "pt"=>0, "pc"=>0), - "margin" => array("px"=>100, "%"=>0, "em"=>2, "ex"=>2, "mm"=>0, "cm"=>0, "in"=>0, "pt"=>0, "pc"=>0), - "border" => array("px"=>100, "%"=>0, "em"=>2, "ex"=>2, "mm"=>0, "cm"=>0, "in"=>0, "pt"=>0, "pc"=>0), - "float" => 0, - "clear" => 0, - // text properties - "text-decoration" => 0, - ); +function bb_sanitize_style($input) +{ + // whitelist array: property => limits (0 = no limitation) + $w = array( + // color properties + "color" => 0, + "background-color" => 0, + // box properties + "padding" => array("px" => 100, "%" => 0, "em" => 2, "ex" => 2, "mm" => 0, "cm" => 0, "in" => 0, "pt" => 0, "pc" => 0), + "margin" => array("px" => 100, "%" => 0, "em" => 2, "ex" => 2, "mm" => 0, "cm" => 0, "in" => 0, "pt" => 0, "pc" => 0), + "border" => array("px" => 100, "%" => 0, "em" => 2, "ex" => 2, "mm" => 0, "cm" => 0, "in" => 0, "pt" => 0, "pc" => 0), + "float" => 0, + "clear" => 0, + // text properties + "text-decoration" => 0, + ); - // determine if input is string or array - - $input_is_array = is_array($input); - $css = []; - $css_string = (($input_is_array) ? $input[1] : $input); - $a = explode(';', $css_string); + // determine if input is string or array - foreach($a as $parts){ - list($k, $v) = explode(':', $parts); - $css[ trim($k) ] = trim($v); - } + $input_is_array = is_array($input); + $css = []; + $css_string = (($input_is_array) ? $input[1] : $input); + $a = explode(';', $css_string); - // sanitize properties - $b = array_merge(array_diff_key($css, $w), array_diff_key($w, $css)); - $css = array_diff_key($css, $b); - $css_string_san = ''; + foreach ($a as $parts) { + list($k, $v) = explode(':', $parts); + $css[ trim($k) ] = trim($v); + } - foreach ($css as $key => $value) { - if ($w[$key] != null) { - foreach ($w[$key] as $limit_key => $limit_value) { - //sanitize values - if (strpos($value, $limit_key)) { - $value = preg_replace_callback( - "/(\S.*?)$limit_key/ism", - function($match) use($limit_value, $limit_key) { - if ($match[1] > $limit_value) { - return $limit_value . $limit_key; - } else { - return $match[1] . $limit_key; - } - }, - $value - ); - } - } - } - $css_string_san .= $key . ":" . $value ."; "; - } + // sanitize properties + $b = array_merge(array_diff_key($css, $w), array_diff_key($w, $css)); + $css = array_diff_key($css, $b); + $css_string_san = ''; - if ($input_is_array) { - return '' . $input[2] . ''; - } + foreach ($css as $key => $value) { + if ($w[$key] != null) { + foreach ($w[$key] as $limit_key => $limit_value) { + //sanitize values + if (strpos($value, $limit_key)) { + $value = preg_replace_callback( + "/(\S.*?)$limit_key/ism", + function ($match) use ($limit_value, $limit_key) { + if ($match[1] > $limit_value) { + return $limit_value . $limit_key; + } else { + return $match[1] . $limit_key; + } + }, + $value + ); + } + } + } + $css_string_san .= $key . ":" . $value . "; "; + } - return $css_string_san; + if ($input_is_array) { + return '' . $input[2] . ''; + } + + return $css_string_san; } -function oblanguage_callback($matches) { - if(strlen($matches[1]) == 2) { - $compare = strtolower(substr(App::$language,0,2)); - } - else { - $compare = strtolower(App::$language); - } +function oblanguage_callback($matches) +{ + if (strlen($matches[1]) == 2) { + $compare = strtolower(substr(App::$language, 0, 2)); + } else { + $compare = strtolower(App::$language); + } - if($compare === strtolower($matches[1])) - return $matches[2]; + if ($compare === strtolower($matches[1])) { + return $matches[2]; + } - return ''; + return ''; } -function oblanguage_necallback($matches) { - if(strlen($matches[1]) == 2) { - $compare = strtolower(substr(App::$language,0,2)); - } - else { - $compare = strtolower(App::$language); - } +function oblanguage_necallback($matches) +{ + if (strlen($matches[1]) == 2) { + $compare = strtolower(substr(App::$language, 0, 2)); + } else { + $compare = strtolower(App::$language); + } - if($compare !== strtolower($matches[1])) - return $matches[2]; + if ($compare !== strtolower($matches[1])) { + return $matches[2]; + } - return ''; + return ''; } -function bb_observer($Text) { +function bb_observer($Text) +{ - $observer = App::get_observer(); + $observer = App::get_observer(); - if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) { + if ((strpos($Text, '[/observer]') !== false) || (strpos($Text, '[/rpost]') !== false)) { + if ($observer) { + $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); + } else { + $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); + } + } - if ($observer) { - $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); - } else { - $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); - } - } + $channel = App::get_channel(); - $channel = App::get_channel(); + if (strpos($Text, '[/channel]') !== false) { + if ($channel) { + $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text); + $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text); + } else { + $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text); + $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text); + } + } - if (strpos($Text,'[/channel]') !== false) { - if ($channel) { - $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text); - $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text); - } else { - $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text); - $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text); - } - } - - return $Text; + return $Text; } -function bb_imgoptions($match) { +function bb_imgoptions($match) +{ - // $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); - // alt text cannot contain ']' - - // [img|zmg=wwwxhhh float=left|right alt=alt text]url[/img|zmg] - // [img|zmg width="nnn" height="nnn" alt="xyz" style="float: abc;"]url[/img|zmg] - - $local_match = null; - $width = 0; - $float = false; - $alt = false; + // $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); + // alt text cannot contain ']' - $style = EMPTY_STR; + // [img|zmg=wwwxhhh float=left|right alt=alt text]url[/img|zmg] + // [img|zmg width="nnn" height="nnn" alt="xyz" style="float: abc;"]url[/img|zmg] - $attributes = $match[3]; + $local_match = null; + $width = 0; + $float = false; + $alt = false; - $x = preg_match("/alt='(.*?)'/ism", $attributes, $matches); - if ($x) { - $alt = $matches[1]; - } - - $x = preg_match("/alt=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($x) { - $alt = $matches[1]; - } + $style = EMPTY_STR; - $x = preg_match("/alt=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($x) { - $alt = $matches[1]; - } + $attributes = $match[3]; - $x = preg_match("/width=([0-9]*)/ism", $attributes, $matches); - if ($x) { - $width = bb_xss($matches[1]); - } + $x = preg_match("/alt='(.*?)'/ism", $attributes, $matches); + if ($x) { + $alt = $matches[1]; + } - $x = preg_match("/width='(.*?)'/ism", $attributes, $matches); - if ($x) { - $width = bb_xss($matches[1]); - } - - $x = preg_match("/width=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($x) { - $width = bb_xss($matches[1]); - } + $x = preg_match("/alt=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $alt = $matches[1]; + } - $x = preg_match("/width=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($x) { - $width = bb_xss($matches[1]); - } + $x = preg_match("/alt=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($x) { + $alt = $matches[1]; + } - $x = preg_match("/height=([0-9]*)/ism", $attributes, $matches); - if ($x) { - $height = bb_xss($matches[1]); - } + $x = preg_match("/width=([0-9]*)/ism", $attributes, $matches); + if ($x) { + $width = bb_xss($matches[1]); + } - $x = preg_match("/height='(.*?)'/ism", $attributes, $matches); - if ($x) { - $height = bb_xss($matches[1]); - } - - $x = preg_match("/height=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($x) { - $height = bb_xss($matches[1]); - } - - $x = preg_match("/height=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($x) { - $height = bb_xss($matches[1]); - } + $x = preg_match("/width='(.*?)'/ism", $attributes, $matches); + if ($x) { + $width = bb_xss($matches[1]); + } - $x = preg_match("/style='(.*?)'/ism", $attributes, $matches); - if ($x) { - $style = bb_sanitize_style($matches[1]); - } - - $x = preg_match("/style=\"\;(.*?)\"\;/ism", $attributes, $matches); - if ($x) { - $style = bb_sanitize_style($matches[1]); - } + $x = preg_match("/width=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $width = bb_xss($matches[1]); + } - $x = preg_match("/style=\\\"(.*?)\\\"/ism", $attributes, $matches); - if ($x) { - $style = bb_sanitize_style($matches[1]); - } + $x = preg_match("/width=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($x) { + $width = bb_xss($matches[1]); + } - // legacy img options - - if ($match[2] === '=') { - // pull out (optional) legacy size declarations first - if (preg_match("/([0-9]*)x([0-9]*)/ism",$match[3],$local_match)) { - $width = intval($local_match[1]); - } - $match[3] = substr($match[3],strpos($match[3],' ')); - } + $x = preg_match("/height=([0-9]*)/ism", $attributes, $matches); + if ($x) { + $height = bb_xss($matches[1]); + } - // then (optional) legacy float specifiers - if ($n = strpos($match[3],'float=left') !== false) { - $float = 'left'; - $match[3] = substr($match[3],$n + 10); - } - if ($n = strpos($match[3],'float=right') !== false) { - $float = 'right'; - $match[3] = substr($match[3],$n + 11); - } - - // finally alt text which extends to the close of the tag - if ((! $alt) && ($n = strpos($match[3],'alt=') !== false)) { - $alt = substr($match[3],$n + 4); - } + $x = preg_match("/height='(.*?)'/ism", $attributes, $matches); + if ($x) { + $height = bb_xss($matches[1]); + } - // now assemble the resulting img tag from these components - - $output = ''; - - return $output; - + $x = preg_match("/height=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($x) { + $height = bb_xss($matches[1]); + } + + $x = preg_match("/style='(.*?)'/ism", $attributes, $matches); + if ($x) { + $style = bb_sanitize_style($matches[1]); + } + + $x = preg_match("/style=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $style = bb_sanitize_style($matches[1]); + } + + $x = preg_match("/style=\\\"(.*?)\\\"/ism", $attributes, $matches); + if ($x) { + $style = bb_sanitize_style($matches[1]); + } + + // legacy img options + + if ($match[2] === '=') { + // pull out (optional) legacy size declarations first + if (preg_match("/([0-9]*)x([0-9]*)/ism", $match[3], $local_match)) { + $width = intval($local_match[1]); + } + $match[3] = substr($match[3], strpos($match[3], ' ')); + } + + // then (optional) legacy float specifiers + if ($n = strpos($match[3], 'float=left') !== false) { + $float = 'left'; + $match[3] = substr($match[3], $n + 10); + } + if ($n = strpos($match[3], 'float=right') !== false) { + $float = 'right'; + $match[3] = substr($match[3], $n + 11); + } + + // finally alt text which extends to the close of the tag + if ((! $alt) && ($n = strpos($match[3], 'alt=') !== false)) { + $alt = substr($match[3], $n + 4); + } + + // now assemble the resulting img tag from these components + + $output = ''; + + return $output; } -function multicode_purify($s) { +function multicode_purify($s) +{ - $s = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", function ($match) { - return '[code' . $match[1] . ']' . bb_code_protect($match[2]) . '[/code]'; - }, $s); + $s = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", function ($match) { + return '[code' . $match[1] . ']' . bb_code_protect($match[2]) . '[/code]'; + }, $s); - $s = preg_replace_callback('#(^|\n)([`~]{3,})(?: *\.?([a-zA-Z0-9\-.]+))?\n+([\s\S]+?)\n+\2(\n|$)#', function ($match) { - return $match[1] . $match[2] . "\n" . bb_code_protect($match[4]) . "\n" . $match[2] . (($match[5]) ? $match[5] : "\n"); - }, $s); + $s = preg_replace_callback('#(^|\n)([`~]{3,})(?: *\.?([a-zA-Z0-9\-.]+))?\n+([\s\S]+?)\n+\2(\n|$)#', function ($match) { + return $match[1] . $match[2] . "\n" . bb_code_protect($match[4]) . "\n" . $match[2] . (($match[5]) ? $match[5] : "\n"); + }, $s); -// if (strpos($s,'<') !== false || strpos($s,'>') !== false) { - $s = purify_html($s, [ 'escape' ]); -// } - - return bb_code_unprotect($s); +// if (strpos($s,'<') !== false || strpos($s,'>') !== false) { + $s = purify_html($s, [ 'escape' ]); +// } + return bb_code_unprotect($s); } -function bb_code_preprotect($matches) { - return '[code' . $matches[1] . ']' . 'b64.^8e%.' . base64_encode(str_replace('
    ','|+br+|',$matches[2])) . '.b64.$8e%' . '[/code]'; +function bb_code_preprotect($matches) +{ + return '[code' . $matches[1] . ']' . 'b64.^8e%.' . base64_encode(str_replace('
    ', '|+br+|', $matches[2])) . '.b64.$8e%' . '[/code]'; } -function bb_code_preunprotect($s) { - return preg_replace_callback('|b64\.\^8e\%\.(.*?)\.b64\.\$8e\%|ism','bb_code_unprotect_sub',$s); +function bb_code_preunprotect($s) +{ + return preg_replace_callback('|b64\.\^8e\%\.(.*?)\.b64\.\$8e\%|ism', 'bb_code_unprotect_sub', $s); } -function bb_code_protect($s) { - return 'b64.^9e%.' . base64_encode(str_replace('
    ','|+br+|',$s)) . '.b64.$9e%'; +function bb_code_protect($s) +{ + return 'b64.^9e%.' . base64_encode(str_replace('
    ', '|+br+|', $s)) . '.b64.$9e%'; } -function bb_code_unprotect($s) { - return preg_replace_callback('|b64\.\^9e\%\.(.*?)\.b64\.\$9e\%|ism','bb_code_unprotect_sub',$s); +function bb_code_unprotect($s) +{ + return preg_replace_callback('|b64\.\^9e\%\.(.*?)\.b64\.\$9e\%|ism', 'bb_code_unprotect_sub', $s); } -function bb_code_unprotect_sub($match) { - $x = str_replace( [ '<', '>' ], [ '<', '>' ], base64_decode($match[1])); - return str_replace('|+br+|','
    ', $x); +function bb_code_unprotect_sub($match) +{ + $x = str_replace([ '<', '>' ], [ '<', '>' ], base64_decode($match[1])); + return str_replace('|+br+|', '
    ', $x); } -function bb_colorbox($match) { - if (strpos($match[1],'zrl')) { - $url = zid($match[2]); - } - else { - $url = $match[2]; - } - return 'censored'; +function bb_colorbox($match) +{ + if (strpos($match[1], 'zrl')) { + $url = zid($match[2]); + } else { + $url = $match[2]; + } + return 'censored'; } -function bb_code($match) { - if(strpos($match[0], "
    ")) - return '
    ' . bb_code_protect(trim($match[1])) . '
    '; - else - return '' . bb_code_protect(trim($match[1])) . ''; +function bb_code($match) +{ + if (strpos($match[0], "
    ")) { + return '
    ' . bb_code_protect(trim($match[1])) . '
    '; + } else { + return '' . bb_code_protect(trim($match[1])) . ''; + } } -function bb_code_options($match) { - if(strpos($match[0], "
    ")) { - $class = ""; - $pre = true; - } else { - $class = "inline-code"; - $pre = false; - } - if(strpos($match[1], 'nowrap')) { - $style = "overflow-x: auto; white-space: pre;"; - } else { - $style = ""; - } - if($pre) { - return '
    ' . bb_code_protect(trim($match[2])) . '
    '; - } else { - return '' . bb_code_protect(trim($match[2])) . ''; - } +function bb_code_options($match) +{ + if (strpos($match[0], "
    ")) { + $class = ""; + $pre = true; + } else { + $class = "inline-code"; + $pre = false; + } + if (strpos($match[1], 'nowrap')) { + $style = "overflow-x: auto; white-space: pre;"; + } else { + $style = ""; + } + if ($pre) { + return '
    ' . bb_code_protect(trim($match[2])) . '
    '; + } else { + return '' . bb_code_protect(trim($match[2])) . ''; + } } -function md_protect($match) { - return bb_code_protect($match[1]); +function md_protect($match) +{ + return bb_code_protect($match[1]); } -function html_protect($match) { - return str_replace(['<','>'],['<','>'],$match[1]); +function html_protect($match) +{ + return str_replace(['<','>'], ['<','>'], $match[1]); } -function md_header($content) { +function md_header($content) +{ - $headingLevel = strlen($content[1]); - $header = trim($content[2]); - // Build anchor without space, numbers. + $headingLevel = strlen($content[1]); + $header = trim($content[2]); + // Build anchor without space, numbers. $anchor = preg_replace('#[^a-z?!]#', '', strtolower($header)); return sprintf('%s', $headingLevel, $anchor, $header, $headingLevel); - } -function md_codeblock($content) { +function md_codeblock($content) +{ - $language = !empty($content[3]) ? filter_var($content[3], FILTER_SANITIZE_STRING) : ''; - $class = !empty($language) ? sprintf(' class="%s language-%s"', $language, $language) : ''; - // Build one block so that we not render each paragraph separately. - $content = str_replace("\n", '
    ', $content[4]); + $language = !empty($content[3]) ? filter_var($content[3], FILTER_SANITIZE_STRING) : ''; + $class = !empty($language) ? sprintf(' class="%s language-%s"', $language, $language) : ''; + // Build one block so that we not render each paragraph separately. + $content = str_replace("\n", '
    ', $content[4]); - return sprintf('
    %s
    ', $class, bb_code_protect($content)); + return sprintf('
    %s
    ', $class, bb_code_protect($content)); } -function md_italic($content) { +function md_italic($content) +{ - return '' . $content[1] . $content[3] . ''; + return '' . $content[1] . $content[3] . ''; } -function md_bold($content) { +function md_bold($content) +{ - return '' . $content[1] . $content[3] . ''; + return '' . $content[1] . $content[3] . ''; } -function md_bolditalic($content) { +function md_bolditalic($content) +{ - return '' . $content[1] . $content[3] . ''; + return '' . $content[1] . $content[3] . ''; } -function md_image($content) { - $url = filter_var($content[1], FILTER_SANITIZE_URL); - $alt = ''; - if (isset($content[2])) { - $content[2] = str_replace('"', '', $content[2]); - $alt = ' alt="' . filter_var($content[2], FILTER_SANITIZE_STRING) . '"'; - } +function md_image($content) +{ + $url = filter_var($content[1], FILTER_SANITIZE_URL); + $alt = ''; + if (isset($content[2])) { + $content[2] = str_replace('"', '', $content[2]); + $alt = ' alt="' . filter_var($content[2], FILTER_SANITIZE_STRING) . '"'; + } - return sprintf('', $url, $alt); + return sprintf('', $url, $alt); } -function md_topheader($matches) { - // Terrible hack to check we haven't found an empty list item. - if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { - return $matches[0]; - } +function md_topheader($matches) +{ + // Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { + return $matches[0]; + } - $level = $matches[2][0] == '=' ? 1 : 2; - - return "" . $matches[1] . "" . "\n"; + $level = $matches[2][0] == '=' ? 1 : 2; + return "" . $matches[1] . "" . "\n"; } -function bb_fixtable_lf($match) { +function bb_fixtable_lf($match) +{ - // bbcode version (1 arg) - // remove extraneous whitespace between table element tags since newlines will all - // be converted to '
    ' and turn your neatly crafted tables into a whole lot of - // empty space. - - $x = preg_replace("/\]\s+\[/",'][',$match[1]); - $x = str_replace("\\\n","\n",$x); - return '[table]' . $x . '[/table]'; + // bbcode version (1 arg) + // remove extraneous whitespace between table element tags since newlines will all + // be converted to '
    ' and turn your neatly crafted tables into a whole lot of + // empty space. + $x = preg_replace("/\]\s+\[/", '][', $match[1]); + $x = str_replace("\\\n", "\n", $x); + return '[table]' . $x . '[/table]'; } -function ht_fixtable_lf($match) { +function ht_fixtable_lf($match) +{ - // HTML version (2 args) - // remove extraneous whitespace between table element tags since newlines will all - // be converted to '
    ' and turn your neatly crafted tables into a whole lot of - // empty space. - - $x = preg_replace("/\>\s+\<',$match[2]); - return '' . $x . ''; + // HTML version (2 args) + // remove extraneous whitespace between table element tags since newlines will all + // be converted to '
    ' and turn your neatly crafted tables into a whole lot of + // empty space. + $x = preg_replace("/\>\s+\<', $match[2]); + return '' . $x . ''; } -function bb_colortag($matches) { - return '' . $matches[2] . ''; +function bb_colortag($matches) +{ + return '' . $matches[2] . ''; } -function bb_fonttag($matches) { - return '' . $matches[2] . ''; +function bb_fonttag($matches) +{ + return '' . $matches[2] . ''; } -function bb_sizetag($matches) { - return '' . $matches[2] . ''; - +function bb_sizetag($matches) +{ + return '' . $matches[2] . ''; } -function bb_hltag($matches) { - return '' . $matches[2] . ''; +function bb_hltag($matches) +{ + return '' . $matches[2] . ''; } -function bb_xss($s) { - // don't allow functions of any kind - $s = str_replace( [ '(', ')' ], [ '', '' ], $s); +function bb_xss($s) +{ + // don't allow functions of any kind + $s = str_replace([ '(', ')' ], [ '', '' ], $s); - // don't allow injection of multiple params + // don't allow injection of multiple params - if (strpos($s,';') !== false) { - return substr($s,0,strpos($s,';')); - } - return $s; + if (strpos($s, ';') !== false) { + return substr($s, 0, strpos($s, ';')); + } + return $s; } -function bbtopoll($s) { +function bbtopoll($s) +{ - $pl = []; + $pl = []; - $match = ''; - if(! preg_match("/\[poll=(.*?)\](.*?)\[\/poll\]/ism",$s,$match)) { - return null; - } - $pl['poll_id'] = $match[1]; - $pl['poll_question'] = $match[2]; + $match = ''; + if (! preg_match("/\[poll=(.*?)\](.*?)\[\/poll\]/ism", $s, $match)) { + return null; + } + $pl['poll_id'] = $match[1]; + $pl['poll_question'] = $match[2]; - $match = ''; - if(preg_match_all("/\[poll\-answer=(.*?)\](.*?)\[\/poll\-answer\]/is",$s,$match,PREG_SET_ORDER)) { - $pl['answer'] = []; - foreach($match as $m) { - $ans = [ 'answer_id' => $m[1], 'answer_text' => $m[2] ]; - $pl['answer'][] = $ans; - } - } - - return $pl; + $match = ''; + if (preg_match_all("/\[poll\-answer=(.*?)\](.*?)\[\/poll\-answer\]/is", $s, $match, PREG_SET_ORDER)) { + $pl['answer'] = []; + foreach ($match as $m) { + $ans = [ 'answer_id' => $m[1], 'answer_text' => $m[2] ]; + $pl['answer'][] = $ans; + } + } + return $pl; } -function parseIdentityAwareHTML($Text) { +function parseIdentityAwareHTML($Text) +{ - // Hide all [noparse] contained bbtags by spacefying them - if (strpos($Text,'[noparse]') !== false) { - $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text); - } - if (strpos($Text,'[nobb]') !== false) { - $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text); - } - if (strpos($Text,'[pre]') !== false) { - $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); - } - // process [observer] tags before we do anything else because we might - // be stripping away stuff that then doesn't need to be worked on anymore + // Hide all [noparse] contained bbtags by spacefying them + if (strpos($Text, '[noparse]') !== false) { + $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy', $Text); + } + if (strpos($Text, '[nobb]') !== false) { + $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy', $Text); + } + if (strpos($Text, '[pre]') !== false) { + $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy', $Text); + } + // process [observer] tags before we do anything else because we might + // be stripping away stuff that then doesn't need to be worked on anymore $observer = App::get_observer(); - if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) { + if ((strpos($Text, '[/observer]') !== false) || (strpos($Text, '[/rpost]') !== false)) { + $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_callback', $Text); - $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text); + $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_necallback', $Text); - $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text); + if ($observer) { + $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); + } else { + $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); + } + } + // replace [observer.baseurl] + if ($observer) { + $s1 = ''; + $s2 = ''; + $obsBaseURL = $observer['xchan_connurl']; + $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL); + $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); + $Text = str_replace('[observer.url]', $observer['xchan_url'], $Text); + $Text = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $Text); + $Text = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $Text); + $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $Text); + $Text = str_replace('[observer.photo]', $s1 . '[zmg]' . $observer['xchan_photo_l'] . '[/zmg]' . $s2, $Text); + $Text = str_replace('[observer.baseurl/]', $obsBaseURL, $Text); + $Text = str_replace('[observer.url/]', $observer['xchan_url'], $Text); + $Text = str_replace('[observer.name/]', $s1 . $observer['xchan_name'] . $s2, $Text); + $Text = str_replace('[observer.address/]', $s1 . $observer['xchan_addr'] . $s2, $Text); + $Text = str_replace('[observer.webname/]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $Text); + $Text = str_replace('[observer.photo/]', $s1 . '[zmg]' . $observer['xchan_photo_l'] . '[/zmg]' . $s2, $Text); + } else { + $Text = str_replace('[observer.baseurl]', '', $Text); + $Text = str_replace('[observer.url]', '', $Text); + $Text = str_replace('[observer.name]', '', $Text); + $Text = str_replace('[observer.address]', '', $Text); + $Text = str_replace('[observer.webname]', '', $Text); + $Text = str_replace('[observer.photo]', '', $Text); + $Text = str_replace('[observer.baseurl/]', '', $Text); + $Text = str_replace('[observer.url/]', '', $Text); + $Text = str_replace('[observer.name/]', '', $Text); + $Text = str_replace('[observer.address/]', '', $Text); + $Text = str_replace('[observer.webname/]', '', $Text); + $Text = str_replace('[observer.photo/]', '', $Text); + } - if ($observer) { - $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); - } else { - $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); - } - } - // replace [observer.baseurl] - if ($observer) { - $s1 = ''; - $s2 = ''; - $obsBaseURL = $observer['xchan_connurl']; - $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL); - $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); - $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text); - $Text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $Text); - $Text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $Text); - $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text); - $Text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text); - $Text = str_replace('[observer.baseurl/]', $obsBaseURL, $Text); - $Text = str_replace('[observer.url/]',$observer['xchan_url'], $Text); - $Text = str_replace('[observer.name/]',$s1 . $observer['xchan_name'] . $s2, $Text); - $Text = str_replace('[observer.address/]',$s1 . $observer['xchan_addr'] . $s2, $Text); - $Text = str_replace('[observer.webname/]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text); - $Text = str_replace('[observer.photo/]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text); + $Text = str_replace(array('[baseurl]','[baseurl/]','[sitename]','[sitename/]'), array(z_root(),z_root(), get_config('system', 'sitename'),get_config('system', 'sitename')), $Text); - } else { - $Text = str_replace('[observer.baseurl]', '', $Text); - $Text = str_replace('[observer.url]','', $Text); - $Text = str_replace('[observer.name]','', $Text); - $Text = str_replace('[observer.address]','', $Text); - $Text = str_replace('[observer.webname]','',$Text); - $Text = str_replace('[observer.photo]','', $Text); - $Text = str_replace('[observer.baseurl/]', '', $Text); - $Text = str_replace('[observer.url/]','', $Text); - $Text = str_replace('[observer.name/]','', $Text); - $Text = str_replace('[observer.address/]','', $Text); - $Text = str_replace('[observer.webname/]','',$Text); - $Text = str_replace('[observer.photo/]','', $Text); - } - - $Text = str_replace(array('[baseurl]','[baseurl/]','[sitename]','[sitename/]'),array(z_root(),z_root(), get_config('system','sitename'),get_config('system','sitename')),$Text); - - // Unhide all [noparse] contained bbtags unspacefying them - // and triming the [noparse] tag. - if (strpos($Text,'[noparse]') !== false) { - $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); - } - if (strpos($Text,'[nobb]') !== false) { - $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text); - } - if (strpos($Text,'[pre]') !== false) { - $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); - } - return $Text; + // Unhide all [noparse] contained bbtags unspacefying them + // and triming the [noparse] tag. + if (strpos($Text, '[noparse]') !== false) { + $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); + } + if (strpos($Text, '[nobb]') !== false) { + $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text); + } + if (strpos($Text, '[pre]') !== false) { + $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); + } + return $Text; } -function bbcode($Text, $options = []) { +function bbcode($Text, $options = []) +{ - if(! is_array($options)) { - $options = []; - } + if (! is_array($options)) { + $options = []; + } - if(is_array($Text)) { - btlogger('Text is array: ' . print_r($Text,true)); - } + if (is_array($Text)) { + btlogger('Text is array: ' . print_r($Text, true)); + } - $cache = ((array_key_exists('cache',$options)) ? $options['cache'] : false); - $newwin = ((array_key_exists('newwin',$options)) ? $options['newwin'] : true); - $export = ((array_key_exists('export',$options)) ? $options['export'] : false); - $activitypub = ((array_key_exists('activitypub',$options)) ? $options['activitypub'] : false); - $censored = ((array_key_exists('censored',$options)) ? $options['censored'] : false); - $plain = ((array_key_exists('plain',$options)) ? $options['plain'] : false); - $bbonly = ((array_key_exists('bbonly',$options)) ? $options['bbonly'] : false); - - if ($activitypub) { - $export = true; - } + $cache = ((array_key_exists('cache', $options)) ? $options['cache'] : false); + $newwin = ((array_key_exists('newwin', $options)) ? $options['newwin'] : true); + $export = ((array_key_exists('export', $options)) ? $options['export'] : false); + $activitypub = ((array_key_exists('activitypub', $options)) ? $options['activitypub'] : false); + $censored = ((array_key_exists('censored', $options)) ? $options['censored'] : false); + $plain = ((array_key_exists('plain', $options)) ? $options['plain'] : false); + $bbonly = ((array_key_exists('bbonly', $options)) ? $options['bbonly'] : false); - $target = (($newwin) ? ' target="_blank" ' : ''); + if ($activitypub) { + $export = true; + } - call_hooks('bbcode_filter', $Text); + $target = (($newwin) ? ' target="_blank" ' : ''); + call_hooks('bbcode_filter', $Text); - // Hide all [noparse] contained bbtags by spacefying them - if (strpos($Text,'[noparse]') !== false) { - $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text); - } - if (strpos($Text,'[nobb]') !== false) { - $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text); - } - if (strpos($Text,'[pre]') !== false) { - $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); - } - $Text = bb_format_attachdata($Text); + // Hide all [noparse] contained bbtags by spacefying them + if (strpos($Text, '[noparse]') !== false) { + $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy', $Text); + } + if (strpos($Text, '[nobb]') !== false) { + $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy', $Text); + } + if (strpos($Text, '[pre]') !== false) { + $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy', $Text); + } - // If we find any event code, turn it into an event. - // After we're finished processing the bbcode we'll - // replace all of the event code with a reformatted version. + $Text = bb_format_attachdata($Text); - $ev = bbtoevent($Text); + // If we find any event code, turn it into an event. + // After we're finished processing the bbcode we'll + // replace all of the event code with a reformatted version. - // and the same with polls + $ev = bbtoevent($Text); - $pl = bbtopoll($Text); + // and the same with polls + $pl = bbtopoll($Text); - // process [observer] tags before we do anything else because we might - // be stripping away stuff that then doesn't need to be worked on anymore - if($cache || $export) - $observer = false; - else - $observer = App::get_observer(); + // process [observer] tags before we do anything else because we might + // be stripping away stuff that then doesn't need to be worked on anymore - if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) { - $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text); - $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text); + if ($cache || $export) { + $observer = false; + } else { + $observer = App::get_observer(); + } - if ($observer) { - $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); - } else { - $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); - $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); - $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); - } - } + if ((strpos($Text, '[/observer]') !== false) || (strpos($Text, '[/rpost]') !== false)) { + $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_callback', $Text); + $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_necallback', $Text); - if($cache || $export) - $channel = false; - else - $channel = App::get_channel(); + if ($observer) { + $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text); + } else { + $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); + } + } - if (strpos($Text,'[/channel]') !== false) { - if ($channel) { - $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text); - $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text); - } else { - $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text); - $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text); - } - } + if ($cache || $export) { + $channel = false; + } else { + $channel = App::get_channel(); + } + if (strpos($Text, '[/channel]') !== false) { + if ($channel) { + $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text); + $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text); + } else { + $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text); + $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text); + } + } - $x = bb_extract_images($Text); - $Text = $x['body']; - $saved_images = $x['images']; - if(! $export) - $Text = str_replace(array('[baseurl]','[baseurl/]','[sitename]','[sitename/]'),array(z_root(),z_root(), get_config('system','sitename'),get_config('system','sitename')),$Text); + $x = bb_extract_images($Text); + $Text = $x['body']; + $saved_images = $x['images']; + if (! $export) { + $Text = str_replace(array('[baseurl]','[baseurl/]','[sitename]','[sitename/]'), array(z_root(),z_root(), get_config('system', 'sitename'),get_config('system', 'sitename')), $Text); + } - // Replace any html brackets with HTML Entities to prevent executing HTML or script - // Don't use strip_tags here because it breaks [url] search by replacing & with amp - // These are no longer needed since we run the content through purify_html() - // $Text = str_replace("<", "<", $Text); - // $Text = str_replace(">", ">", $Text); + // Replace any html brackets with HTML Entities to prevent executing HTML or script + // Don't use strip_tags here because it breaks [url] search by replacing & with amp + // These are no longer needed since we run the content through purify_html() + // $Text = str_replace("<", "<", $Text); + // $Text = str_replace(">", ">", $Text); - // Check for [code] text here, before the linefeeds are messed with. - // The highlighter will unescape and re-escape the content. - if (strpos($Text,'[code=') !== false) { - $Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", function ($match) use ($options) { - return bb_code_protect(text_highlight($match[2],strtolower($match[1]),$options)); - }, $Text); - } + // Check for [code] text here, before the linefeeds are messed with. + // The highlighter will unescape and re-escape the content. - $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text); - $Text = preg_replace_callback("/\(.*?)\<\/table\>/ism",'ht_fixtable_lf',$Text); + if (strpos($Text, '[code=') !== false) { + $Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", function ($match) use ($options) { + return bb_code_protect(text_highlight($match[2], strtolower($match[1]), $options)); + }, $Text); + } - $Text = str_replace("\r\n", "\n", $Text); + $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism", 'bb_fixtable_lf', $Text); + $Text = preg_replace_callback("/\(.*?)\<\/table\>/ism", 'ht_fixtable_lf', $Text); - if ($bbonly) { - $Text = purify_html($Text); - } - else { + $Text = str_replace("\r\n", "\n", $Text); - // escape some frequently encountered false positives with a zero-width space + if ($bbonly) { + $Text = purify_html($Text); + } else { + // escape some frequently encountered false positives with a zero-width space - // Here we are catching things like [quote](something)[/quote] and [b](something)[/b] and preventing them from turning into broken markdown links [text](url) - // We'll do this with a zero-width space between ] and ( - $Text = preg_replace("/\[(.*?)\]\((.*?)\)\[\/(.*?)\]/ism", '[$1]' . html_entity_decode('​') . '($2)[/$3]', $Text); + // Here we are catching things like [quote](something)[/quote] and [b](something)[/b] and preventing them from turning into broken markdown links [text](url) + // We'll do this with a zero-width space between ] and ( + $Text = preg_replace("/\[(.*?)\]\((.*?)\)\[\/(.*?)\]/ism", '[$1]' . html_entity_decode('​') . '($2)[/$3]', $Text); - // save code blocks from being interpreted as markdown + // save code blocks from being interpreted as markdown - $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_preprotect', $Text); + $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_preprotect', $Text); - // Quick but flawed fix for performance regression after purification - // was moved to rendering code to allow multiple code formats - // A proper fix would be to escape any code blocks before purification, - // restore them and store the resultant intermediate multicode. - // This is now accomplished using multicode_purify() - - // if (strpbrk($Text,'<>') !== false) { - // $Text = purify_html($Text, [ 'escape' ]); - // } - - // the bbcode tag 'nomd' will bypass markdown processing for any given text region - - $Text = preg_replace_callback('#\[nomd\](.*?)\[\/nomd\]#ism','md_protect',$Text); - - // and for completeness, there's 'nohtml' - - - $Text = preg_replace_callback('#\[nohtml\](.*?)\[\/nohtml\]#ism','html_protect',$Text); - - - // Perform some markdown conversions before translating linefeeds so as to keep the regexes manageable - // The preceding character check in bold/italic sequences is so we don't mistake underscore/asterisk in the middle of conversational text as an italic trigger. - - $Text = preg_replace_callback('#(^|\n| )(?$3
  • ',$Text); - // markdown inline code blocks must be preceded by space or linebreak - $Text = preg_replace('#(^|\n| )(?$2', $Text); - // strip backslash escape for inline code - $Text = preg_replace('#(\\\)`#','`',$Text); - $Text = preg_replace('#<\/code><\/pre>\n
    | .*?>)#','
    ',$Text); - - // blockquotes - $Text = preg_replace('#^(>)+ +(.*?)$#m','
    $2
    ',$Text); - $Text = preg_replace('#^(\>)+ +(.*?)$#m','
    $2
    ',$Text); - $Text = preg_replace('#\n
    #',"\n", $Text); - - // links - $Text = preg_replace_callback('#!\[[^\]]*\]\((.*?)(?=\"|\))(\".*\")?\)(?!`)#','md_image',$Text); - $Text = preg_replace('#\[([^\[]+)\]\((?:javascript:)?([^\)]+)\)(?!`)#','$1',$Text); - - // unordered lists - $Text = preg_replace('#^(?
  • $1
  • ',$Text); - // strip the backslash escape if present - $Text = preg_replace('#^(\\\)([*\-+]) #m','$2',$Text); - // order lists - $Text = preg_replace('#^\d+[\.\)] +(.*?)$#m','
    1. $1
    ',$Text); - - $Text = preg_replace('/\s*<\/(ol|ul)>\n+<\1>\s*/',"\n",$Text); - - $Text = bb_code_preunprotect($Text); - } - - - // Convert new line chars to html
    tags - - $Text = str_replace(array("\r", "\n"), array('
    ', '
    '), $Text); - $Text = str_replace(array("\t", " "), array("    ", "  "), $Text); - - // Check for [code] text - if (strpos($Text,'[code]') !== false) { - $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text); - } - - // Check for [code options] text - if (strpos($Text,'[code ') !== false) { - $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text); - } - - // Set up the parameters for a URL search string - $URLSearchString = "^\[\]"; - // Set up the parameters for a MAIL search string - $MAILSearchString = $URLSearchString; - - // replace [observer.baseurl] - if ($observer) { - $s1 = ''; - $s2 = ''; - $obsBaseURL = $observer['xchan_connurl']; - $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL); - $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); - $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text); - $Text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $Text); - $Text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $Text); - $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text); - $Text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text); - $Text = str_replace('[observer.baseurl/]', $obsBaseURL, $Text); - $Text = str_replace('[observer.url/]',$observer['xchan_url'], $Text); - $Text = str_replace('[observer.name/]',$s1 . $observer['xchan_name'] . $s2, $Text); - $Text = str_replace('[observer.address/]',$s1 . $observer['xchan_addr'] . $s2, $Text); - $Text = str_replace('[observer.webname/]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text); - $Text = str_replace('[observer.photo/]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text); - } else { - $Text = str_replace('[observer.baseurl]', '', $Text); - $Text = str_replace('[observer.url]','', $Text); - $Text = str_replace('[observer.name]','', $Text); - $Text = str_replace('[observer.address]','', $Text); - $Text = str_replace('[observer.webname]','',$Text); - $Text = str_replace('[observer.photo]','', $Text); - $Text = str_replace('[observer.baseurl/]', '', $Text); - $Text = str_replace('[observer.url/]','', $Text); - $Text = str_replace('[observer.name/]','', $Text); - $Text = str_replace('[observer.address/]','', $Text); - $Text = str_replace('[observer.webname/]','',$Text); - $Text = str_replace('[observer.photo/]','', $Text); - } - - - - // Perform URL Search - - $urlchars = '[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]'; - - if (strpos($Text,'http') !== false) { - $Text = preg_replace("/([^\]\='".'"'."\;\/])(https?\:\/\/$urlchars+)/ismu", '$1$2', $Text); - } - - $count = 0; - while (strpos($Text,'[/share]') !== false && $count < 10) { - $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text); - $count ++; - } - - if (strpos($Text,'[/url]') !== false) { - $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $Text); - $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); - $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $Text); - $Text = preg_replace("/\@(\!?)\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '@$1$3', $Text); - $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); - } - - if (strpos($Text,'[/zrl]') !== false) { - // render hubzilla bookmarks as normal links - $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '$1', $Text); - $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $Text); - $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '$1', $Text); - $Text = preg_replace("/\@(\!?)\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '@$1$3', $Text); - $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $Text); - } - - // named anchors do not work well in conversational text, as it is often collapsed by a "showmore" script. - // Included here for completeness. - - if (strpos($Text,'[/anchor]') !== false) { - $Text = preg_replace("/\[anchor\](.*?)\[\/anchor\]/ism", '', $Text); - } - - if (strpos($Text,'[/goto]') !== false) { - $Text = preg_replace("/\[goto=(.*?)\](.*?)\[\/goto\]/ism", '$2', $Text); - } - - // Perform MAIL Search - if (strpos($Text,'[/mail]') !== false) { - $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $Text); - $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '$2', $Text); - } - - - // leave open the posibility of [map=something] - // this is replaced in prepare_body() which has knowledge of the item location - - if ($export) { - $Text = str_replace( [ '[map]','[/map]' ], [ '','' ] , $Text); - $Text = preg_replace("/\[map=(.*?)[, ](.*?)\]/ism", 'geo:$1,$2', $Text); - } - else { - if (strpos($Text,'[/map]') !== false) { - $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text); - } - if (strpos($Text,'[map=') !== false) { - $Text = preg_replace_callback("/\[map=(.*?)\/\]/ism", 'bb_map_coords', $Text); - $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text); - } - if (strpos($Text,'[map]') !== false) { - $Text = preg_replace("/\[map\/\]/", '
    ', $Text); - $Text = preg_replace("/\[map\]/", '
    ', $Text); - } - } - - // Check for bold text - if (strpos($Text,'[b]') !== false) { - $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '$1', $Text); - } - // Check for Italics text - if (strpos($Text,'[i]') !== false) { - $Text = preg_replace("(\[i\](.*?)\[\/i\])ism", '$1', $Text); - } - // Check for Underline text - if (strpos($Text,'[u]') !== false) { - $Text = preg_replace("(\[u\](.*?)\[\/u\])ism", '$1', $Text); - } - // Check for strike-through text - if (strpos($Text,'[s]') !== false) { - $Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '$1', $Text); - } - // Check for over-line text - if (strpos($Text,'[o]') !== false) { - $Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '$1', $Text); - } - if (strpos($Text,'[sup]') !== false) { - $Text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '$1', $Text); - } - if (strpos($Text,'[sub]') !== false) { - $Text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '$1', $Text); - } - - // Check for colored text - if (strpos($Text,'[/color]') !== false) { - $Text = preg_replace_callback("(\[color=(.*?)\](.*?)\[\/color\])ism", 'bb_colortag', $Text); - } - // Check for highlighted text - if (strpos($Text,'[/hl]') !== false) { - $Text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "$1", $Text); - $Text = preg_replace_callback("(\[mark=(.*?)\](.*?)\[\/mark\])ism", 'bb_hltag', $Text); - } - // Check for highlighted text - if (strpos($Text,'[/mark]') !== false) { - $Text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "$1", $Text); - $Text = preg_replace_callback("(\[mark=(.*?)\](.*?)\[\/mark\])ism", 'bb_hltag', $Text); - } - - // Check for sized text - // [size=50] --> font-size: 50px (with the unit). - if (strpos($Text,'[/size]') !== false) { - $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "$2", $Text); - $Text = preg_replace_callback("(\[size=(.*?)\](.*?)\[\/size\])ism", 'bb_sizetag', $Text); - } - // Check for h1 - if (strpos($Text,'[h1]') !== false) { - $Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'

    $1

    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - // Check for h2 - if (strpos($Text,'[h2]') !== false) { - $Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'

    $1

    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - // Check for h3 - if (strpos($Text,'[h3]') !== false) { - $Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'

    $1

    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - // Check for h4 - if (strpos($Text,'[h4]') !== false) { - $Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'

    $1

    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - // Check for h5 - if (strpos($Text,'[h5]') !== false) { - $Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'
    $1
    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - // Check for h6 - if (strpos($Text,'[h6]') !== false) { - $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'
    $1
    ',$Text); - $Text = str_replace('
    ', '', $Text); - } - - // Check for table of content without params - while(strpos($Text,'[toc]') !== false) { - $toc_id = 'toc-' . random_string(10); - $Text = preg_replace("/\[toc\]/ism", '
      ', $Text, 1); - $Text = preg_replace("/\[toc\/\]/ism", '
        ', $Text, 1); - } - // Check for table of content with params - while(strpos($Text,'[toc') !== false) { - $toc_id = 'toc-' . random_string(10); - $Text = preg_replace("/\[toc([^\]]+?)\/\]/ism", '
          ', $Text, 1); - $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '
            ', $Text, 1); - } - // Check for centered text - if (strpos($Text,'[/center]') !== false) { - $Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "
            $1
            ", $Text); - } - // Check for footer - if (strpos($Text,'[/footer]') !== false) { - $Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "
            $1
            ", $Text); - } - - // Check for bdi - if (strpos($Text,'[/bdi]') !== false) { - $Text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "$1", $Text); - } - - - // Check for list text - - $Text = preg_replace("/
            \[\*\]/ism","[*]",$Text); - $Text = str_replace("[*]", "
          • ", $Text); - - // handle nested lists - $endlessloop = 0; - - while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) || - ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) || - ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) || - ((strpos($Text, "[/dl]") !== false) && (strpos($Text, "[dl") !== false)) || - ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) { - $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '
              $1
            ', $Text); - $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '
              $1
            ', $Text); - $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '
              $1
            ', $Text); - $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'
              $2
            ', $Text); - $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '
              $2
            ', $Text); - $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '
              $2
            ', $Text); - $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '
              $2
            ', $Text); - $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '
              $1
            ', $Text); - $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '
              $1
            ', $Text); - $Text = preg_replace("/\[\/li\]
            \[li\]/ism",'[/li][li]',$Text); - $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '
          • $1
          • ', $Text); - - // [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large - // etc. style may be specified for the "terms" in the definition list. The quotation marks - // are also optional. The regex looks intimidating, but breaks down as: - // "[dl" "]" "[/dl]" - // where optional-termStyles are: "terms=" - $Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:"|")?([a-zA-Z]+)(?:"|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text); - - } - - // Friendica generates this - if (strpos($Text,'[/abstract]') !== false) { - $Text = preg_replace("/\[abstract\](.*?)\[\/abstract\]/ism", '

            $1

            ', $Text); - } - - if (strpos($Text,'[checklist]') !== false) { - $Text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $Text); - } - - - $loop = 0; - while (strpos($Text,'[/table]') !== false && strpos($Text,"[table") !== false && ++$loop < 20) { - $Text = preg_replace("/\[table\](.*?)\[\/table\]/ism", '$1
            ', $Text); - $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/ism", '$1
            ', $Text); - $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/ism", '$1
            ', $Text); - } - if (strpos($Text,'[th]') !== false) { - $Text = preg_replace("/\[th\](.*?)\[\/th\]/ism", '$1', $Text); - } - if (strpos($Text,'[td]') !== false) { - $Text = preg_replace("/\[td\](.*?)\[\/td\]/ism", '$1', $Text); - } - if (strpos($Text,'[tr]') !== false) { - $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/ism", '$1', $Text); - } - if (strpos($Text,'[tbody]') !== false) { - $Text = preg_replace("/\[tbody\](.*?)\[\/tbody\]/ism", '$1', $Text); - } - - - $Text = str_replace('
            ', "\n", $Text); - $Text = str_replace('[hr]', '
            ', $Text); - - // This is actually executed in prepare_body() - - $Text = str_replace('[nosmile]', '', $Text); - - // Check for font change text - if (strpos($Text,'[/font]') !== false) { - $Text = preg_replace_callback("/\[font=(.*?)\](.*?)\[\/font\]/sm", 'bb_fonttag', $Text); - } - - if(strpos($Text,'[/summary]') !== false) { - $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", 'bb_summary', $Text); - } - - // Check for [spoiler] text - $endlessloop = 0; - while ((strpos($Text, "[/spoiler]")!== false) && (strpos($Text, "[spoiler]") !== false) && (++$endlessloop < 20)) { - $Text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); - } - - // Check for [spoiler=Author] text - $endlessloop = 0; - while ((strpos($Text, "[/spoiler]")!== false) && (strpos($Text, "[spoiler=") !== false) && (++$endlessloop < 20)) { - $Text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); - } - - // Check for [open] text - $endlessloop = 0; - while ((strpos($Text, "[/open]")!== false) && (strpos($Text, "[open]") !== false) && (++$endlessloop < 20)) { - $Text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); - } - - // Check for [open=Title] text - $endlessloop = 0; - while ((strpos($Text, "[/open]")!== false) && (strpos($Text, "[open=") !== false) && (++$endlessloop < 20)) { - $Text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); - } - - - // Declare the format for [quote] layout - $QuoteLayout = '
            $1
            '; - - - // Check for [quote] text - // handle nested quotes - $endlessloop = 0; - while ((strpos($Text, "[/quote]") !== false) && (strpos($Text, "[quote]") !== false) && (++$endlessloop < 20)) - $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text); - - // Check for [quote=Author] text - - $t_wrote = t('$1 wrote:'); - - // handle nested quotes - $endlessloop = 0; - while ((strpos($Text, "[/quote]")!== false) && (strpos($Text, "[quote=") !== false) && (++$endlessloop < 20)) - $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", - "" . $t_wrote . "
            $2
            ", - $Text); - - if ($plain) { - $Text = str_replace([ '
            ','
            ' ], [ '“', '”' ], $Text); - } - - - // Images - - // [img]pathtoimage[/img] - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - // Friendica's modified bbcode img tags - $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } - - $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); - - if($censored) { - $Text = separate_img_links($Text); - $Text = preg_replace_callback("/\/ism","bb_colorbox",$Text); - } - - // style (sanitized) - if (strpos($Text,'[/style]') !== false) { - $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $Text); - } - - // crypt - if (strpos($Text,'[/crypt]') !== false) { - if ($activitypub) { - $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_b64_crypt', $Text); - } - else { - $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text); - } - } - - if (strpos($Text,'[/app]') !== false) { - if ($activitypub) { - $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app_ap', $Text); - } - else { - $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $Text); - } - } - - if(strpos($Text,'[/element]') !== false) { - $Text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $Text); - } - - // html5 video and audio - if (strpos($Text,'[/video]') !== false) { - $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text); - } - if (strpos($Text,'[/audio]') !== false) { - $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text); - } - if (strpos($Text,'[/zvideo]') !== false) { - $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text); - } - if (strpos($Text,'[/zaudio]') !== false) { - $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text); - } - - // if video couldn't be embedded, link to it instead. - if (strpos($Text,'[/video]') !== false) { - $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '$1', $Text); - } - if (strpos($Text,'[/audio]') !== false) { - $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '$1', $Text); - } - - if (strpos($Text,'[/zvideo]') !== false) { - $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '$1', $Text); - } - if (strpos($Text,'[/zaudio]') !== false) { - $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '$1', $Text); - } - - // SVG stuff - - if ($activitypub) { - $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg_export', $Text); - } - else { - $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $Text); - } - - // oembed tag - if(! $export) - $Text = oembed_bbcode2html($Text); - - // Avoid triple linefeeds through oembed - $Text = str_replace("


            ", "

            ", $Text); - - // If we found an event earlier, strip out all the event code and replace with a reformatted version. - // Replace the event-start section with the entire formatted event. The other bbcode is stripped. - // Summary (e.g. title) is required, earlier revisions only required description (in addition to - // start which is always required). Allow desc with a missing summary for compatibility. - - if ((x($ev,'desc') || x($ev,'summary')) && x($ev,'dtstart')) { - - $sub = format_event_html($ev); - - $sub = str_replace('$',"\0",$sub); - - $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text); - - $Text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$Text); - $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text); - $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text); - $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text); - $Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text); - $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text); - $Text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism",'',$Text); - $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text); - - $Text = str_replace("\0",'$',$Text); - - } - - // Unhide all [noparse] contained bbtags unspacefying them - // and triming the [noparse] tag. - if (strpos($Text,'[noparse]') !== false) { - $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); - } - if (strpos($Text,'[nobb]') !== false) { - $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text); - } - if (strpos($Text,'[pre]') !== false) { - $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); - } - - // replace escaped links in code= blocks - $Text = str_replace('%eY9-!','http', $Text); - $Text = bb_code_unprotect($Text); - - // This lets you use HTML entities in posts - just wrap them in brackets. For instance [©] to display a copyright symbol. - - $Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text); - - // fix any escaped ampersands that may have been converted into links - - if(strpos($Text,'&') !== false) - $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text); - - // This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where - // the scheme begins with z (zhttp), h (http(s)), f (ftp(s)), g (gemini), m (mailto|magnet), t (tel) and named anchors. - // data: urls are allowed if exporting to activitypub which allows inline svg to federate, but not - // to be used for local display - - if ($activitypub) { - $Text = preg_replace("/\<(.*?)(src|href)=\"[^dzghfmt#](.*?)\>/ism", '<$1$2="">', $Text); - } - else { - $Text = preg_replace("/\<(.*?)(src|href)=\"[^zhgfmt#](.*?)\>/ism", '<$1$2="">', $Text); - } - - $Text = bb_replace_images($Text, $saved_images); - - $args = [ 'text' => $Text, 'options' => $options ]; - call_hooks('bbcode', $args); - - return $args['text']; + // Quick but flawed fix for performance regression after purification + // was moved to rendering code to allow multiple code formats + // A proper fix would be to escape any code blocks before purification, + // restore them and store the resultant intermediate multicode. + // This is now accomplished using multicode_purify() + + // if (strpbrk($Text,'<>') !== false) { + // $Text = purify_html($Text, [ 'escape' ]); + // } + + // the bbcode tag 'nomd' will bypass markdown processing for any given text region + + $Text = preg_replace_callback('#\[nomd\](.*?)\[\/nomd\]#ism', 'md_protect', $Text); + + // and for completeness, there's 'nohtml' + + + $Text = preg_replace_callback('#\[nohtml\](.*?)\[\/nohtml\]#ism', 'html_protect', $Text); + + + // Perform some markdown conversions before translating linefeeds so as to keep the regexes manageable + // The preceding character check in bold/italic sequences is so we don't mistake underscore/asterisk in the middle of conversational text as an italic trigger. + + $Text = preg_replace_callback('#(^|\n| )(?$3
            ',$Text); + // markdown inline code blocks must be preceded by space or linebreak + $Text = preg_replace('#(^|\n| )(?$2', $Text); + // strip backslash escape for inline code + $Text = preg_replace('#(\\\)`#', '`', $Text); + $Text = preg_replace('#<\/code><\/pre>\n
            | .*?>)#', '
            ', $Text); + + // blockquotes + $Text = preg_replace('#^(>)+ +(.*?)$#m', '
            $2
            ', $Text); + $Text = preg_replace('#^(\>)+ +(.*?)$#m', '
            $2
            ', $Text); + $Text = preg_replace('#\n
            #', "\n", $Text); + + // links + $Text = preg_replace_callback('#!\[[^\]]*\]\((.*?)(?=\"|\))(\".*\")?\)(?!`)#', 'md_image', $Text); + $Text = preg_replace('#\[([^\[]+)\]\((?:javascript:)?([^\)]+)\)(?!`)#', '$1', $Text); + + // unordered lists + $Text = preg_replace('#^(?
          • $1
          • ', $Text); + // strip the backslash escape if present + $Text = preg_replace('#^(\\\)([*\-+]) #m', '$2', $Text); + // order lists + $Text = preg_replace('#^\d+[\.\)] +(.*?)$#m', '
            1. $1
            ', $Text); + + $Text = preg_replace('/\s*<\/(ol|ul)>\n+<\1>\s*/', "\n", $Text); + + $Text = bb_code_preunprotect($Text); + } + + + // Convert new line chars to html
            tags + + $Text = str_replace(array("\r", "\n"), array('
            ', '
            '), $Text); + $Text = str_replace(array("\t", " "), array("    ", "  "), $Text); + + // Check for [code] text + if (strpos($Text, '[code]') !== false) { + $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text); + } + + // Check for [code options] text + if (strpos($Text, '[code ') !== false) { + $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text); + } + + // Set up the parameters for a URL search string + $URLSearchString = "^\[\]"; + // Set up the parameters for a MAIL search string + $MAILSearchString = $URLSearchString; + + // replace [observer.baseurl] + if ($observer) { + $s1 = ''; + $s2 = ''; + $obsBaseURL = $observer['xchan_connurl']; + $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL); + $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); + $Text = str_replace('[observer.url]', $observer['xchan_url'], $Text); + $Text = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $Text); + $Text = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $Text); + $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $Text); + $Text = str_replace('[observer.photo]', $s1 . '[zmg]' . $observer['xchan_photo_l'] . '[/zmg]' . $s2, $Text); + $Text = str_replace('[observer.baseurl/]', $obsBaseURL, $Text); + $Text = str_replace('[observer.url/]', $observer['xchan_url'], $Text); + $Text = str_replace('[observer.name/]', $s1 . $observer['xchan_name'] . $s2, $Text); + $Text = str_replace('[observer.address/]', $s1 . $observer['xchan_addr'] . $s2, $Text); + $Text = str_replace('[observer.webname/]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $Text); + $Text = str_replace('[observer.photo/]', $s1 . '[zmg]' . $observer['xchan_photo_l'] . '[/zmg]' . $s2, $Text); + } else { + $Text = str_replace('[observer.baseurl]', '', $Text); + $Text = str_replace('[observer.url]', '', $Text); + $Text = str_replace('[observer.name]', '', $Text); + $Text = str_replace('[observer.address]', '', $Text); + $Text = str_replace('[observer.webname]', '', $Text); + $Text = str_replace('[observer.photo]', '', $Text); + $Text = str_replace('[observer.baseurl/]', '', $Text); + $Text = str_replace('[observer.url/]', '', $Text); + $Text = str_replace('[observer.name/]', '', $Text); + $Text = str_replace('[observer.address/]', '', $Text); + $Text = str_replace('[observer.webname/]', '', $Text); + $Text = str_replace('[observer.photo/]', '', $Text); + } + + + + // Perform URL Search + + $urlchars = '[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]'; + + if (strpos($Text, 'http') !== false) { + $Text = preg_replace("/([^\]\='" . '"' . "\;\/])(https?\:\/\/$urlchars+)/ismu", '$1$2', $Text); + } + + $count = 0; + while (strpos($Text, '[/share]') !== false && $count < 10) { + $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text); + $count++; + } + + if (strpos($Text, '[/url]') !== false) { + $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $Text); + $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); + $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $Text); + $Text = preg_replace("/\@(\!?)\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '@$1$3', $Text); + $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); + } + + if (strpos($Text, '[/zrl]') !== false) { + // render hubzilla bookmarks as normal links + $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '$1', $Text); + $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $Text); + $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '$1', $Text); + $Text = preg_replace("/\@(\!?)\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '@$1$3', $Text); + $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $Text); + } + + // named anchors do not work well in conversational text, as it is often collapsed by a "showmore" script. + // Included here for completeness. + + if (strpos($Text, '[/anchor]') !== false) { + $Text = preg_replace("/\[anchor\](.*?)\[\/anchor\]/ism", '', $Text); + } + + if (strpos($Text, '[/goto]') !== false) { + $Text = preg_replace("/\[goto=(.*?)\](.*?)\[\/goto\]/ism", '$2', $Text); + } + + // Perform MAIL Search + if (strpos($Text, '[/mail]') !== false) { + $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $Text); + $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '$2', $Text); + } + + + // leave open the posibility of [map=something] + // this is replaced in prepare_body() which has knowledge of the item location + + if ($export) { + $Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text); + $Text = preg_replace("/\[map=(.*?)[, ](.*?)\]/ism", 'geo:$1,$2', $Text); + } else { + if (strpos($Text, '[/map]') !== false) { + $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text); + } + if (strpos($Text, '[map=') !== false) { + $Text = preg_replace_callback("/\[map=(.*?)\/\]/ism", 'bb_map_coords', $Text); + $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text); + } + if (strpos($Text, '[map]') !== false) { + $Text = preg_replace("/\[map\/\]/", '
            ', $Text); + $Text = preg_replace("/\[map\]/", '
            ', $Text); + } + } + + // Check for bold text + if (strpos($Text, '[b]') !== false) { + $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '$1', $Text); + } + // Check for Italics text + if (strpos($Text, '[i]') !== false) { + $Text = preg_replace("(\[i\](.*?)\[\/i\])ism", '$1', $Text); + } + // Check for Underline text + if (strpos($Text, '[u]') !== false) { + $Text = preg_replace("(\[u\](.*?)\[\/u\])ism", '$1', $Text); + } + // Check for strike-through text + if (strpos($Text, '[s]') !== false) { + $Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '$1', $Text); + } + // Check for over-line text + if (strpos($Text, '[o]') !== false) { + $Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '$1', $Text); + } + if (strpos($Text, '[sup]') !== false) { + $Text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '$1', $Text); + } + if (strpos($Text, '[sub]') !== false) { + $Text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '$1', $Text); + } + + // Check for colored text + if (strpos($Text, '[/color]') !== false) { + $Text = preg_replace_callback("(\[color=(.*?)\](.*?)\[\/color\])ism", 'bb_colortag', $Text); + } + // Check for highlighted text + if (strpos($Text, '[/hl]') !== false) { + $Text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "$1", $Text); + $Text = preg_replace_callback("(\[mark=(.*?)\](.*?)\[\/mark\])ism", 'bb_hltag', $Text); + } + // Check for highlighted text + if (strpos($Text, '[/mark]') !== false) { + $Text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "$1", $Text); + $Text = preg_replace_callback("(\[mark=(.*?)\](.*?)\[\/mark\])ism", 'bb_hltag', $Text); + } + + // Check for sized text + // [size=50] --> font-size: 50px (with the unit). + if (strpos($Text, '[/size]') !== false) { + $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "$2", $Text); + $Text = preg_replace_callback("(\[size=(.*?)\](.*?)\[\/size\])ism", 'bb_sizetag', $Text); + } + // Check for h1 + if (strpos($Text, '[h1]') !== false) { + $Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism", '

            $1

            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + // Check for h2 + if (strpos($Text, '[h2]') !== false) { + $Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism", '

            $1

            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + // Check for h3 + if (strpos($Text, '[h3]') !== false) { + $Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism", '

            $1

            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + // Check for h4 + if (strpos($Text, '[h4]') !== false) { + $Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism", '

            $1

            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + // Check for h5 + if (strpos($Text, '[h5]') !== false) { + $Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism", '
            $1
            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + // Check for h6 + if (strpos($Text, '[h6]') !== false) { + $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism", '
            $1
            ', $Text); + $Text = str_replace('
            ', '', $Text); + } + + // Check for table of content without params + while (strpos($Text, '[toc]') !== false) { + $toc_id = 'toc-' . random_string(10); + $Text = preg_replace("/\[toc\]/ism", '
              ', $Text, 1); + $Text = preg_replace("/\[toc\/\]/ism", '
                ', $Text, 1); + } + // Check for table of content with params + while (strpos($Text, '[toc') !== false) { + $toc_id = 'toc-' . random_string(10); + $Text = preg_replace("/\[toc([^\]]+?)\/\]/ism", '
                  ', $Text, 1); + $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '
                    ', $Text, 1); + } + // Check for centered text + if (strpos($Text, '[/center]') !== false) { + $Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "
                    $1
                    ", $Text); + } + // Check for footer + if (strpos($Text, '[/footer]') !== false) { + $Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "
                    $1
                    ", $Text); + } + + // Check for bdi + if (strpos($Text, '[/bdi]') !== false) { + $Text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "$1", $Text); + } + + + // Check for list text + + $Text = preg_replace("/
                    \[\*\]/ism", "[*]", $Text); + $Text = str_replace("[*]", "
                  • ", $Text); + + // handle nested lists + $endlessloop = 0; + + while ( + (((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) || + ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) || + ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) || + ((strpos($Text, "[/dl]") !== false) && (strpos($Text, "[dl") !== false)) || + ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20) + ) { + $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '
                      $1
                    ', $Text); + $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '
                      $1
                    ', $Text); + $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '
                      $1
                    ', $Text); + $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism", '
                      $2
                    ', $Text); + $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '
                      $2
                    ', $Text); + $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '
                      $2
                    ', $Text); + $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '
                      $2
                    ', $Text); + $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '
                      $1
                    ', $Text); + $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '
                      $1
                    ', $Text); + $Text = preg_replace("/\[\/li\]
                    \[li\]/ism", '[/li][li]', $Text); + $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '
                  • $1
                  • ', $Text); + + // [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large + // etc. style may be specified for the "terms" in the definition list. The quotation marks + // are also optional. The regex looks intimidating, but breaks down as: + // "[dl" "]" "[/dl]" + // where optional-termStyles are: "terms=" + $Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:"|")?([a-zA-Z]+)(?:"|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text); + } + + // Friendica generates this + if (strpos($Text, '[/abstract]') !== false) { + $Text = preg_replace("/\[abstract\](.*?)\[\/abstract\]/ism", '

                    $1

                    ', $Text); + } + + if (strpos($Text, '[checklist]') !== false) { + $Text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $Text); + } + + + $loop = 0; + while (strpos($Text, '[/table]') !== false && strpos($Text, "[table") !== false && ++$loop < 20) { + $Text = preg_replace("/\[table\](.*?)\[\/table\]/ism", '$1
                    ', $Text); + $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/ism", '$1
                    ', $Text); + $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/ism", '$1
                    ', $Text); + } + if (strpos($Text, '[th]') !== false) { + $Text = preg_replace("/\[th\](.*?)\[\/th\]/ism", '$1', $Text); + } + if (strpos($Text, '[td]') !== false) { + $Text = preg_replace("/\[td\](.*?)\[\/td\]/ism", '$1', $Text); + } + if (strpos($Text, '[tr]') !== false) { + $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/ism", '$1', $Text); + } + if (strpos($Text, '[tbody]') !== false) { + $Text = preg_replace("/\[tbody\](.*?)\[\/tbody\]/ism", '$1', $Text); + } + + + $Text = str_replace('
                    ', "\n", $Text); + $Text = str_replace('[hr]', '
                    ', $Text); + + // This is actually executed in prepare_body() + + $Text = str_replace('[nosmile]', '', $Text); + + // Check for font change text + if (strpos($Text, '[/font]') !== false) { + $Text = preg_replace_callback("/\[font=(.*?)\](.*?)\[\/font\]/sm", 'bb_fonttag', $Text); + } + + if (strpos($Text, '[/summary]') !== false) { + $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", 'bb_summary', $Text); + } + + // Check for [spoiler] text + $endlessloop = 0; + while ((strpos($Text, "[/spoiler]") !== false) && (strpos($Text, "[spoiler]") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); + } + + // Check for [spoiler=Author] text + $endlessloop = 0; + while ((strpos($Text, "[/spoiler]") !== false) && (strpos($Text, "[spoiler=") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); + } + + // Check for [open] text + $endlessloop = 0; + while ((strpos($Text, "[/open]") !== false) && (strpos($Text, "[open]") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); + } + + // Check for [open=Title] text + $endlessloop = 0; + while ((strpos($Text, "[/open]") !== false) && (strpos($Text, "[open=") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); + } + + + // Declare the format for [quote] layout + $QuoteLayout = '
                    $1
                    '; + + + // Check for [quote] text + // handle nested quotes + $endlessloop = 0; + while ((strpos($Text, "[/quote]") !== false) && (strpos($Text, "[quote]") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text); + } + + // Check for [quote=Author] text + + $t_wrote = t('$1 wrote:'); + + // handle nested quotes + $endlessloop = 0; + while ((strpos($Text, "[/quote]") !== false) && (strpos($Text, "[quote=") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace( + "/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", + "" . $t_wrote . "
                    $2
                    ", + $Text + ); + } + + if ($plain) { + $Text = str_replace([ '
                    ','
                    ' ], [ '“', '”' ], $Text); + } + + + // Images + + // [img]pathtoimage[/img] + if (strpos($Text, '[/img]') !== false) { + $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); + // Friendica's modified bbcode img tags + $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); + } + if (strpos($Text, '[/zmg]') !== false) { + $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); + } + + $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism", 'bb_imgoptions', $Text); + + if ($censored) { + $Text = separate_img_links($Text); + $Text = preg_replace_callback("/\/ism", "bb_colorbox", $Text); + } + + // style (sanitized) + if (strpos($Text, '[/style]') !== false) { + $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $Text); + } + + // crypt + if (strpos($Text, '[/crypt]') !== false) { + if ($activitypub) { + $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_b64_crypt', $Text); + } else { + $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text); + } + } + + if (strpos($Text, '[/app]') !== false) { + if ($activitypub) { + $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism", 'bb_parse_app_ap', $Text); + } else { + $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism", 'bb_parse_app', $Text); + } + } + + if (strpos($Text, '[/element]') !== false) { + $Text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism", 'bb_parse_element', $Text); + } + + // html5 video and audio + if (strpos($Text, '[/video]') !== false) { + $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text); + } + if (strpos($Text, '[/audio]') !== false) { + $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text); + } + if (strpos($Text, '[/zvideo]') !== false) { + $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text); + } + if (strpos($Text, '[/zaudio]') !== false) { + $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text); + } + + // if video couldn't be embedded, link to it instead. + if (strpos($Text, '[/video]') !== false) { + $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '$1', $Text); + } + if (strpos($Text, '[/audio]') !== false) { + $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '$1', $Text); + } + + if (strpos($Text, '[/zvideo]') !== false) { + $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '$1', $Text); + } + if (strpos($Text, '[/zaudio]') !== false) { + $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '$1', $Text); + } + + // SVG stuff + + if ($activitypub) { + $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg_export', $Text); + } else { + $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $Text); + } + + // oembed tag + if (! $export) { + $Text = oembed_bbcode2html($Text); + } + + // Avoid triple linefeeds through oembed + $Text = str_replace("


                    ", "

                    ", $Text); + + // If we found an event earlier, strip out all the event code and replace with a reformatted version. + // Replace the event-start section with the entire formatted event. The other bbcode is stripped. + // Summary (e.g. title) is required, earlier revisions only required description (in addition to + // start which is always required). Allow desc with a missing summary for compatibility. + + if ((x($ev, 'desc') || x($ev, 'summary')) && x($ev, 'dtstart')) { + $sub = format_event_html($ev); + + $sub = str_replace('$', "\0", $sub); + + $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism", $sub, $Text); + + $Text = preg_replace("/\[event\](.*?)\[\/event\]/ism", '', $Text); + $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism", '', $Text); + $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism", '', $Text); + $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism", '', $Text); + $Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism", '', $Text); + $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism", '', $Text); + $Text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism", '', $Text); + $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism", '', $Text); + + $Text = str_replace("\0", '$', $Text); + } + + // Unhide all [noparse] contained bbtags unspacefying them + // and triming the [noparse] tag. + if (strpos($Text, '[noparse]') !== false) { + $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); + } + if (strpos($Text, '[nobb]') !== false) { + $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text); + } + if (strpos($Text, '[pre]') !== false) { + $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); + } + + // replace escaped links in code= blocks + $Text = str_replace('%eY9-!', 'http', $Text); + $Text = bb_code_unprotect($Text); + + // This lets you use HTML entities in posts - just wrap them in brackets. For instance [©] to display a copyright symbol. + + $Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text); + + // fix any escaped ampersands that may have been converted into links + + if (strpos($Text, '&') !== false) { + $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text); + } + + // This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where + // the scheme begins with z (zhttp), h (http(s)), f (ftp(s)), g (gemini), m (mailto|magnet), t (tel) and named anchors. + // data: urls are allowed if exporting to activitypub which allows inline svg to federate, but not + // to be used for local display + + if ($activitypub) { + $Text = preg_replace("/\<(.*?)(src|href)=\"[^dzghfmt#](.*?)\>/ism", '<$1$2="">', $Text); + } else { + $Text = preg_replace("/\<(.*?)(src|href)=\"[^zhgfmt#](.*?)\>/ism", '<$1$2="">', $Text); + } + + $Text = bb_replace_images($Text, $saved_images); + + $args = [ 'text' => $Text, 'options' => $options ]; + call_hooks('bbcode', $args); + + return $args['text']; } - diff --git a/include/channel.php b/include/channel.php index 05d92ffe8..04611f685 100644 --- a/include/channel.php +++ b/include/channel.php @@ -1,10 +1,10 @@ false, 'message' => ''); +function identity_check_service_class($account_id) +{ + $ret = array('success' => false, 'message' => ''); - $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ", - intval($account_id) - ); - if(! ($r && count($r))) { - $ret['total_identities'] = 0; - $ret['message'] = t('Unable to obtain identity information from database'); - return $ret; - } + $r = q( + "select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ", + intval($account_id) + ); + if (! ($r && count($r))) { + $ret['total_identities'] = 0; + $ret['message'] = t('Unable to obtain identity information from database'); + return $ret; + } - $ret['total_identities'] = intval($r[0]['total']); + $ret['total_identities'] = intval($r[0]['total']); - if (! account_service_class_allows($account_id, 'total_identities', $r[0]['total'])) { - $ret['message'] .= upgrade_message(); - return $ret; - } + if (! account_service_class_allows($account_id, 'total_identities', $r[0]['total'])) { + $ret['message'] .= upgrade_message(); + return $ret; + } - $ret['success'] = true; + $ret['success'] = true; - return $ret; + return $ret; } @@ -74,25 +76,29 @@ function identity_check_service_class($account_id) { * @param string $name * @return string describing the error state, or nil return if name is valid */ -function validate_channelname($name) { +function validate_channelname($name) +{ - if (! $name) - return t('Empty name'); + if (! $name) { + return t('Empty name'); + } - if (mb_strlen($name) > 191) - return t('Name too long'); + if (mb_strlen($name) > 191) { + return t('Name too long'); + } - $arr = ['name' => $name]; - /** - * @hooks validate_channelname - * Used to validate the names used by a channel. - * * \e string \b name - * * \e string \b message - return error message - */ - call_hooks('validate_channelname', $arr); + $arr = ['name' => $name]; + /** + * @hooks validate_channelname + * Used to validate the names used by a channel. + * * \e string \b name + * * \e string \b message - return error message + */ + call_hooks('validate_channelname', $arr); - if (x($arr, 'message')) - return $arr['message']; + if (x($arr, 'message')) { + return $arr['message']; + } } @@ -100,78 +106,83 @@ function validate_channelname($name) { * @brief Create a system channel - which has no account attached. * */ -function create_sys_channel() { +function create_sys_channel() +{ - // Ensure that there is a host keypair. + // Ensure that there is a host keypair. - if ((! get_config('system', 'pubkey')) || (! get_config('system', 'prvkey'))) { - $hostkey = Crypto::new_keypair(4096); - set_config('system', 'pubkey', $hostkey['pubkey']); - set_config('system', 'prvkey', $hostkey['prvkey']); - } + if ((! get_config('system', 'pubkey')) || (! get_config('system', 'prvkey'))) { + $hostkey = Crypto::new_keypair(4096); + set_config('system', 'pubkey', $hostkey['pubkey']); + set_config('system', 'prvkey', $hostkey['prvkey']); + } - $sys = get_sys_channel(); + $sys = get_sys_channel(); - if ($sys) { - if (isset($sys['channel_pubkey']) && $sys['channel_pubkey'] && $sys['channel_pubkey'] === get_config('system','pubkey')) { - return; - } - else { - // upgrade the sys channel and return - $pubkey = get_config('system','pubkey'); - $prvkey = get_config('system','prvkey'); - $guid_sig = Libzot::sign($sys['channel_guid'],$prvkey); - $hash = Libzot::make_xchan_hash($sys['channel_guid'],$pubkey); + if ($sys) { + if (isset($sys['channel_pubkey']) && $sys['channel_pubkey'] && $sys['channel_pubkey'] === get_config('system', 'pubkey')) { + return; + } else { + // upgrade the sys channel and return + $pubkey = get_config('system', 'pubkey'); + $prvkey = get_config('system', 'prvkey'); + $guid_sig = Libzot::sign($sys['channel_guid'], $prvkey); + $hash = Libzot::make_xchan_hash($sys['channel_guid'], $pubkey); - q("update channel set channel_guid_sig = '%s', channel_hash = '%s', channel_pubkey = '%s', channel_prvkey = '%s' where channel_id = %d", - dbesc($guid_sig), - dbesc($hash), - dbesc($pubkey), - dbesc($prvkey), - dbesc($sys['channel_id']) - ); + q( + "update channel set channel_guid_sig = '%s', channel_hash = '%s', channel_pubkey = '%s', channel_prvkey = '%s' where channel_id = %d", + dbesc($guid_sig), + dbesc($hash), + dbesc($pubkey), + dbesc($prvkey), + dbesc($sys['channel_id']) + ); - q("update xchan set xchan_guid_sig = '%s', xchan_hash = '%s', xchan_pubkey = '%s', xchan_url = '%s' where xchan_hash = '%s'", - dbesc($guid_sig), - dbesc($hash), - dbesc($pubkey), - dbesc(z_root()), - dbesc($sys['channel_hash']) - ); - q("update hubloc set hubloc_guid_sig = '%s', hubloc_hash = '%s', hubloc_id_url = '%s', hubloc_url_sig = '%s', hubloc_url = '%s', hubloc_callback = '%s', hubloc_site_id = '%s', hubloc_orphancheck = 0, hubloc_error = 0, hubloc_deleted = 0 where hubloc_hash = '%s'", - dbesc($guid_sig), - dbesc($hash), - dbesc(z_root()), - dbesc(Libzot::sign(z_root(),$prvkey)), - dbesc(z_root()), - dbesc(z_root() . '/zot'), - dbesc(Libzot::make_xchan_hash(z_root(),$pubkey)), - dbesc($sys['channel_hash']) - ); + q( + "update xchan set xchan_guid_sig = '%s', xchan_hash = '%s', xchan_pubkey = '%s', xchan_url = '%s' where xchan_hash = '%s'", + dbesc($guid_sig), + dbesc($hash), + dbesc($pubkey), + dbesc(z_root()), + dbesc($sys['channel_hash']) + ); + q( + "update hubloc set hubloc_guid_sig = '%s', hubloc_hash = '%s', hubloc_id_url = '%s', hubloc_url_sig = '%s', hubloc_url = '%s', hubloc_callback = '%s', hubloc_site_id = '%s', hubloc_orphancheck = 0, hubloc_error = 0, hubloc_deleted = 0 where hubloc_hash = '%s'", + dbesc($guid_sig), + dbesc($hash), + dbesc(z_root()), + dbesc(Libzot::sign(z_root(), $prvkey)), + dbesc(z_root()), + dbesc(z_root() . '/zot'), + dbesc(Libzot::make_xchan_hash(z_root(), $pubkey)), + dbesc($sys['channel_hash']) + ); - q("update abook set abook_xchan = '%s' where abook_xchan = '%s'", - dbesc($hash), - dbesc($sys['channel_hash']) - ); + q( + "update abook set abook_xchan = '%s' where abook_xchan = '%s'", + dbesc($hash), + dbesc($sys['channel_hash']) + ); - q("update abconfig set xchan = '%s' where xchan = '%s'", - dbesc($hash), - dbesc($sys['channel_hash']) - ); + q( + "update abconfig set xchan = '%s' where xchan = '%s'", + dbesc($hash), + dbesc($sys['channel_hash']) + ); - return; - } - } + return; + } + } - create_identity([ - 'account_id' => 'xxx', // Typecast trickery: account_id is required. This will create an identity with an (integer) account_id of 0 - 'nickname' => 'sys', - 'name' => 'System', - 'permissions_role' => 'social', - 'pageflags' => 0, - 'publish' => 0, - 'system' => 1 - ]); + create_identity([ + 'account_id' => 'xxx', // Typecast trickery: account_id is required. This will create an identity with an (integer) account_id of 0 + 'nickname' => 'sys', + 'name' => 'System', + 'permissions_role' => 'social', + 'pageflags' => 0, + 'publish' => 0, + 'system' => 1 + ]); } @@ -180,21 +191,22 @@ function create_sys_channel() { * * @return array|bool */ -function get_sys_channel() { +function get_sys_channel() +{ - // App::$sys_channel caches this lookup - - if (is_array(App::$sys_channel)) { - return App::$sys_channel; - } - - $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1"); + // App::$sys_channel caches this lookup - if ($r) { - App::$sys_channel = array_shift($r); - return App::$sys_channel; - } - return false; + if (is_array(App::$sys_channel)) { + return App::$sys_channel; + } + + $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1"); + + if ($r) { + App::$sys_channel = array_shift($r); + return App::$sys_channel; + } + return false; } @@ -204,12 +216,13 @@ function get_sys_channel() { * @param int $channel_id * @return bool */ -function is_sys_channel($channel_id) { - $s = get_sys_channel(); - if ($s) { - return (intval($s['channel_id']) === intval($channel_id)); - } - return false; +function is_sys_channel($channel_id) +{ + $s = get_sys_channel(); + if ($s) { + return (intval($s['channel_id']) === intval($channel_id)); + } + return false; } @@ -221,13 +234,15 @@ function is_sys_channel($channel_id) { * @returns int|booleean * on error returns boolean false */ -function channel_total() { - $r = q("select channel_id from channel where channel_removed = 0"); +function channel_total() +{ + $r = q("select channel_id from channel where channel_removed = 0"); - if (is_array($r)) - return count($r); + if (is_array($r)) { + return count($r); + } - return false; + return false; } @@ -248,544 +263,571 @@ function channel_total() { * 'message' => optional error text if success is false * 'channel' => if successful the created channel array */ -function create_identity($arr) { +function create_identity($arr) +{ - $ret = array('success' => false); + $ret = array('success' => false); - if(! $arr['account_id']) { - $ret['message'] = t('No account identifier'); - return $ret; - } - $ret = identity_check_service_class($arr['account_id']); - if (!$ret['success']) { - return $ret; - } - // save this for auto_friending - $total_identities = $ret['total_identities']; + if (! $arr['account_id']) { + $ret['message'] = t('No account identifier'); + return $ret; + } + $ret = identity_check_service_class($arr['account_id']); + if (!$ret['success']) { + return $ret; + } + // save this for auto_friending + $total_identities = $ret['total_identities']; - $nick = mb_strtolower(trim($arr['nickname'])); - if(! $nick) { - $ret['message'] = t('Nickname is required.'); - return $ret; - } + $nick = mb_strtolower(trim($arr['nickname'])); + if (! $nick) { + $ret['message'] = t('Nickname is required.'); + return $ret; + } - $name = escape_tags($arr['name']); - $pageflags = ((x($arr,'pageflags')) ? intval($arr['pageflags']) : PAGE_NORMAL); - $system = ((x($arr,'system')) ? intval($arr['system']) : 0); - $name_error = validate_channelname($arr['name']); - if($name_error) { - $ret['message'] = $name_error; - return $ret; - } + $name = escape_tags($arr['name']); + $pageflags = ((x($arr, 'pageflags')) ? intval($arr['pageflags']) : PAGE_NORMAL); + $system = ((x($arr, 'system')) ? intval($arr['system']) : 0); + $name_error = validate_channelname($arr['name']); + if ($name_error) { + $ret['message'] = $name_error; + return $ret; + } - if($nick === 'sys' && (! $system)) { - $ret['message'] = t('Reserved nickname. Please choose another.'); - return $ret; - } + if ($nick === 'sys' && (! $system)) { + $ret['message'] = t('Reserved nickname. Please choose another.'); + return $ret; + } - if(check_webbie(array($nick)) !== $nick) { - $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); - return $ret; - } + if (check_webbie(array($nick)) !== $nick) { + $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); + return $ret; + } - $guid = Libzot::new_uid($nick); + $guid = Libzot::new_uid($nick); - if ($system) { - $key = [ 'pubkey' => get_config('system','pubkey'), 'prvkey' => get_config('system','prvkey') ]; - } - else { - $key = Crypto::new_keypair(4096); - } - - $sig = Libzot::sign($guid,$key['prvkey']); - $hash = Libzot::make_xchan_hash($guid,$key['pubkey']); + if ($system) { + $key = [ 'pubkey' => get_config('system', 'pubkey'), 'prvkey' => get_config('system', 'prvkey') ]; + } else { + $key = Crypto::new_keypair(4096); + } - // Force a few things on the short term until we can provide a theme or app with choice + $sig = Libzot::sign($guid, $key['prvkey']); + $hash = Libzot::make_xchan_hash($guid, $key['pubkey']); - $publish = 1; + // Force a few things on the short term until we can provide a theme or app with choice - if(array_key_exists('publish', $arr)) - $publish = intval($arr['publish']); + $publish = 1; - $role_permissions = null; - $parent_channel_hash = EMPTY_STR; + if (array_key_exists('publish', $arr)) { + $publish = intval($arr['publish']); + } - if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) { - $role_permissions = PermissionRoles::role_perms($arr['permissions_role']); - if(isset($role_permissions['channel_type']) && $role_permissions['channel_type'] === 'collection') { - $parent_channel_hash = $arr['parent_hash']; - } - } + $role_permissions = null; + $parent_channel_hash = EMPTY_STR; - if($role_permissions && array_key_exists('directory_publish',$role_permissions)) - $publish = intval($role_permissions['directory_publish']); + if (array_key_exists('permissions_role', $arr) && $arr['permissions_role']) { + $role_permissions = PermissionRoles::role_perms($arr['permissions_role']); + if (isset($role_permissions['channel_type']) && $role_permissions['channel_type'] === 'collection') { + $parent_channel_hash = $arr['parent_hash']; + } + } - $primary = true; + if ($role_permissions && array_key_exists('directory_publish', $role_permissions)) { + $publish = intval($role_permissions['directory_publish']); + } - if(array_key_exists('primary', $arr)) - $primary = intval($arr['primary']); + $primary = true; - $expire = 0; + if (array_key_exists('primary', $arr)) { + $primary = intval($arr['primary']); + } - $r = channel_store_lowlevel( - [ - 'channel_account_id' => intval($arr['account_id']), - 'channel_primary' => intval($primary), - 'channel_name' => $name, - 'channel_parent' => $parent_channel_hash, - 'channel_address' => $nick, - 'channel_guid' => $guid, - 'channel_guid_sig' => $sig, - 'channel_hash' => $hash, - 'channel_prvkey' => $key['prvkey'], - 'channel_pubkey' => $key['pubkey'], - 'channel_pageflags' => intval($pageflags), - 'channel_system' => intval($system), - 'channel_expire_days' => intval($expire), - 'channel_timezone' => App::$timezone - ] - ); + $expire = 0; - $r = q("select * from channel where channel_account_id = %d + $r = channel_store_lowlevel( + [ + 'channel_account_id' => intval($arr['account_id']), + 'channel_primary' => intval($primary), + 'channel_name' => $name, + 'channel_parent' => $parent_channel_hash, + 'channel_address' => $nick, + 'channel_guid' => $guid, + 'channel_guid_sig' => $sig, + 'channel_hash' => $hash, + 'channel_prvkey' => $key['prvkey'], + 'channel_pubkey' => $key['pubkey'], + 'channel_pageflags' => intval($pageflags), + 'channel_system' => intval($system), + 'channel_expire_days' => intval($expire), + 'channel_timezone' => App::$timezone + ] + ); + + $r = q( + "select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", - intval($arr['account_id']), - dbesc($guid) - ); + intval($arr['account_id']), + dbesc($guid) + ); - if(! $r) { - $ret['message'] = t('Unable to retrieve created identity'); - return $ret; - } + if (! $r) { + $ret['message'] = t('Unable to retrieve created identity'); + return $ret; + } - $a = q("select * from account where account_id = %d", - intval($arr['account_id']) - ); + $a = q( + "select * from account where account_id = %d", + intval($arr['account_id']) + ); - $photo_type = null; + $photo_type = null; - $z = [ - 'account' => $a[0], - 'channel' => $r[0], - 'photo_url' => '' - ]; - /** - * @hooks create_channel_photo - * * \e array \b account - * * \e array \b channel - * * \e string \b photo_url - Return value - */ - call_hooks('create_channel_photo', $z); + $z = [ + 'account' => $a[0], + 'channel' => $r[0], + 'photo_url' => '' + ]; + /** + * @hooks create_channel_photo + * * \e array \b account + * * \e array \b channel + * * \e string \b photo_url - Return value + */ + call_hooks('create_channel_photo', $z); - if($z['photo_url']) { - $photo_type = import_channel_photo_from_url($z['photo_url'],$arr['account_id'],$r[0]['channel_id']); - } + if ($z['photo_url']) { + $photo_type = import_channel_photo_from_url($z['photo_url'], $arr['account_id'], $r[0]['channel_id']); + } - if($role_permissions && array_key_exists('limits',$role_permissions)) - $perm_limits = $role_permissions['limits']; - else - $perm_limits = site_default_perms(); + if ($role_permissions && array_key_exists('limits', $role_permissions)) { + $perm_limits = $role_permissions['limits']; + } else { + $perm_limits = site_default_perms(); + } - foreach($perm_limits as $p => $v) - PermissionLimits::Set($r[0]['channel_id'],$p,$v); + foreach ($perm_limits as $p => $v) { + PermissionLimits::Set($r[0]['channel_id'], $p, $v); + } - if($role_permissions && array_key_exists('perms_auto',$role_permissions)) - set_pconfig($r[0]['channel_id'],'system','autoperms',intval($role_permissions['perms_auto'])); + if ($role_permissions && array_key_exists('perms_auto', $role_permissions)) { + set_pconfig($r[0]['channel_id'], 'system', 'autoperms', intval($role_permissions['perms_auto'])); + } - $ret['channel'] = $r[0]; + $ret['channel'] = $r[0]; - if(intval($arr['account_id'])) - set_default_login_identity($arr['account_id'],$ret['channel']['channel_id'],false); + if (intval($arr['account_id'])) { + set_default_login_identity($arr['account_id'], $ret['channel']['channel_id'], false); + } - // Create a verified hub location pointing to this site. + // Create a verified hub location pointing to this site. - $r = hubloc_store_lowlevel( - [ - 'hubloc_guid' => $guid, - 'hubloc_guid_sig' => $sig, - 'hubloc_id_url' => (($system) ? z_root() : channel_url($ret['channel'])), - 'hubloc_hash' => $hash, - 'hubloc_addr' => channel_reddress($ret['channel']), - 'hubloc_primary' => intval($primary), - 'hubloc_url' => z_root(), - 'hubloc_url_sig' => Libzot::sign(z_root(),$ret['channel']['channel_prvkey']), - 'hubloc_site_id' => Libzot::make_xchan_hash(z_root(),get_config('system','pubkey')), - 'hubloc_host' => App::get_hostname(), - 'hubloc_callback' => z_root() . '/zot', - 'hubloc_sitekey' => get_config('system','pubkey'), - 'hubloc_network' => 'zot6', - 'hubloc_updated' => datetime_convert() - ] - ); - if(! $r) - logger('Unable to store hub location'); + $r = hubloc_store_lowlevel( + [ + 'hubloc_guid' => $guid, + 'hubloc_guid_sig' => $sig, + 'hubloc_id_url' => (($system) ? z_root() : channel_url($ret['channel'])), + 'hubloc_hash' => $hash, + 'hubloc_addr' => channel_reddress($ret['channel']), + 'hubloc_primary' => intval($primary), + 'hubloc_url' => z_root(), + 'hubloc_url_sig' => Libzot::sign(z_root(), $ret['channel']['channel_prvkey']), + 'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), get_config('system', 'pubkey')), + 'hubloc_host' => App::get_hostname(), + 'hubloc_callback' => z_root() . '/zot', + 'hubloc_sitekey' => get_config('system', 'pubkey'), + 'hubloc_network' => 'zot6', + 'hubloc_updated' => datetime_convert() + ] + ); + if (! $r) { + logger('Unable to store hub location'); + } - $newuid = $ret['channel']['channel_id']; + $newuid = $ret['channel']['channel_id']; - $r = xchan_store_lowlevel( - [ - 'xchan_hash' => $hash, - 'xchan_guid' => $guid, - 'xchan_guid_sig' => $sig, - 'xchan_pubkey' => $key['pubkey'], - 'xchan_photo_mimetype' => (($photo_type) ? $photo_type : 'image/png'), - 'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}", - 'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}", - 'xchan_photo_s' => z_root() . "/photo/profile/s/{$newuid}", - 'xchan_addr' => channel_reddress($ret['channel']), - 'xchan_url' => (($system) ? z_root() : channel_url($ret['channel'])), - 'xchan_follow' => z_root() . '/follow?f=&url=%s', - 'xchan_connurl' => z_root() . '/poco/' . $ret['channel']['channel_address'], - 'xchan_name' => $ret['channel']['channel_name'], - 'xchan_network' => 'zot6', - 'xchan_updated' => datetime_convert(), - 'xchan_photo_date' => datetime_convert(), - 'xchan_name_date' => datetime_convert(), - 'xchan_system' => $system - ] - ); + $r = xchan_store_lowlevel( + [ + 'xchan_hash' => $hash, + 'xchan_guid' => $guid, + 'xchan_guid_sig' => $sig, + 'xchan_pubkey' => $key['pubkey'], + 'xchan_photo_mimetype' => (($photo_type) ? $photo_type : 'image/png'), + 'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}", + 'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}", + 'xchan_photo_s' => z_root() . "/photo/profile/s/{$newuid}", + 'xchan_addr' => channel_reddress($ret['channel']), + 'xchan_url' => (($system) ? z_root() : channel_url($ret['channel'])), + 'xchan_follow' => z_root() . '/follow?f=&url=%s', + 'xchan_connurl' => z_root() . '/poco/' . $ret['channel']['channel_address'], + 'xchan_name' => $ret['channel']['channel_name'], + 'xchan_network' => 'zot6', + 'xchan_updated' => datetime_convert(), + 'xchan_photo_date' => datetime_convert(), + 'xchan_name_date' => datetime_convert(), + 'xchan_system' => $system + ] + ); - // Not checking return value. - // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate + // Not checking return value. + // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate - $r = profile_store_lowlevel( - [ - 'aid' => intval($ret['channel']['channel_account_id']), - 'uid' => intval($newuid), - 'profile_guid' => new_uuid(), - 'profile_name' => t('Default Profile'), - 'is_default' => 1, - 'publish' => $publish, - 'fullname' => $ret['channel']['channel_name'], - 'photo' => z_root() . "/photo/profile/l/{$newuid}", - 'thumb' => z_root() . "/photo/profile/m/{$newuid}" - ] - ); + $r = profile_store_lowlevel( + [ + 'aid' => intval($ret['channel']['channel_account_id']), + 'uid' => intval($newuid), + 'profile_guid' => new_uuid(), + 'profile_name' => t('Default Profile'), + 'is_default' => 1, + 'publish' => $publish, + 'fullname' => $ret['channel']['channel_name'], + 'photo' => z_root() . "/photo/profile/l/{$newuid}", + 'thumb' => z_root() . "/photo/profile/m/{$newuid}" + ] + ); - if($role_permissions) { - $myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : [] ); - } - else { - $x = PermissionRoles::role_perms('social'); - $myperms = $x['perms_connect']; - } + if ($role_permissions) { + $myperms = ((array_key_exists('perms_connect', $role_permissions)) ? $role_permissions['perms_connect'] : [] ); + } else { + $x = PermissionRoles::role_perms('social'); + $myperms = $x['perms_connect']; + } - $r = abook_store_lowlevel( - [ - 'abook_account' => intval($ret['channel']['channel_account_id']), - 'abook_channel' => intval($newuid), - 'abook_xchan' => $hash, - 'abook_closeness' => 0, - 'abook_created' => datetime_convert(), - 'abook_updated' => datetime_convert(), - 'abook_self' => 1 - ] - ); + $r = abook_store_lowlevel( + [ + 'abook_account' => intval($ret['channel']['channel_account_id']), + 'abook_channel' => intval($newuid), + 'abook_xchan' => $hash, + 'abook_closeness' => 0, + 'abook_created' => datetime_convert(), + 'abook_updated' => datetime_convert(), + 'abook_self' => 1 + ] + ); - $x = Permissions::serialise(Permissions::FilledPerms($myperms)); - set_abconfig($newuid,$hash,'system','my_perms',$x); + $x = Permissions::serialise(Permissions::FilledPerms($myperms)); + set_abconfig($newuid, $hash, 'system', 'my_perms', $x); - if(intval($ret['channel']['channel_account_id'])) { + if (intval($ret['channel']['channel_account_id'])) { + // Save our permissions role so we can perhaps call it up and modify it later. - // Save our permissions role so we can perhaps call it up and modify it later. + if ($role_permissions) { + set_pconfig($newuid, 'system', 'permissions_role', $arr['permissions_role']); + if (array_key_exists('online', $role_permissions)) { + set_pconfig($newuid, 'system', 'hide_presence', 1 - intval($role_permissions['online'])); + } + if (array_key_exists('perms_auto', $role_permissions)) { + $autoperms = intval($role_permissions['perms_auto']); + set_pconfig($newuid, 'system', 'autoperms', $autoperms); + } + } - if($role_permissions) { - set_pconfig($newuid,'system','permissions_role',$arr['permissions_role']); - if(array_key_exists('online',$role_permissions)) - set_pconfig($newuid,'system','hide_presence',1-intval($role_permissions['online'])); - if(array_key_exists('perms_auto',$role_permissions)) { - $autoperms = intval($role_permissions['perms_auto']); - set_pconfig($newuid,'system','autoperms',$autoperms); - } - } + // Create a group with yourself as a member. This allows somebody to use it + // right away as a default group for new contacts. - // Create a group with yourself as a member. This allows somebody to use it - // right away as a default group for new contacts. + $group_hash = AccessList::add($newuid, t('Friends')); + if ($group_hash) { + AccessList::member_add($newuid, t('Friends'), $ret['channel']['channel_hash']); - $group_hash = AccessList::add($newuid, t('Friends')); - if ($group_hash) { - AccessList::member_add($newuid,t('Friends'),$ret['channel']['channel_hash']); + // if our role_permissions indicate that we're using a default collection ACL, add it. - // if our role_permissions indicate that we're using a default collection ACL, add it. + if (is_array($role_permissions) && $role_permissions['default_collection']) { + $default_collection_str = '<' . $group_hash . '>'; + } + q( + "update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", + dbesc($group_hash), + dbesc(($default_collection_str) ? $default_collection_str : EMPTY_STR), + intval($newuid) + ); + } - if(is_array($role_permissions) && $role_permissions['default_collection']) { - $default_collection_str = '<' . $group_hash . '>'; - } - q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", - dbesc($group_hash), - dbesc(($default_collection_str) ? $default_collection_str : EMPTY_STR), - intval($newuid) - ); - } + set_pconfig($ret['channel']['channel_id'], 'system', 'photo_path', '%Y/%Y-%m'); + set_pconfig($ret['channel']['channel_id'], 'system', 'attach_path', '%Y/%Y-%m'); - set_pconfig($ret['channel']['channel_id'],'system','photo_path', '%Y/%Y-%m'); - set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y/%Y-%m'); - - // If this channel has a parent, auto follow them. + // If this channel has a parent, auto follow them. - if($parent_channel_hash) { - $ch = channelx_by_hash($parent_channel_hash); - if($ch) { - connect_and_sync($ret['channel'],channel_reddress($ch), true); - } - } + if ($parent_channel_hash) { + $ch = channelx_by_hash($parent_channel_hash); + if ($ch) { + connect_and_sync($ret['channel'], channel_reddress($ch), true); + } + } - // auto-follow any of the hub's pre-configured channel choices. - // Only do this if it's the first channel for this account; - // otherwise it could get annoying. Don't make this list too big - // or it will impact registration time. + // auto-follow any of the hub's pre-configured channel choices. + // Only do this if it's the first channel for this account; + // otherwise it could get annoying. Don't make this list too big + // or it will impact registration time. - $accts = get_config('system','auto_follow'); - if(($accts) && (! $total_identities)) { - if(! is_array($accts)) - $accts = array($accts); + $accts = get_config('system', 'auto_follow'); + if (($accts) && (! $total_identities)) { + if (! is_array($accts)) { + $accts = array($accts); + } - foreach($accts as $acct) { - if(trim($acct)) { - $f = connect_and_sync($ret['channel'],trim($acct)); - if($f['success']) { + foreach ($accts as $acct) { + if (trim($acct)) { + $f = connect_and_sync($ret['channel'], trim($acct)); + if ($f['success']) { + $can_view_stream = their_perms_contains($ret['channel']['channel_id'], $f['abook']['abook_xchan'], 'view_stream'); - $can_view_stream = their_perms_contains($ret['channel']['channel_id'],$f['abook']['abook_xchan'],'view_stream'); + // If we can view their stream, pull in some posts - // If we can view their stream, pull in some posts + if (($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) { + Run::Summon([ 'Onepoll',$f['abook']['abook_id'] ]); + } + } + } + } + } - if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) { - Run::Summon([ 'Onepoll',$f['abook']['abook_id'] ]); - } - } - } - } + /** + * @hooks create_identity + * Called when creating a channel. + * * \e int - The UID of the created identity + */ - } + call_hooks('create_identity', $newuid); - /** - * @hooks create_identity - * Called when creating a channel. - * * \e int - The UID of the created identity - */ + Run::Summon([ 'Directory', $ret['channel']['channel_id'] ]); + } - call_hooks('create_identity', $newuid); - - Run::Summon( [ 'Directory', $ret['channel']['channel_id'] ] ); - } - - $ret['success'] = true; - return $ret; + $ret['success'] = true; + return $ret; } -function connect_and_sync($channel,$address, $sub_channel = false) { +function connect_and_sync($channel, $address, $sub_channel = false) +{ - if ((! $channel) || (! $address)) { - return false; - } + if ((! $channel) || (! $address)) { + return false; + } - $f = Connect::connect($channel,$address, $sub_channel); - if ($f['success']) { - $clone = []; - foreach ($f['abook'] as $k => $v) { - if (strpos($k,'abook_') === 0) { - $clone[$k] = $v; - } - } - unset($clone['abook_id']); - unset($clone['abook_account']); - unset($clone['abook_channel']); - - $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); - if ($abconfig) { - $clone['abconfig'] = $abconfig; - } + $f = Connect::connect($channel, $address, $sub_channel); + if ($f['success']) { + $clone = []; + foreach ($f['abook'] as $k => $v) { + if (strpos($k, 'abook_') === 0) { + $clone[$k] = $v; + } + } + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); - Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ] ], true); - return $f; - } - return false; -} + $abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']); + if ($abconfig) { + $clone['abconfig'] = $abconfig; + } - -function change_channel_keys($channel) { - - $ret = array('success' => false); - - $stored = []; - - $key = Crypto::new_keypair(4096); - - $sig = Libzot::sign($channel['channel_guid'],$key['prvkey']); - $hash = Libzot::make_xchan_hash($channel['channel_guid'],$channel['channel_pubkey']); - - $stored['old_guid'] = $channel['channel_guid']; - $stored['old_guid_sig'] = $channel['channel_guid_sig']; - $stored['old_key'] = $channel['channel_pubkey']; - $stored['old_hash'] = $channel['channel_hash']; - - $stored['new_key'] = $key['pubkey']; - $stored['new_sig'] = Libzot::sign($key['pubkey'],$channel['channel_prvkey']); - - // Save this info for the notifier to collect - - set_pconfig($channel['channel_id'],'system','keychange',$stored); - - $r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', channel_hash = '%s' where channel_id = %d", - dbesc($key['prvkey']), - dbesc($key['pubkey']), - dbesc($sig), - dbesc($hash), - intval($channel['channel_id']) - ); - if (! $r) { - return $ret; - } - - $r = q("select * from channel where channel_id = %d", - intval($channel['channel_id']) - ); - - if (! $r) { - $ret['message'] = t('Unable to retrieve modified identity'); - return $ret; - } - - $modified = $r[0]; - - $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", - dbesc($stored['old_hash']), - dbesc(z_root()) - ); - - if($h) { - foreach($h as $hv) { - $hv['hubloc_guid_sig'] = $sig; - $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = Libzot::sign(z_root(),$modifed['channel_prvkey']); - hubloc_store_lowlevel($hv); - } - } - - $x = q("select * from xchan where xchan_hash = '%s' ", - dbesc($stored['old_hash']) - ); - - $check = q("select * from xchan where xchan_hash = '%s'", - dbesc($hash) - ); - - if (($x) && (! $check)) { - $oldxchan = $x[0]; - foreach ($x as $xv) { - $xv['xchan_guid_sig'] = $sig; - $xv['xchan_hash'] = $hash; - $xv['xchan_pubkey'] = $key['pubkey']; - $xv['xchan_updated'] = datetime_convert(); - xchan_store_lowlevel($xv); - $newxchan = $xv; - } - } - - Libsync::build_sync_packet($channel['channel_id'], [ 'keychange' => $stored ]); - - $a = q("select * from abook where abook_xchan = '%s' and abook_self = 1", - dbesc($stored['old_hash']) - ); - - if ($a) { - q("update abook set abook_xchan = '%s' where abook_id = %d", - dbesc($hash), - intval($a[0]['abook_id']) - ); - } - - xchan_change_key($oldxchan,$newxchan,$stored); - - Run::Summon([ 'Notifier', 'keychange', $channel['channel_id'] ]); - - $ret['success'] = true; - return $ret; + Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ] ], true); + return $f; + } + return false; } -function channel_change_address($channel,$new_address) { - $ret = array('success' => false); +function change_channel_keys($channel) +{ - $old_address = $channel['channel_address']; + $ret = array('success' => false); - if ($new_address === 'sys') { - $ret['message'] = t('Reserved nickname. Please choose another.'); - return $ret; - } + $stored = []; - if (check_webbie(array($new_address)) !== $new_address) { - $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); - return $ret; - } + $key = Crypto::new_keypair(4096); - $r = q("update channel set channel_address = '%s' where channel_id = %d", - dbesc($new_address), - intval($channel['channel_id']) - ); - if (! $r) { - return $ret; - } + $sig = Libzot::sign($channel['channel_guid'], $key['prvkey']); + $hash = Libzot::make_xchan_hash($channel['channel_guid'], $channel['channel_pubkey']); - $r = q("select * from channel where channel_id = %d", - intval($channel['channel_id']) - ); + $stored['old_guid'] = $channel['channel_guid']; + $stored['old_guid_sig'] = $channel['channel_guid_sig']; + $stored['old_key'] = $channel['channel_pubkey']; + $stored['old_hash'] = $channel['channel_hash']; - if (! $r) { - $ret['message'] = t('Unable to retrieve modified identity'); - return $ret; - } + $stored['new_key'] = $key['pubkey']; + $stored['new_sig'] = Libzot::sign($key['pubkey'], $channel['channel_prvkey']); - $r = q("update xchan set xchan_addr = '%s' where xchan_hash = '%s'", - dbesc($new_address . '@' . App::get_hostname()), - dbesc($channel['channel_hash']) - ); + // Save this info for the notifier to collect - $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", - dbesc($channel['channel_hash']), - dbesc(z_root()) - ); + set_pconfig($channel['channel_id'], 'system', 'keychange', $stored); - if ($h) { - foreach ($h as $hv) { - if ($hv['hubloc_primary']) { - q("update hubloc set hubloc_primary = 0 where hubloc_id = %d", - intval($hv['hubloc_id']) - ); - } - q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d", - intval($hv['hubloc_id']) - ); + $r = q( + "update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', channel_hash = '%s' where channel_id = %d", + dbesc($key['prvkey']), + dbesc($key['pubkey']), + dbesc($sig), + dbesc($hash), + intval($channel['channel_id']) + ); + if (! $r) { + return $ret; + } - unset($hv['hubloc_id']); - $hv['hubloc_addr'] = $new_address . '@' . App::get_hostname(); - hubloc_store_lowlevel($hv); - } - } + $r = q( + "select * from channel where channel_id = %d", + intval($channel['channel_id']) + ); - // fix apps which were stored with the actual name rather than a macro + if (! $r) { + $ret['message'] = t('Unable to retrieve modified identity'); + return $ret; + } - $r = q("select * from app where app_channel = %d and app_system = 1", - intval($channel['channel_id']) - ); - if ($r) { - foreach ($r as $rv) { - $replace = preg_replace('/([\=\/])(' . $old_address . ')($|[\%\/])/ism','$1' . $new_address . '$3',$rv['app_url']); - if ($replace != $rv['app_url']) { - q("update app set app_url = '%s' where id = %d", - dbesc($replace), - intval($rv['id']) - ); - } - } - } + $modified = $r[0]; - Run::Summon( [ 'Notifier', 'refresh_all', $channel['channel_id'] ] ); + $h = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", + dbesc($stored['old_hash']), + dbesc(z_root()) + ); - $ret['success'] = true; - return $ret; + if ($h) { + foreach ($h as $hv) { + $hv['hubloc_guid_sig'] = $sig; + $hv['hubloc_hash'] = $hash; + $hv['hubloc_url_sig'] = Libzot::sign(z_root(), $modifed['channel_prvkey']); + hubloc_store_lowlevel($hv); + } + } + + $x = q( + "select * from xchan where xchan_hash = '%s' ", + dbesc($stored['old_hash']) + ); + + $check = q( + "select * from xchan where xchan_hash = '%s'", + dbesc($hash) + ); + + if (($x) && (! $check)) { + $oldxchan = $x[0]; + foreach ($x as $xv) { + $xv['xchan_guid_sig'] = $sig; + $xv['xchan_hash'] = $hash; + $xv['xchan_pubkey'] = $key['pubkey']; + $xv['xchan_updated'] = datetime_convert(); + xchan_store_lowlevel($xv); + $newxchan = $xv; + } + } + + Libsync::build_sync_packet($channel['channel_id'], [ 'keychange' => $stored ]); + + $a = q( + "select * from abook where abook_xchan = '%s' and abook_self = 1", + dbesc($stored['old_hash']) + ); + + if ($a) { + q( + "update abook set abook_xchan = '%s' where abook_id = %d", + dbesc($hash), + intval($a[0]['abook_id']) + ); + } + + xchan_change_key($oldxchan, $newxchan, $stored); + + Run::Summon([ 'Notifier', 'keychange', $channel['channel_id'] ]); + + $ret['success'] = true; + return $ret; +} + +function channel_change_address($channel, $new_address) +{ + + $ret = array('success' => false); + + $old_address = $channel['channel_address']; + + if ($new_address === 'sys') { + $ret['message'] = t('Reserved nickname. Please choose another.'); + return $ret; + } + + if (check_webbie(array($new_address)) !== $new_address) { + $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); + return $ret; + } + + $r = q( + "update channel set channel_address = '%s' where channel_id = %d", + dbesc($new_address), + intval($channel['channel_id']) + ); + if (! $r) { + return $ret; + } + + $r = q( + "select * from channel where channel_id = %d", + intval($channel['channel_id']) + ); + + if (! $r) { + $ret['message'] = t('Unable to retrieve modified identity'); + return $ret; + } + + $r = q( + "update xchan set xchan_addr = '%s' where xchan_hash = '%s'", + dbesc($new_address . '@' . App::get_hostname()), + dbesc($channel['channel_hash']) + ); + + $h = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ", + dbesc($channel['channel_hash']), + dbesc(z_root()) + ); + + if ($h) { + foreach ($h as $hv) { + if ($hv['hubloc_primary']) { + q( + "update hubloc set hubloc_primary = 0 where hubloc_id = %d", + intval($hv['hubloc_id']) + ); + } + q( + "update hubloc set hubloc_deleted = 1 where hubloc_id = %d", + intval($hv['hubloc_id']) + ); + + unset($hv['hubloc_id']); + $hv['hubloc_addr'] = $new_address . '@' . App::get_hostname(); + hubloc_store_lowlevel($hv); + } + } + + // fix apps which were stored with the actual name rather than a macro + + $r = q( + "select * from app where app_channel = %d and app_system = 1", + intval($channel['channel_id']) + ); + if ($r) { + foreach ($r as $rv) { + $replace = preg_replace('/([\=\/])(' . $old_address . ')($|[\%\/])/ism', '$1' . $new_address . '$3', $rv['app_url']); + if ($replace != $rv['app_url']) { + q( + "update app set app_url = '%s' where id = %d", + dbesc($replace), + intval($rv['id']) + ); + } + } + } + + Run::Summon([ 'Notifier', 'refresh_all', $channel['channel_id'] ]); + + $ret['success'] = true; + return $ret; } @@ -800,18 +842,21 @@ function channel_change_address($channel,$new_address) { * - if true, set this default unconditionally * - if $force is false only do this if there is no existing default */ -function set_default_login_identity($account_id, $channel_id, $force = true) { - $r = q("select account_default_channel from account where account_id = %d limit 1", - intval($account_id) - ); - if ($r) { - if ((intval($r[0]['account_default_channel']) == 0) || ($force)) { - $r = q("update account set account_default_channel = %d where account_id = %d", - intval($channel_id), - intval($account_id) - ); - } - } +function set_default_login_identity($account_id, $channel_id, $force = true) +{ + $r = q( + "select account_default_channel from account where account_id = %d limit 1", + intval($account_id) + ); + if ($r) { + if ((intval($r[0]['account_default_channel']) == 0) || ($force)) { + $r = q( + "update account set account_default_channel = %d where account_id = %d", + intval($channel_id), + intval($account_id) + ); + } + } } /** @@ -819,25 +864,26 @@ function set_default_login_identity($account_id, $channel_id, $force = true) { * * @return array with default section names to export */ -function get_default_export_sections() { - $sections = [ - 'channel', - 'connections', - 'config', - 'apps', - 'chatrooms', - 'events' - ]; +function get_default_export_sections() +{ + $sections = [ + 'channel', + 'connections', + 'config', + 'apps', + 'chatrooms', + 'events' + ]; - $cb = [ 'sections' => $sections ]; - /** - * @hooks get_default_export_sections - * Called to get the default list of functional data groups to export in identity_basic_export(). - * * \e array \b sections - return value - */ - call_hooks('get_default_export_sections', $cb); + $cb = [ 'sections' => $sections ]; + /** + * @hooks get_default_export_sections + * Called to get the default list of functional data groups to export in identity_basic_export(). + * * \e array \b sections - return value + */ + call_hooks('get_default_export_sections', $cb); - return $cb['sections']; + return $cb['sections']; } @@ -853,273 +899,293 @@ function get_default_export_sections() { * @return array * See function for details */ -function identity_basic_export($channel_id, $sections = null) { +function identity_basic_export($channel_id, $sections = null) +{ - /* - * basic channel export - */ + /* + * basic channel export + */ - if(! $sections) { - $sections = get_default_export_sections(); - } + if (! $sections) { + $sections = get_default_export_sections(); + } - $ret = []; + $ret = []; - // use constants here as otherwise we will have no idea if we can import from a site - // with a non-standard platform and version. + // use constants here as otherwise we will have no idea if we can import from a site + // with a non-standard platform and version. - $ret['compatibility'] = [ - 'project' => PLATFORM_NAME, - 'codebase' => 'zap', - 'version' => STD_VERSION, - 'database' => DB_UPDATE_VERSION - ]; + $ret['compatibility'] = [ + 'project' => PLATFORM_NAME, + 'codebase' => 'zap', + 'version' => STD_VERSION, + 'database' => DB_UPDATE_VERSION + ]; - /* - * Process channel information regardless of it is one of the sections desired - * because we need the channel relocation information in all export files/streams. - */ + /* + * Process channel information regardless of it is one of the sections desired + * because we need the channel relocation information in all export files/streams. + */ - $r = q("select * from channel where channel_id = %d limit 1", - intval($channel_id) - ); - if ($r) { - $ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()]; - if (in_array('channel',$sections)) { - $ret['channel'] = $r[0]; - unset($ret['channel']['channel_password']); - unset($ret['channel']['channel_salt']); - } - } + $r = q( + "select * from channel where channel_id = %d limit 1", + intval($channel_id) + ); + if ($r) { + $ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()]; + if (in_array('channel', $sections)) { + $ret['channel'] = $r[0]; + unset($ret['channel']['channel_password']); + unset($ret['channel']['channel_salt']); + } + } - if (in_array('channel',$sections) || in_array('profile',$sections)) { - $r = q("select * from profile where uid = %d", - intval($channel_id) - ); - if ($r) { - $ret['profile'] = $r; - } + if (in_array('channel', $sections) || in_array('profile', $sections)) { + $r = q( + "select * from profile where uid = %d", + intval($channel_id) + ); + if ($r) { + $ret['profile'] = $r; + } - $r = q("select mimetype, content, os_storage from photo + $r = q( + "select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1", - intval(PHOTO_PROFILE), - intval($channel_id) - ); + intval(PHOTO_PROFILE), + intval($channel_id) + ); - if ($r) { - $ret['photo'] = [ - 'type' => $r[0]['mimetype'], - 'data' => (($r[0]['os_storage']) - ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode(dbunescbin($r[0]['content']))) - ]; - } - } + if ($r) { + $ret['photo'] = [ + 'type' => $r[0]['mimetype'], + 'data' => (($r[0]['os_storage']) + ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode(dbunescbin($r[0]['content']))) + ]; + } + } - if (in_array('connections',$sections)) { - $r = q("select * from atoken where atoken_uid = %d", - intval($channel_id) - ); - if ($r) { - $ret['atoken'] = $r; - } - - $xchans = []; - $r = q("select * from abook where abook_channel = %d ", - intval($channel_id) - ); - if ($r) { - $ret['abook'] = $r; + if (in_array('connections', $sections)) { + $r = q( + "select * from atoken where atoken_uid = %d", + intval($channel_id) + ); + if ($r) { + $ret['atoken'] = $r; + } - for ($x = 0; $x < count($ret['abook']); $x ++) { - $xchans[] = $ret['abook'][$x]['abook_xchan']; - $abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']); - if ($abconfig) { - $ret['abook'][$x]['abconfig'] = $abconfig; - } - } - stringify_array_elms($xchans); - } + $xchans = []; + $r = q( + "select * from abook where abook_channel = %d ", + intval($channel_id) + ); + if ($r) { + $ret['abook'] = $r; - if($xchans) { - $r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) "); - if ($r) { - $ret['xchan'] = $r; - } + for ($x = 0; $x < count($ret['abook']); $x++) { + $xchans[] = $ret['abook'][$x]['abook_xchan']; + $abconfig = load_abconfig($channel_id, $ret['abook'][$x]['abook_xchan']); + if ($abconfig) { + $ret['abook'][$x]['abconfig'] = $abconfig; + } + } + stringify_array_elms($xchans); + } - $r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) "); - if ($r) { - $ret['hubloc'] = $r; - } - } + if ($xchans) { + $r = q("select * from xchan where xchan_hash in ( " . implode(',', $xchans) . " ) "); + if ($r) { + $ret['xchan'] = $r; + } - $r = q("select * from pgrp where uid = %d ", - intval($channel_id) - ); + $r = q("select * from hubloc where hubloc_hash in ( " . implode(',', $xchans) . " ) "); + if ($r) { + $ret['hubloc'] = $r; + } + } - if ($r) { - $ret['group'] = $r; - } + $r = q( + "select * from pgrp where uid = %d ", + intval($channel_id) + ); - $r = q("select * from pgrp_member where uid = %d ", - intval($channel_id) - ); - if ($r) { - $ret['group_member'] = $r; - } + if ($r) { + $ret['group'] = $r; + } - $r = q("select * from xign where uid = %d ", - intval($channel_id) - ); - if ($r) { - $ret['xign'] = $r; - } + $r = q( + "select * from pgrp_member where uid = %d ", + intval($channel_id) + ); + if ($r) { + $ret['group_member'] = $r; + } - $r = q("select * from block where block_channel_id = %d ", - intval($channel_id) - ); - if ($r) { - $ret['block'] = $r; - } + $r = q( + "select * from xign where uid = %d ", + intval($channel_id) + ); + if ($r) { + $ret['xign'] = $r; + } + $r = q( + "select * from block where block_channel_id = %d ", + intval($channel_id) + ); + if ($r) { + $ret['block'] = $r; + } + } - } + if (in_array('config', $sections)) { + $r = q( + "select * from pconfig where uid = %d", + intval($channel_id) + ); + if ($r) { + $ret['config'] = $r; + } - if (in_array('config',$sections)) { - $r = q("select * from pconfig where uid = %d", - intval($channel_id) - ); - if ($r) { - $ret['config'] = $r; - } + // All other term types will be included in items, if requested. - // All other term types will be included in items, if requested. + $r = q( + "select * from term where ttype in (%d,%d) and uid = %d", + intval(TERM_SAVEDSEARCH), + intval(TERM_THING), + intval($channel_id) + ); + if ($r) { + $ret['term'] = $r; + } + // add psuedo-column obj_baseurl to aid in relocations - $r = q("select * from term where ttype in (%d,%d) and uid = %d", - intval(TERM_SAVEDSEARCH), - intval(TERM_THING), - intval($channel_id) - ); - if ($r) { - $ret['term'] = $r; - } - // add psuedo-column obj_baseurl to aid in relocations + $r = q( + "select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", + dbesc(z_root()), + intval($channel_id) + ); - $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", - dbesc(z_root()), - intval($channel_id) - ); + if ($r) { + $ret['obj'] = $r; + } - if ($r) { - $ret['obj'] = $r; - } + $r = q( + "select * from likes where channel_id = %d", + intval($channel_id) + ); - $r = q("select * from likes where channel_id = %d", - intval($channel_id) - ); + if ($r) { + $ret['likes'] = $r; + } + } - if ($r) { - $ret['likes'] = $r; - } - } + if (in_array('apps', $sections)) { + $r = q( + "select * from app where app_channel = %d and app_system = 0", + intval($channel_id) + ); + if ($r) { + for ($x = 0; $x < count($r); $x++) { + $r[$x]['term'] = q( + "select * from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($r[$x]['id']) + ); + } + $ret['app'] = $r; + } + $r = q( + "select * from app where app_channel = %d and app_system = 1", + intval($channel_id) + ); + if ($r) { + for ($x = 0; $x < count($r); $x++) { + $r[$x]['term'] = q( + "select * from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($r[$x]['id']) + ); + } + $ret['sysapp'] = $r; + } + } - if (in_array('apps',$sections)) { - $r = q("select * from app where app_channel = %d and app_system = 0", - intval($channel_id) - ); - if ($r) { - for ($x = 0; $x < count($r); $x ++) { - $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($r[$x]['id']) - ); - } - $ret['app'] = $r; - } - $r = q("select * from app where app_channel = %d and app_system = 1", - intval($channel_id) - ); - if ($r) { - for ($x = 0; $x < count($r); $x ++) { - $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($r[$x]['id']) - ); - } - $ret['sysapp'] = $r; - } - } + if (in_array('chatrooms', $sections)) { + $r = q( + "select * from chatroom where cr_uid = %d", + intval($channel_id) + ); + if ($r) { + $ret['chatroom'] = $r; + } + } - if (in_array('chatrooms',$sections)) { - $r = q("select * from chatroom where cr_uid = %d", - intval($channel_id) - ); - if ($r) { - $ret['chatroom'] = $r; - } - } + if (in_array('events', $sections)) { + $r = q( + "select * from event where uid = %d", + intval($channel_id) + ); + if ($r) { + $ret['event'] = $r; + } - if (in_array('events',$sections)) { - $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'] = []; + xchan_query($r); + $r = fetch_post_tags($r, true); + foreach ($r as $rr) { + $ret['event_item'][] = encode_item($rr, true); + } + } + } - $r = q("select * from item where resource_type = 'event' and uid = %d", - intval($channel_id) - ); - if ($r) { - $ret['event_item'] = []; - xchan_query($r); - $r = fetch_post_tags($r,true); - foreach ($r as $rr) { - $ret['event_item'][] = encode_item($rr,true); - } - } - } + if (in_array('items', $sections)) { + /** @warning this may run into memory limits on smaller systems */ - if (in_array('items', $sections)) { - /** @warning this may run into memory limits on smaller systems */ + /** 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. + */ - /** 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 + $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('3 MONTH') - ); - if ($r) { - $ret['item'] = []; - xchan_query($r); - $r = fetch_post_tags($r,true); - foreach ($r as $rr) { - $ret['item'][] = encode_item($rr,true); - } - } - } + intval($channel_id), + db_utcnow(), + db_quoteinterval('3 MONTH') + ); + if ($r) { + $ret['item'] = []; + xchan_query($r); + $r = fetch_post_tags($r, true); + foreach ($r as $rr) { + $ret['item'][] = encode_item($rr, true); + } + } + } - $addon = [ - 'channel_id' => $channel_id, - 'sections' => $sections, - 'data' => $ret - ]; - /** - * @hooks identity_basic_export - * Called when exporting a channel's basic information for backup or transfer. - * * \e number \b channel_id - The channel ID - * * \e array \b sections - * * \e array \b data - The data will get returned - */ - call_hooks('identity_basic_export', $addon); - $ret = $addon['data']; + $addon = [ + 'channel_id' => $channel_id, + 'sections' => $sections, + 'data' => $ret + ]; + /** + * @hooks identity_basic_export + * Called when exporting a channel's basic information for backup or transfer. + * * \e number \b channel_id - The channel ID + * * \e array \b sections + * * \e array \b data - The data will get returned + */ + call_hooks('identity_basic_export', $addon); + $ret = $addon['data']; - return $ret; + return $ret; } /** @@ -1132,30 +1198,28 @@ function identity_basic_export($channel_id, $sections = null) { * * \e array \b relocate - (optional) * * \e array \b item - array with items encoded_item() */ -function identity_export_year($channel_id, $year, $month = 0) { +function identity_export_year($channel_id, $year, $month = 0) +{ - if (! $year) { - return []; - } + if (! $year) { + return []; + } - if ($month && $month <= 12) { - $target_month = sprintf('%02d', $month); - $target_month_plus = sprintf('%02d', $month+1); - } - else { - $target_month = '01'; - } + if ($month && $month <= 12) { + $target_month = sprintf('%02d', $month); + $target_month_plus = sprintf('%02d', $month + 1); + } else { + $target_month = '01'; + } - $mindate = datetime_convert('UTC', 'UTC', $year . '-' . $target_month . '-01 00:00:00'); - if ($month && $month < 12) { - $maxdate = datetime_convert('UTC', 'UTC', $year . '-' . $target_month_plus . '-01 00:00:00'); - } - else { - $maxdate = datetime_convert('UTC', 'UTC', $year+1 . '-01-01 00:00:00'); - } - - return channel_export_items_date($channel_id,$mindate,$maxdate); + $mindate = datetime_convert('UTC', 'UTC', $year . '-' . $target_month . '-01 00:00:00'); + if ($month && $month < 12) { + $maxdate = datetime_convert('UTC', 'UTC', $year . '-' . $target_month_plus . '-01 00:00:00'); + } else { + $maxdate = datetime_convert('UTC', 'UTC', $year + 1 . '-01-01 00:00:00'); + } + return channel_export_items_date($channel_id, $mindate, $maxdate); } /** @@ -1169,46 +1233,47 @@ function identity_export_year($channel_id, $year, $month = 0) { * @return array */ -function channel_export_items_date($channel_id, $start, $finish) { +function channel_export_items_date($channel_id, $start, $finish) +{ - if (! $start) { - return []; - } - else { - $start = datetime_convert('UTC', 'UTC', $start); - } - - $finish = datetime_convert('UTC', 'UTC', (($finish) ? $finish : 'now')); - if ($finish < $start) { - return []; - } + if (! $start) { + return []; + } else { + $start = datetime_convert('UTC', 'UTC', $start); + } - $ret = []; + $finish = datetime_convert('UTC', 'UTC', (($finish) ? $finish : 'now')); + if ($finish < $start) { + return []; + } - $ch = channelx_by_n($channel_id); - if ($ch) { - $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; - } + $ret = []; - $ret['compatibility']['codebase'] = 'zap'; + $ch = channelx_by_n($channel_id); + if ($ch) { + $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; + } - $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type = '' order by created", - intval(ITEM_TYPE_POST), - intval($channel_id), - dbesc($start), - dbesc($finish) - ); + $ret['compatibility']['codebase'] = 'zap'; - if ($r) { - $ret['item'] = []; - xchan_query($r); - $r = fetch_post_tags($r, true); - foreach ($r as $rr) { - $ret['item'][] = encode_item($rr, true); - } - } + $r = q( + "select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type = '' order by created", + intval(ITEM_TYPE_POST), + intval($channel_id), + dbesc($start), + dbesc($finish) + ); - return $ret; + if ($r) { + $ret['item'] = []; + xchan_query($r); + $r = fetch_post_tags($r, true); + foreach ($r as $rr) { + $ret['item'][] = encode_item($rr, true); + } + } + + return $ret; } @@ -1223,87 +1288,90 @@ function channel_export_items_date($channel_id, $start, $finish) { * @return array */ -function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50) { +function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50) +{ - if (intval($page) < 1) { - $page = 0; - } + if (intval($page) < 1) { + $page = 0; + } - if (intval($limit) < 1) { - $limit = 1; - } + if (intval($limit) < 1) { + $limit = 1; + } - if (intval($limit) > 5000) { - $limit = 5000; - } + if (intval($limit) > 5000) { + $limit = 5000; + } - if (! $start) { - $start = NULL_DATE; - } - else { - $start = datetime_convert('UTC', 'UTC', $start); - } - - $finish = datetime_convert('UTC', 'UTC', (($finish) ? $finish : 'now')); - if ($finish < $start) { - return []; - } + if (! $start) { + $start = NULL_DATE; + } else { + $start = datetime_convert('UTC', 'UTC', $start); + } - $offset = intval($limit) * intval($page); + $finish = datetime_convert('UTC', 'UTC', (($finish) ? $finish : 'now')); + if ($finish < $start) { + return []; + } - $ret = []; + $offset = intval($limit) * intval($page); - $ch = channelx_by_n($channel_id); - if ($ch) { - $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; - } + $ret = []; - $ret['compatibility']['codebase'] = 'zap'; + $ch = channelx_by_n($channel_id); + if ($ch) { + $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; + } + + $ret['compatibility']['codebase'] = 'zap'; - $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and resource_type = '' and created >= '%s' and created <= '%s' order by created limit %d offset %d", - intval(ITEM_TYPE_POST), - intval($channel_id), - dbesc($start), - dbesc($finish), - intval($limit), - intval($offset) - ); + $r = q( + "select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and resource_type = '' and created >= '%s' and created <= '%s' order by created limit %d offset %d", + intval(ITEM_TYPE_POST), + intval($channel_id), + dbesc($start), + dbesc($finish), + intval($limit), + intval($offset) + ); - if ($r) { - $ret['item'] = []; - xchan_query($r); - $r = fetch_post_tags($r, true); - foreach ($r as $rr) { - $ret['item'][] = encode_item($rr, true); - } - } + if ($r) { + $ret['item'] = []; + xchan_query($r); + $r = fetch_post_tags($r, true); + foreach ($r as $rr) { + $ret['item'][] = encode_item($rr, true); + } + } - return $ret; + return $ret; } -function get_my_url() { - if (x($_SESSION, 'zrl_override')) { - return $_SESSION['zrl_override']; - } - if (x($_SESSION, 'my_url')) { - return $_SESSION['my_url']; - } +function get_my_url() +{ + if (x($_SESSION, 'zrl_override')) { + return $_SESSION['zrl_override']; + } + if (x($_SESSION, 'my_url')) { + return $_SESSION['my_url']; + } - return false; + return false; } -function get_my_address() { - if (x($_SESSION, 'zid_override')) { - return $_SESSION['zid_override']; - } - if (x($_SESSION, 'my_address')) { - return $_SESSION['my_address']; - } +function get_my_address() +{ + if (x($_SESSION, 'zid_override')) { + return $_SESSION['zid_override']; + } + if (x($_SESSION, 'my_address')) { + return $_SESSION['my_address']; + } - return false; + return false; } /** @@ -1313,75 +1381,81 @@ function get_my_address() { * don't have it already. * And if they aren't already authenticated here, attempt reverse magic auth. */ -function zid_init() { - $tmp_str = get_my_address(); - if (validate_email($tmp_str)) { - $arr = [ - 'zid' => $tmp_str, - 'url' => App::$cmd - ]; - /** - * @hooks zid_init - * * \e string \b zid - their zid - * * \e string \b url - the destination url - */ - call_hooks('zid_init', $arr); +function zid_init() +{ + $tmp_str = get_my_address(); + if (validate_email($tmp_str)) { + $arr = [ + 'zid' => $tmp_str, + 'url' => App::$cmd + ]; + /** + * @hooks zid_init + * * \e string \b zid - their zid + * * \e string \b url - the destination url + */ + call_hooks('zid_init', $arr); - if (! local_channel()) { - $r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", - dbesc($tmp_str) - ); - if (! $r) { - Run::Summon( [ 'Gprobe', bin2hex($tmp_str) ] ); - } - if ($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) { - return; - } + if (! local_channel()) { + $r = q( + "select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", + dbesc($tmp_str) + ); + if (! $r) { + Run::Summon([ 'Gprobe', bin2hex($tmp_str) ]); + } + if ($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) { + return; + } - logger('Not authenticated. Invoking reverse magic-auth for ' . $tmp_str); - // try to avoid recursion - but send them home to do a proper magic auth - $query = App::$query_string; - $query = str_replace(array('?zid=','&zid='),array('?rzid=','&rzid='),$query); - $dest = '/' . $query; - if ($r && ($r[0]['hubloc_url'] != z_root()) && (! strstr($dest,'/magic')) && (! strstr($dest,'/rmagic'))) { - goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&owa=1&bdest=' . bin2hex(z_root() . $dest)); - } - else - logger('No hubloc found.'); - } - } + logger('Not authenticated. Invoking reverse magic-auth for ' . $tmp_str); + // try to avoid recursion - but send them home to do a proper magic auth + $query = App::$query_string; + $query = str_replace(array('?zid=','&zid='), array('?rzid=','&rzid='), $query); + $dest = '/' . $query; + if ($r && ($r[0]['hubloc_url'] != z_root()) && (! strstr($dest, '/magic')) && (! strstr($dest, '/rmagic'))) { + goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&owa=1&bdest=' . bin2hex(z_root() . $dest)); + } else { + logger('No hubloc found.'); + } + } + } } /** * @brief If somebody arrives at our site using a zat, authenticate them. * */ -function zat_init() { - if (local_channel() || remote_channel()) { - return; - } +function zat_init() +{ + if (local_channel() || remote_channel()) { + return; + } - $r = q("select * from atoken where atoken_token = '%s' limit 1", - dbesc($_REQUEST['zat']) - ); - if ($r) { - $xchan = atoken_xchan($r[0]); -// atoken_create_xchan($xchan); - atoken_login($xchan); - } + $r = q( + "select * from atoken where atoken_token = '%s' limit 1", + dbesc($_REQUEST['zat']) + ); + if ($r) { + $xchan = atoken_xchan($r[0]); +// atoken_create_xchan($xchan); + atoken_login($xchan); + } } -function atoken_delete_and_sync($channel_id,$atoken_guid) { - $r = q("select * from atoken where atoken_guid = '%s' and atoken_uid = %d", - dbesc($atoken_guid), - intval($channel_id) - ); - if ($r) { - $atok = array_shift($r); - $atok['deleted'] = true; - atoken_delete($atok['atoken_id']); - Libsync::build_sync_packet($channel_id, [ 'atoken' => [ $atok ] ] ); - } +function atoken_delete_and_sync($channel_id, $atoken_guid) +{ + $r = q( + "select * from atoken where atoken_guid = '%s' and atoken_uid = %d", + dbesc($atoken_guid), + intval($channel_id) + ); + if ($r) { + $atok = array_shift($r); + $atok['deleted'] = true; + atoken_delete($atok['atoken_id']); + Libsync::build_sync_packet($channel_id, [ 'atoken' => [ $atok ] ]); + } } /** @@ -1394,21 +1468,22 @@ function atoken_delete_and_sync($channel_id,$atoken_guid) { * * @return int */ -function get_theme_uid() { - $uid = ((isset($_REQUEST['puid'])) ? intval($_REQUEST['puid']) : 0); - if (local_channel()) { - if ((get_pconfig(local_channel(),'system','always_my_theme')) || (! $uid)) { - return local_channel(); - } - } - if (! $uid) { - $x = get_sys_channel(); - if ($x) { - return $x['channel_id']; - } - } +function get_theme_uid() +{ + $uid = ((isset($_REQUEST['puid'])) ? intval($_REQUEST['puid']) : 0); + if (local_channel()) { + if ((get_pconfig(local_channel(), 'system', 'always_my_theme')) || (! $uid)) { + return local_channel(); + } + } + if (! $uid) { + $x = get_sys_channel(); + if ($x) { + return $x['channel_id']; + } + } - return $uid; + return $uid; } /** @@ -1419,24 +1494,24 @@ function get_theme_uid() { * one of (300, 80, 48) * @return string with path to profile photo */ -function get_default_profile_photo($size = 300) { - $scheme = get_config('system','default_profile_photo'); - if (! $scheme) { - $scheme = 'rainbow_man'; - } +function get_default_profile_photo($size = 300) +{ + $scheme = get_config('system', 'default_profile_photo'); + if (! $scheme) { + $scheme = 'rainbow_man'; + } - if (! is_dir('images/default_profile_photos/' . $scheme)) { - $x = [ 'scheme' => $scheme, 'size' => $size, 'url' => '' ]; - call_hooks('default_profile_photo',$x); - if ($x['url']) { - return $x['url']; - } - else { - $scheme = 'rainbow_man'; - } - } + if (! is_dir('images/default_profile_photos/' . $scheme)) { + $x = [ 'scheme' => $scheme, 'size' => $size, 'url' => '' ]; + call_hooks('default_profile_photo', $x); + if ($x['url']) { + return $x['url']; + } else { + $scheme = 'rainbow_man'; + } + } - return 'images/default_profile_photos/' . $scheme . '/' . $size . '.png'; + return 'images/default_profile_photos/' . $scheme . '/' . $size . '.png'; } /** @@ -1446,8 +1521,9 @@ function get_default_profile_photo($size = 300) { * xchan_hash of the identity in question * @return bool true or false */ -function is_foreigner($s) { - return((strpbrk($s, '.:@')) ? true : false); +function is_foreigner($s) +{ + return((strpbrk($s, '.:@')) ? true : false); } /** @@ -1457,8 +1533,9 @@ function is_foreigner($s) { * xchan_hash of the identity in question * @return bool true or false */ -function is_member($s) { - return((is_foreigner($s)) ? false : true); +function is_member($s) +{ + return((is_foreigner($s)) ? false : true); } /** @@ -1468,31 +1545,34 @@ function is_member($s) { * @return array An associative array with * * \e bool \b result */ -function get_online_status($nick) { +function get_online_status($nick) +{ - $ret = array('result' => false); + $ret = array('result' => false); - if (observer_prohibited()) { - return $ret; - } + if (observer_prohibited()) { + return $ret; + } - $r = q("select channel_id, channel_hash from channel where channel_address = '%s' limit 1", - dbesc($nick) - ); - if ($r) { - $hide = get_pconfig($r[0]['channel_id'],'system','hide_online_status'); - if ($hide) { - return $ret; - } - $x = q("select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1", - dbesc($r[0]['channel_hash']) - ); - if ($x) { - $ret['result'] = $x[0]['cp_status']; - } - } + $r = q( + "select channel_id, channel_hash from channel where channel_address = '%s' limit 1", + dbesc($nick) + ); + if ($r) { + $hide = get_pconfig($r[0]['channel_id'], 'system', 'hide_online_status'); + if ($hide) { + return $ret; + } + $x = q( + "select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1", + dbesc($r[0]['channel_hash']) + ); + if ($x) { + $ret['result'] = $x[0]['cp_status']; + } + } - return $ret; + return $ret; } @@ -1502,26 +1582,28 @@ function get_online_status($nick) { * @param string $webbie * @return array|bool|string */ -function remote_online_status($webbie) { +function remote_online_status($webbie) +{ - $result = false; - $r = q("select * from hubloc where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - if (! $r) { - return $result; - } - $url = $r[0]['hubloc_url'] . '/online/' . substr($webbie,0,strpos($webbie,'@')); + $result = false; + $r = q( + "select * from hubloc where hubloc_addr = '%s' limit 1", + dbesc($webbie) + ); + if (! $r) { + return $result; + } + $url = $r[0]['hubloc_url'] . '/online/' . substr($webbie, 0, strpos($webbie, '@')); - $x = z_fetch_url($url); - if ($x['success']) { - $j = json_decode($x['body'],true); - if ($j) { - $result = (($j['result']) ? $j['result'] : false); - } - } + $x = z_fetch_url($url); + if ($x['success']) { + $j = json_decode($x['body'], true); + if ($j) { + $result = (($j['result']) ? $j['result'] : false); + } + } - return $result; + return $result; } @@ -1530,82 +1612,89 @@ function remote_online_status($webbie) { * * @return string with parsed HTML channel_id_selet template */ -function identity_selector() { - if (local_channel()) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", - intval(get_account_id()) - ); - if ($r && count($r) > 1) { - $o = replace_macros(get_markup_template('channel_id_select.tpl'), array( - '$channels' => $r, - '$selected' => local_channel() - )); +function identity_selector() +{ + if (local_channel()) { + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", + intval(get_account_id()) + ); + if ($r && count($r) > 1) { + $o = replace_macros(get_markup_template('channel_id_select.tpl'), array( + '$channels' => $r, + '$selected' => local_channel() + )); - return $o; - } - } + return $o; + } + } - return ''; + return ''; } -function is_public_profile() { - if (! local_channel()) { - return false; - } +function is_public_profile() +{ + if (! local_channel()) { + return false; + } - if (intval(get_config('system','block_public'))) { - return false; - } + if (intval(get_config('system', 'block_public'))) { + return false; + } - $channel = App::get_channel(); - if ($channel) { - $perm = PermissionLimits::Get($channel['channel_id'],'view_profile'); - if ($perm == PERMS_PUBLIC) { - return true; - } - } + $channel = App::get_channel(); + if ($channel) { + $perm = PermissionLimits::Get($channel['channel_id'], 'view_profile'); + if ($perm == PERMS_PUBLIC) { + return true; + } + } - return false; + return false; } -function get_profile_fields_basic($filter = 0) { +function get_profile_fields_basic($filter = 0) +{ - $profile_fields_basic = (($filter == 0) ? get_config('system','profile_fields_basic') : null); + $profile_fields_basic = (($filter == 0) ? get_config('system', 'profile_fields_basic') : null); - if (! $profile_fields_basic) { - $profile_fields_basic = array('fullname','pdesc','chandesc','basic_gender','pronouns','dob','dob_tz','region','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); - } - - $x = []; - if ($profile_fields_basic) - foreach ($profile_fields_basic as $f) - $x[$f] = 1; + if (! $profile_fields_basic) { + $profile_fields_basic = array('fullname','pdesc','chandesc','basic_gender','pronouns','dob','dob_tz','region','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); + } - return $x; + $x = []; + if ($profile_fields_basic) { + foreach ($profile_fields_basic as $f) { + $x[$f] = 1; + } + } + + return $x; } -function get_profile_fields_advanced($filter = 0) { - $basic = get_profile_fields_basic($filter); - $profile_fields_advanced = (($filter == 0) ? get_config('system','profile_fields_advanced') : null); - if (! $profile_fields_advanced) { - $profile_fields_advanced = array('comms', 'address','locality','postal_code','advanced_gender', 'partner','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','employment','education'); - } - $x = []; - if ($basic) { - foreach ($basic as $f => $v) { - $x[$f] = $v; - } - } +function get_profile_fields_advanced($filter = 0) +{ + $basic = get_profile_fields_basic($filter); + $profile_fields_advanced = (($filter == 0) ? get_config('system', 'profile_fields_advanced') : null); + if (! $profile_fields_advanced) { + $profile_fields_advanced = array('comms', 'address','locality','postal_code','advanced_gender', 'partner','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','employment','education'); + } + $x = []; + if ($basic) { + foreach ($basic as $f => $v) { + $x[$f] = $v; + } + } - if ($profile_fields_advanced) { - foreach ($profile_fields_advanced as $f) { - $x[$f] = 1; - } - } + if ($profile_fields_advanced) { + foreach ($profile_fields_advanced as $f) { + $x[$f] = 1; + } + } - return $x; + return $x; } /** @@ -1620,132 +1709,150 @@ function get_profile_fields_advanced($filter = 0) { * Current notification flag value. Send this to notifications_on() to restore the channel settings when finished * with the activity requiring notifications_off(); */ -function notifications_off($channel_id) { - $r = q("select channel_notifyflags from channel where channel_id = %d limit 1", - intval($channel_id) - ); - q("update channel set channel_notifyflags = 0 where channel_id = %d", - intval($channel_id) - ); +function notifications_off($channel_id) +{ + $r = q( + "select channel_notifyflags from channel where channel_id = %d limit 1", + intval($channel_id) + ); + q( + "update channel set channel_notifyflags = 0 where channel_id = %d", + intval($channel_id) + ); - return intval($r[0]['channel_notifyflags']); + return intval($r[0]['channel_notifyflags']); } -function notifications_on($channel_id, $value) { - $x = q("update channel set channel_notifyflags = %d where channel_id = %d", - intval($value), - intval($channel_id) - ); +function notifications_on($channel_id, $value) +{ + $x = q( + "update channel set channel_notifyflags = %d where channel_id = %d", + intval($value), + intval($channel_id) + ); - return $x; + return $x; } -function get_channel_default_perms($uid) { +function get_channel_default_perms($uid) +{ - $ret = []; + $ret = []; - $r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 1 limit 1", - intval($uid) - ); - if ($r) { - $ret = Permissions::FilledPerms(get_abconfig($uid,$r[0]['abook_xchan'],'system','my_perms',EMPTY_STR)); - } + $r = q( + "select abook_xchan from abook where abook_channel = %d and abook_self = 1 limit 1", + intval($uid) + ); + if ($r) { + $ret = Permissions::FilledPerms(get_abconfig($uid, $r[0]['abook_xchan'], 'system', 'my_perms', EMPTY_STR)); + } - return $ret; + return $ret; } -function profiles_build_sync($channel_id,$send = true) { - $r = q("select * from profile where uid = %d", - intval($channel_id) - ); - if ($r) { - if($send) { - Libsync::build_sync_packet($channel_id,array('profile' => $r)); - } - else { - return $r; - } - } +function profiles_build_sync($channel_id, $send = true) +{ + $r = q( + "select * from profile where uid = %d", + intval($channel_id) + ); + if ($r) { + if ($send) { + Libsync::build_sync_packet($channel_id, array('profile' => $r)); + } else { + return $r; + } + } } -function auto_channel_create($account_id) { +function auto_channel_create($account_id) +{ - if (! $account_id) { - return false; - } + if (! $account_id) { + return false; + } - $arr = []; - $arr['account_id'] = $account_id; - $arr['name'] = get_aconfig($account_id,'register','channel_name'); - $arr['nickname'] = legal_webbie(get_aconfig($account_id,'register','channel_address')); - $arr['permissions_role'] = get_aconfig($account_id,'register','permissions_role'); + $arr = []; + $arr['account_id'] = $account_id; + $arr['name'] = get_aconfig($account_id, 'register', 'channel_name'); + $arr['nickname'] = legal_webbie(get_aconfig($account_id, 'register', 'channel_address')); + $arr['permissions_role'] = get_aconfig($account_id, 'register', 'permissions_role'); - del_aconfig($account_id,'register','channel_name'); - del_aconfig($account_id,'register','channel_address'); - del_aconfig($account_id,'register','permissions_role'); + del_aconfig($account_id, 'register', 'channel_name'); + del_aconfig($account_id, 'register', 'channel_address'); + del_aconfig($account_id, 'register', 'permissions_role'); - if((! $arr['name']) || (! $arr['nickname'])) { - $x = q("select * from account where account_id = %d limit 1", - intval($account_id) - ); - if($x) { - if(! $arr['name']) - $arr['name'] = substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@')); - if(! $arr['nickname']) - $arr['nickname'] = legal_webbie(substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@'))); - } - } - if(! $arr['permissions_role']) - $arr['permissions_role'] = 'social'; + if ((! $arr['name']) || (! $arr['nickname'])) { + $x = q( + "select * from account where account_id = %d limit 1", + intval($account_id) + ); + if ($x) { + if (! $arr['name']) { + $arr['name'] = substr($x[0]['account_email'], 0, strpos($x[0]['account_email'], '@')); + } + if (! $arr['nickname']) { + $arr['nickname'] = legal_webbie(substr($x[0]['account_email'], 0, strpos($x[0]['account_email'], '@'))); + } + } + } + if (! $arr['permissions_role']) { + $arr['permissions_role'] = 'social'; + } - if(validate_channelname($arr['name'])) - return false; - if($arr['nickname'] === 'sys') - $arr['nickname'] = $arr['nickname'] . mt_rand(1000,9999); + if (validate_channelname($arr['name'])) { + return false; + } + if ($arr['nickname'] === 'sys') { + $arr['nickname'] = $arr['nickname'] . mt_rand(1000, 9999); + } - $arr['nickname'] = check_webbie(array($arr['nickname'], $arr['nickname'] . mt_rand(1000,9999))); + $arr['nickname'] = check_webbie(array($arr['nickname'], $arr['nickname'] . mt_rand(1000, 9999))); - return create_identity($arr); + return create_identity($arr); } -function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_1200) { +function get_cover_photo($channel_id, $format = 'bbcode', $res = PHOTO_RES_COVER_1200) +{ - $r = q("select height, width, resource_id, edited, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", - intval($channel_id), - intval($res), - intval(PHOTO_COVER) - ); - if(! $r) - return false; + $r = q( + "select height, width, resource_id, edited, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", + intval($channel_id), + intval($res), + intval(PHOTO_COVER) + ); + if (! $r) { + return false; + } - $output = false; + $output = false; - $url = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $res ; + $url = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $res ; - switch($format) { - case 'bbcode': - $output = '[zrl=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . $url . '[/zrl]'; - break; - case 'html': - $output = '' . t('cover photo') . ''; - break; - case 'array': - default: - $output = array( - 'width' => $r[0]['width'], - 'height' => $r[0]['height'], - 'type' => $r[0]['mimetype'], - 'updated' => $r[0]['edited'], - 'url' => $url - ); - break; - } + switch ($format) { + case 'bbcode': + $output = '[zrl=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . $url . '[/zrl]'; + break; + case 'html': + $output = '' . t('cover photo') . ''; + break; + case 'array': + default: + $output = array( + 'width' => $r[0]['width'], + 'height' => $r[0]['height'], + 'type' => $r[0]['mimetype'], + 'updated' => $r[0]['edited'], + 'url' => $url + ); + break; + } - return $output; + return $output; } @@ -1757,69 +1864,71 @@ function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_ * @param array $args (optional) * @return string parsed HTML from \e zcard template */ -function get_zcard($channel, $observer_hash = '', $args = []) { +function get_zcard($channel, $observer_hash = '', $args = []) +{ - logger('get_zcard'); + logger('get_zcard'); - $maxwidth = (($args['width']) ? intval($args['width']) : 0); - $maxheight = (($args['height']) ? intval($args['height']) : 0); + $maxwidth = (($args['width']) ? intval($args['width']) : 0); + $maxheight = (($args['height']) ? intval($args['height']) : 0); - if(($maxwidth > 1200) || ($maxwidth < 1)) { - $maxwidth = 1200; - $cover_width = 1200; - } + if (($maxwidth > 1200) || ($maxwidth < 1)) { + $maxwidth = 1200; + $cover_width = 1200; + } - if($maxwidth <= 425) { - $width = 425; - $cover_width = 425; - $size = 'hz_small'; - $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m'].'?rev='.strtotime($channel['xchan_photo_date'])); - } elseif($maxwidth <= 900) { - $width = 900; - $cover_width = 850; - $size = 'hz_medium'; - $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l'].'?rev='.strtotime($channel['xchan_photo_date'])); - } elseif($maxwidth <= 1200) { - $width = 1200; - $cover_width = 1200; - $size = 'hz_large'; - $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l'].'?rev='.strtotime($channel['xchan_photo_date'])); - } + if ($maxwidth <= 425) { + $width = 425; + $cover_width = 425; + $size = 'hz_small'; + $cover_size = PHOTO_RES_COVER_425; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m'] . '?rev=' . strtotime($channel['xchan_photo_date'])); + } elseif ($maxwidth <= 900) { + $width = 900; + $cover_width = 850; + $size = 'hz_medium'; + $cover_size = PHOTO_RES_COVER_850; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l'] . '?rev=' . strtotime($channel['xchan_photo_date'])); + } elseif ($maxwidth <= 1200) { + $width = 1200; + $cover_width = 1200; + $size = 'hz_large'; + $cover_size = PHOTO_RES_COVER_1200; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l'] . '?rev=' . strtotime($channel['xchan_photo_date'])); + } -// $scale = (float) $maxwidth / $width; -// $translate = intval(($scale / 1.0) * 100); +// $scale = (float) $maxwidth / $width; +// $translate = intval(($scale / 1.0) * 100); - $channel['channel_addr'] = channel_reddress($channel); - $zcard = array('chan' => $channel); + $channel['channel_addr'] = channel_reddress($channel); + $zcard = array('chan' => $channel); - $r = q("select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", - intval($channel['channel_id']), - intval($cover_size), - intval(PHOTO_COVER) - ); + $r = q( + "select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", + intval($channel['channel_id']), + intval($cover_size), + intval(PHOTO_COVER) + ); - if($r) { - $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; - } else { - $default_cover = get_config('system','default_cover_photo','pexels-94622'); - $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ]; - } + if ($r) { + $cover = $r[0]; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; + } else { + $default_cover = get_config('system', 'default_cover_photo', 'pexels-94622'); + $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ]; + } - $o .= replace_macros(get_markup_template('zcard.tpl'), array( - '$maxwidth' => $maxwidth, - '$scale' => $scale, - '$translate' => $translate, - '$size' => $size, - '$cover' => $cover, - '$pphoto' => $pphoto, - '$zcard' => $zcard - )); + $o .= replace_macros(get_markup_template('zcard.tpl'), array( + '$maxwidth' => $maxwidth, + '$scale' => $scale, + '$translate' => $translate, + '$size' => $size, + '$cover' => $cover, + '$pphoto' => $pphoto, + '$zcard' => $zcard + )); - return $o; + return $o; } @@ -1831,69 +1940,68 @@ function get_zcard($channel, $observer_hash = '', $args = []) { * @param array $args (optional) * @return string parsed HTML from \e zcard_embed template */ -function get_zcard_embed($channel, $observer_hash = '', $args = []) { +function get_zcard_embed($channel, $observer_hash = '', $args = []) +{ - logger('get_zcard_embed'); + logger('get_zcard_embed'); - $maxwidth = (($args['width']) ? intval($args['width']) : 0); - $maxheight = (($args['height']) ? intval($args['height']) : 0); + $maxwidth = (($args['width']) ? intval($args['width']) : 0); + $maxheight = (($args['height']) ? intval($args['height']) : 0); - if(($maxwidth > 1200) || ($maxwidth < 1)) { - $maxwidth = 1200; - $cover_width = 1200; - } + if (($maxwidth > 1200) || ($maxwidth < 1)) { + $maxwidth = 1200; + $cover_width = 1200; + } - if($maxwidth <= 425) { - $width = 425; - $cover_width = 425; - $size = 'hz_small'; - $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); - } - elseif($maxwidth <= 900) { - $width = 900; - $cover_width = 850; - $size = 'hz_medium'; - $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); - } - elseif($maxwidth <= 1200) { - $width = 1200; - $cover_width = 1200; - $size = 'hz_large'; - $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); - } + if ($maxwidth <= 425) { + $width = 425; + $cover_width = 425; + $size = 'hz_small'; + $cover_size = PHOTO_RES_COVER_425; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + } elseif ($maxwidth <= 900) { + $width = 900; + $cover_width = 850; + $size = 'hz_medium'; + $cover_size = PHOTO_RES_COVER_850; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); + } elseif ($maxwidth <= 1200) { + $width = 1200; + $cover_width = 1200; + $size = 'hz_large'; + $cover_size = PHOTO_RES_COVER_1200; + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + } - $channel['channel_addr'] = channel_reddress($channel); - $zcard = array('chan' => $channel); + $channel['channel_addr'] = channel_reddress($channel); + $zcard = array('chan' => $channel); - $r = q("select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", - intval($channel['channel_id']), - intval($cover_size), - intval(PHOTO_COVER) - ); + $r = q( + "select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", + intval($channel['channel_id']), + intval($cover_size), + intval(PHOTO_COVER) + ); - if($r) { - $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; - } - else { - $default_cover = get_config('system','default_cover_photo','pexels-94622'); - $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ]; - } + if ($r) { + $cover = $r[0]; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; + } else { + $default_cover = get_config('system', 'default_cover_photo', 'pexels-94622'); + $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ]; + } - $o .= replace_macros(get_markup_template('zcard_embed.tpl'),array( - '$maxwidth' => $maxwidth, - '$scale' => $scale, - '$translate' => $translate, - '$size' => $size, - '$cover' => $cover, - '$pphoto' => $pphoto, - '$zcard' => $zcard - )); + $o .= replace_macros(get_markup_template('zcard_embed.tpl'), array( + '$maxwidth' => $maxwidth, + '$scale' => $scale, + '$translate' => $translate, + '$size' => $size, + '$cover' => $cover, + '$pphoto' => $pphoto, + '$zcard' => $zcard + )); - return $o; + return $o; } /** @@ -1905,28 +2013,32 @@ function get_zcard_embed($channel, $observer_hash = '', $args = []) { * - false if no channel with $nick was found */ -function channelx_by_nick($nick,$include_removed = false) { +function channelx_by_nick($nick, $include_removed = false) +{ - $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); - - // If we are provided a Unicode nickname convert to IDN + $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); - $nick = punify($nick); + // If we are provided a Unicode nickname convert to IDN - // return a cached copy if there is a cached copy and it's a match. - // Also check that there is an xchan_hash to validate the App::$channel data is complete - // and that columns from both joined tables are present - - if (App::$channel && is_array(App::$channel) && array_key_exists('channel_address',App::$channel) - && array_key_exists('xchan_hash',App::$channel) && App::$channel['channel_address'] === $nick) { - return App::$channel; - } + $nick = punify($nick); - $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' $sql_extra LIMIT 1", - dbesc($nick) - ); + // return a cached copy if there is a cached copy and it's a match. + // Also check that there is an xchan_hash to validate the App::$channel data is complete + // and that columns from both joined tables are present - return(($r) ? array_shift($r) : false); + if ( + App::$channel && is_array(App::$channel) && array_key_exists('channel_address', App::$channel) + && array_key_exists('xchan_hash', App::$channel) && App::$channel['channel_address'] === $nick + ) { + return App::$channel; + } + + $r = q( + "SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' $sql_extra LIMIT 1", + dbesc($nick) + ); + + return(($r) ? array_shift($r) : false); } /** @@ -1936,20 +2048,24 @@ function channelx_by_nick($nick,$include_removed = false) { * @return array|bool false if channel ID not found, otherwise the channel array */ -function channelx_by_hash($hash, $include_removed = false) { +function channelx_by_hash($hash, $include_removed = false) +{ - $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); + $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); - if (App::$channel && is_array(App::$channel) && array_key_exists('channel_hash',App::$channel) - && array_key_exists('xchan_hash',App::$channel) && App::$channel['channel_hash'] === $hash) { - return App::$channel; - } + if ( + App::$channel && is_array(App::$channel) && array_key_exists('channel_hash', App::$channel) + && array_key_exists('xchan_hash', App::$channel) && App::$channel['channel_hash'] === $hash + ) { + return App::$channel; + } - $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' $sql_extra LIMIT 1", - dbesc($hash) - ); + $r = q( + "SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' $sql_extra LIMIT 1", + dbesc($hash) + ); - return(($r) ? array_shift($r) : false); + return(($r) ? array_shift($r) : false); } @@ -1960,20 +2076,24 @@ function channelx_by_hash($hash, $include_removed = false) { * @return array|bool false if channel ID not found, otherwise the channel array */ -function channelx_by_n($id, $include_removed = false) { +function channelx_by_n($id, $include_removed = false) +{ - $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); + $sql_extra = (($include_removed) ? "" : " and channel_removed = 0 "); - if (App::$channel && is_array(App::$channel) && array_key_exists('channel_id',App::$channel) - && array_key_exists('xchan_hash',App::$channel) && intval(App::$channel['channel_id']) === intval($id)) { - return App::$channel; - } + if ( + App::$channel && is_array(App::$channel) && array_key_exists('channel_id', App::$channel) + && array_key_exists('xchan_hash', App::$channel) && intval(App::$channel['channel_id']) === intval($id) + ) { + return App::$channel; + } - $r = q("SELECT * FROM channel LEFT JOIN xchan ON channel_hash = xchan_hash WHERE channel_id = %d $sql_extra LIMIT 1", - dbesc($id) - ); + $r = q( + "SELECT * FROM channel LEFT JOIN xchan ON channel_hash = xchan_hash WHERE channel_id = %d $sql_extra LIMIT 1", + dbesc($id) + ); - return(($r) ? array_shift($r) : false); + return(($r) ? array_shift($r) : false); } /** @@ -1983,11 +2103,13 @@ function channelx_by_n($id, $include_removed = false) { * @return string */ -function channel_reddress($channel) { - if(! ($channel && array_key_exists('channel_address', $channel))) - return ''; +function channel_reddress($channel) +{ + if (! ($channel && array_key_exists('channel_address', $channel))) { + return ''; + } - return strtolower($channel['channel_address'] . '@' . App::get_hostname()); + return strtolower($channel['channel_address'] . '@' . App::get_hostname()); } @@ -2001,10 +2123,11 @@ function channel_reddress($channel) { * @return int */ -function channel_manual_conv_update($channel_id) { +function channel_manual_conv_update($channel_id) +{ - $x = get_pconfig($channel_id, 'system', 'manual_conversation_update', get_config('system', 'manual_conversation_update', 1)); - return intval($x); + $x = get_pconfig($channel_id, 'system', 'manual_conversation_update', get_config('system', 'manual_conversation_update', 1)); + return intval($x); } @@ -2013,108 +2136,111 @@ function channel_manual_conv_update($channel_id) { * * @return string with parsed HTML from \e remote_login template */ -function remote_login() { - $o = replace_macros(get_markup_template('remote_login.tpl'),array( - '$title' => t('Remote Authentication'), - '$desc' => t('Enter your channel address (e.g. channel@example.com)'), - '$submit' => t('Authenticate') - )); +function remote_login() +{ + $o = replace_macros(get_markup_template('remote_login.tpl'), array( + '$title' => t('Remote Authentication'), + '$desc' => t('Enter your channel address (e.g. channel@example.com)'), + '$submit' => t('Authenticate') + )); - return $o; + return $o; } -function channel_store_lowlevel($arr) { - $store = [ - 'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'), - 'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'), - 'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''), - 'channel_parent' => ((array_key_exists('channel_parent',$arr)) ? $arr['channel_parent'] : ''), - 'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''), - 'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''), - 'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''), - 'channel_hash' => ((array_key_exists('channel_hash',$arr)) ? $arr['channel_hash'] : ''), - 'channel_timezone' => ((array_key_exists('channel_timezone',$arr)) ? $arr['channel_timezone'] : 'UTC'), - 'channel_location' => ((array_key_exists('channel_location',$arr)) ? $arr['channel_location'] : ''), - 'channel_theme' => ((array_key_exists('channel_theme',$arr)) ? $arr['channel_theme'] : ''), - 'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''), - 'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''), - 'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''), - 'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'), - 'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'), - 'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE), - 'channel_lastpost' => ((array_key_exists('channel_lastpost',$arr)) ? $arr['channel_lastpost'] : NULL_DATE), - 'channel_deleted' => ((array_key_exists('channel_deleted',$arr)) ? $arr['channel_deleted'] : NULL_DATE), - 'channel_active' => ((array_key_exists('channel_active',$arr)) ? $arr['channel_active'] : NULL_DATE), - 'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail',$arr)) ? $arr['channel_max_anon_mail'] : '10'), - 'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req',$arr)) ? $arr['channel_max_friend_req'] : '10'), - 'channel_expire_days' => ((array_key_exists('channel_expire_days',$arr)) ? $arr['channel_expire_days'] : '0'), - 'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset',$arr)) ? $arr['channel_passwd_reset'] : ''), - 'channel_default_group' => ((array_key_exists('channel_default_group',$arr)) ? $arr['channel_default_group'] : ''), - 'channel_allow_cid' => ((array_key_exists('channel_allow_cid',$arr)) ? $arr['channel_allow_cid'] : ''), - 'channel_allow_gid' => ((array_key_exists('channel_allow_gid',$arr)) ? $arr['channel_allow_gid'] : ''), - 'channel_deny_cid' => ((array_key_exists('channel_deny_cid',$arr)) ? $arr['channel_deny_cid'] : ''), - 'channel_deny_gid' => ((array_key_exists('channel_deny_gid',$arr)) ? $arr['channel_deny_gid'] : ''), - 'channel_removed' => ((array_key_exists('channel_removed',$arr)) ? $arr['channel_removed'] : '0'), - 'channel_system' => ((array_key_exists('channel_system',$arr)) ? $arr['channel_system'] : '0'), - 'channel_moved' => ((array_key_exists('channel_moved',$arr)) ? $arr['channel_moved'] : ''), - 'channel_password' => ((array_key_exists('channel_password',$arr)) ? $arr['channel_password'] : ''), - 'channel_salt' => ((array_key_exists('channel_salt',$arr)) ? $arr['channel_salt'] : '') - ]; +function channel_store_lowlevel($arr) +{ + $store = [ + 'channel_account_id' => ((array_key_exists('channel_account_id', $arr)) ? $arr['channel_account_id'] : '0'), + 'channel_primary' => ((array_key_exists('channel_primary', $arr)) ? $arr['channel_primary'] : '0'), + 'channel_name' => ((array_key_exists('channel_name', $arr)) ? $arr['channel_name'] : ''), + 'channel_parent' => ((array_key_exists('channel_parent', $arr)) ? $arr['channel_parent'] : ''), + 'channel_address' => ((array_key_exists('channel_address', $arr)) ? $arr['channel_address'] : ''), + 'channel_guid' => ((array_key_exists('channel_guid', $arr)) ? $arr['channel_guid'] : ''), + 'channel_guid_sig' => ((array_key_exists('channel_guid_sig', $arr)) ? $arr['channel_guid_sig'] : ''), + 'channel_hash' => ((array_key_exists('channel_hash', $arr)) ? $arr['channel_hash'] : ''), + 'channel_timezone' => ((array_key_exists('channel_timezone', $arr)) ? $arr['channel_timezone'] : 'UTC'), + 'channel_location' => ((array_key_exists('channel_location', $arr)) ? $arr['channel_location'] : ''), + 'channel_theme' => ((array_key_exists('channel_theme', $arr)) ? $arr['channel_theme'] : ''), + 'channel_startpage' => ((array_key_exists('channel_startpage', $arr)) ? $arr['channel_startpage'] : ''), + 'channel_pubkey' => ((array_key_exists('channel_pubkey', $arr)) ? $arr['channel_pubkey'] : ''), + 'channel_prvkey' => ((array_key_exists('channel_prvkey', $arr)) ? $arr['channel_prvkey'] : ''), + 'channel_notifyflags' => ((array_key_exists('channel_notifyflags', $arr)) ? $arr['channel_notifyflags'] : '65535'), + 'channel_pageflags' => ((array_key_exists('channel_pageflags', $arr)) ? $arr['channel_pageflags'] : '0'), + 'channel_dirdate' => ((array_key_exists('channel_dirdate', $arr)) ? $arr['channel_dirdate'] : NULL_DATE), + 'channel_lastpost' => ((array_key_exists('channel_lastpost', $arr)) ? $arr['channel_lastpost'] : NULL_DATE), + 'channel_deleted' => ((array_key_exists('channel_deleted', $arr)) ? $arr['channel_deleted'] : NULL_DATE), + 'channel_active' => ((array_key_exists('channel_active', $arr)) ? $arr['channel_active'] : NULL_DATE), + 'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail', $arr)) ? $arr['channel_max_anon_mail'] : '10'), + 'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req', $arr)) ? $arr['channel_max_friend_req'] : '10'), + 'channel_expire_days' => ((array_key_exists('channel_expire_days', $arr)) ? $arr['channel_expire_days'] : '0'), + 'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset', $arr)) ? $arr['channel_passwd_reset'] : ''), + 'channel_default_group' => ((array_key_exists('channel_default_group', $arr)) ? $arr['channel_default_group'] : ''), + 'channel_allow_cid' => ((array_key_exists('channel_allow_cid', $arr)) ? $arr['channel_allow_cid'] : ''), + 'channel_allow_gid' => ((array_key_exists('channel_allow_gid', $arr)) ? $arr['channel_allow_gid'] : ''), + 'channel_deny_cid' => ((array_key_exists('channel_deny_cid', $arr)) ? $arr['channel_deny_cid'] : ''), + 'channel_deny_gid' => ((array_key_exists('channel_deny_gid', $arr)) ? $arr['channel_deny_gid'] : ''), + 'channel_removed' => ((array_key_exists('channel_removed', $arr)) ? $arr['channel_removed'] : '0'), + 'channel_system' => ((array_key_exists('channel_system', $arr)) ? $arr['channel_system'] : '0'), + 'channel_moved' => ((array_key_exists('channel_moved', $arr)) ? $arr['channel_moved'] : ''), + 'channel_password' => ((array_key_exists('channel_password', $arr)) ? $arr['channel_password'] : ''), + 'channel_salt' => ((array_key_exists('channel_salt', $arr)) ? $arr['channel_salt'] : '') + ]; - return create_table_from_array('channel', $store); + return create_table_from_array('channel', $store); } -function profile_store_lowlevel($arr) { +function profile_store_lowlevel($arr) +{ $store = [ - 'profile_guid' => ((array_key_exists('profile_guid',$arr)) ? $arr['profile_guid'] : ''), - 'aid' => ((array_key_exists('aid',$arr)) ? $arr['aid'] : 0), - 'uid' => ((array_key_exists('uid',$arr)) ? $arr['uid'] : 0), - 'profile_name' => ((array_key_exists('profile_name',$arr)) ? $arr['profile_name'] : ''), - 'is_default' => ((array_key_exists('is_default',$arr)) ? $arr['is_default'] : 0), - 'hide_friends' => ((array_key_exists('hide_friends',$arr)) ? $arr['hide_friends'] : 0), - 'fullname' => ((array_key_exists('fullname',$arr)) ? $arr['fullname'] : ''), - 'pdesc' => ((array_key_exists('pdesc',$arr)) ? $arr['pdesc'] : ''), - 'chandesc' => ((array_key_exists('chandesc',$arr)) ? $arr['chandesc'] : ''), - 'dob' => ((array_key_exists('dob',$arr)) ? $arr['dob'] : ''), - 'dob_tz' => ((array_key_exists('dob_tz',$arr)) ? $arr['dob_tz'] : ''), - 'address' => ((array_key_exists('address',$arr)) ? $arr['address'] : ''), - 'locality' => ((array_key_exists('locality',$arr)) ? $arr['locality'] : ''), - 'region' => ((array_key_exists('region',$arr)) ? $arr['region'] : ''), - 'postal_code' => ((array_key_exists('postal_code',$arr)) ? $arr['postal_code'] : ''), - 'country_name' => ((array_key_exists('country_name',$arr)) ? $arr['country_name'] : ''), - 'hometown' => ((array_key_exists('hometown',$arr)) ? $arr['hometown'] : ''), - 'gender' => ((array_key_exists('gender',$arr)) ? $arr['gender'] : ''), - 'marital' => ((array_key_exists('marital',$arr)) ? $arr['marital'] : ''), - 'partner' => ((array_key_exists('partner',$arr)) ? $arr['partner'] : ''), - 'howlong' => ((array_key_exists('howlong',$arr)) ? $arr['howlong'] : NULL_DATE), - 'sexual' => ((array_key_exists('sexual',$arr)) ? $arr['sexual'] : ''), - 'pronouns' => ((array_key_exists('pronouns',$arr)) ? $arr['pronouns'] : ''), - 'politic' => ((array_key_exists('politic',$arr)) ? $arr['politic'] : ''), - 'religion' => ((array_key_exists('religion',$arr)) ? $arr['religion'] : ''), - 'keywords' => ((array_key_exists('keywords',$arr)) ? $arr['keywords'] : ''), - 'likes' => ((array_key_exists('likes',$arr)) ? $arr['likes'] : ''), - 'dislikes' => ((array_key_exists('dislikes',$arr)) ? $arr['dislikes'] : ''), - 'about' => ((array_key_exists('about',$arr)) ? $arr['about'] : ''), - 'summary' => ((array_key_exists('summary',$arr)) ? $arr['summary'] : ''), - 'music' => ((array_key_exists('music',$arr)) ? $arr['music'] : ''), - 'book' => ((array_key_exists('book',$arr)) ? $arr['book'] : ''), - 'tv' => ((array_key_exists('tv',$arr)) ? $arr['tv'] : ''), - 'film' => ((array_key_exists('film',$arr)) ? $arr['film'] : ''), - 'interest' => ((array_key_exists('interest',$arr)) ? $arr['interest'] : ''), - 'romance' => ((array_key_exists('romance',$arr)) ? $arr['romance'] : ''), - 'employment' => ((array_key_exists('employment',$arr)) ? $arr['employment'] : ''), - 'education' => ((array_key_exists('education',$arr)) ? $arr['education'] : ''), - 'contact' => ((array_key_exists('contact',$arr)) ? $arr['contact'] : ''), - 'channels' => ((array_key_exists('channels',$arr)) ? $arr['channels'] : ''), - 'homepage' => ((array_key_exists('homepage',$arr)) ? $arr['homepage'] : ''), - 'photo' => ((array_key_exists('photo',$arr)) ? $arr['photo'] : ''), - 'thumb' => ((array_key_exists('thumb',$arr)) ? $arr['thumb'] : ''), - 'publish' => ((array_key_exists('publish',$arr)) ? $arr['publish'] : 0), - 'profile_vcard' => ((array_key_exists('profile_vcard',$arr)) ? $arr['profile_vcard'] : '') - ]; + 'profile_guid' => ((array_key_exists('profile_guid', $arr)) ? $arr['profile_guid'] : ''), + 'aid' => ((array_key_exists('aid', $arr)) ? $arr['aid'] : 0), + 'uid' => ((array_key_exists('uid', $arr)) ? $arr['uid'] : 0), + 'profile_name' => ((array_key_exists('profile_name', $arr)) ? $arr['profile_name'] : ''), + 'is_default' => ((array_key_exists('is_default', $arr)) ? $arr['is_default'] : 0), + 'hide_friends' => ((array_key_exists('hide_friends', $arr)) ? $arr['hide_friends'] : 0), + 'fullname' => ((array_key_exists('fullname', $arr)) ? $arr['fullname'] : ''), + 'pdesc' => ((array_key_exists('pdesc', $arr)) ? $arr['pdesc'] : ''), + 'chandesc' => ((array_key_exists('chandesc', $arr)) ? $arr['chandesc'] : ''), + 'dob' => ((array_key_exists('dob', $arr)) ? $arr['dob'] : ''), + 'dob_tz' => ((array_key_exists('dob_tz', $arr)) ? $arr['dob_tz'] : ''), + 'address' => ((array_key_exists('address', $arr)) ? $arr['address'] : ''), + 'locality' => ((array_key_exists('locality', $arr)) ? $arr['locality'] : ''), + 'region' => ((array_key_exists('region', $arr)) ? $arr['region'] : ''), + 'postal_code' => ((array_key_exists('postal_code', $arr)) ? $arr['postal_code'] : ''), + 'country_name' => ((array_key_exists('country_name', $arr)) ? $arr['country_name'] : ''), + 'hometown' => ((array_key_exists('hometown', $arr)) ? $arr['hometown'] : ''), + 'gender' => ((array_key_exists('gender', $arr)) ? $arr['gender'] : ''), + 'marital' => ((array_key_exists('marital', $arr)) ? $arr['marital'] : ''), + 'partner' => ((array_key_exists('partner', $arr)) ? $arr['partner'] : ''), + 'howlong' => ((array_key_exists('howlong', $arr)) ? $arr['howlong'] : NULL_DATE), + 'sexual' => ((array_key_exists('sexual', $arr)) ? $arr['sexual'] : ''), + 'pronouns' => ((array_key_exists('pronouns', $arr)) ? $arr['pronouns'] : ''), + 'politic' => ((array_key_exists('politic', $arr)) ? $arr['politic'] : ''), + 'religion' => ((array_key_exists('religion', $arr)) ? $arr['religion'] : ''), + 'keywords' => ((array_key_exists('keywords', $arr)) ? $arr['keywords'] : ''), + 'likes' => ((array_key_exists('likes', $arr)) ? $arr['likes'] : ''), + 'dislikes' => ((array_key_exists('dislikes', $arr)) ? $arr['dislikes'] : ''), + 'about' => ((array_key_exists('about', $arr)) ? $arr['about'] : ''), + 'summary' => ((array_key_exists('summary', $arr)) ? $arr['summary'] : ''), + 'music' => ((array_key_exists('music', $arr)) ? $arr['music'] : ''), + 'book' => ((array_key_exists('book', $arr)) ? $arr['book'] : ''), + 'tv' => ((array_key_exists('tv', $arr)) ? $arr['tv'] : ''), + 'film' => ((array_key_exists('film', $arr)) ? $arr['film'] : ''), + 'interest' => ((array_key_exists('interest', $arr)) ? $arr['interest'] : ''), + 'romance' => ((array_key_exists('romance', $arr)) ? $arr['romance'] : ''), + 'employment' => ((array_key_exists('employment', $arr)) ? $arr['employment'] : ''), + 'education' => ((array_key_exists('education', $arr)) ? $arr['education'] : ''), + 'contact' => ((array_key_exists('contact', $arr)) ? $arr['contact'] : ''), + 'channels' => ((array_key_exists('channels', $arr)) ? $arr['channels'] : ''), + 'homepage' => ((array_key_exists('homepage', $arr)) ? $arr['homepage'] : ''), + 'photo' => ((array_key_exists('photo', $arr)) ? $arr['photo'] : ''), + 'thumb' => ((array_key_exists('thumb', $arr)) ? $arr['thumb'] : ''), + 'publish' => ((array_key_exists('publish', $arr)) ? $arr['publish'] : 0), + 'profile_vcard' => ((array_key_exists('profile_vcard', $arr)) ? $arr['profile_vcard'] : '') + ]; - return create_table_from_array('profile',$store); + return create_table_from_array('profile', $store); } @@ -2129,60 +2255,65 @@ function profile_store_lowlevel($arr) { * @return bool|array */ -function account_remove($account_id, $local = true, $unset_session = true) { +function account_remove($account_id, $local = true, $unset_session = true) +{ - logger('account_remove: ' . $account_id); + logger('account_remove: ' . $account_id); - // Global removal (all clones) not currently supported - $local = true; + // Global removal (all clones) not currently supported + $local = true; - if (! intval($account_id)) { - logger('No account.'); - return false; - } + if (! intval($account_id)) { + logger('No account.'); + return false; + } - // Don't let anybody nuke the only admin account. + // Don't let anybody nuke the only admin account. - $r = q("select account_id from account where (account_roles & %d) > 0", - intval(ACCOUNT_ROLE_ADMIN) - ); + $r = q( + "select account_id from account where (account_roles & %d) > 0", + intval(ACCOUNT_ROLE_ADMIN) + ); - if ($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) { - logger("Unable to remove the only remaining admin account"); - return false; - } + if ($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) { + logger("Unable to remove the only remaining admin account"); + return false; + } - $r = q("select * from account where account_id = %d limit 1", - intval($account_id) - ); - - if (! $r) { - logger('No account with id: ' . $account_id); - return false; - } + $r = q( + "select * from account where account_id = %d limit 1", + intval($account_id) + ); - $account_email = $r[0]['account_email']; + if (! $r) { + logger('No account with id: ' . $account_id); + return false; + } - $x = q("select channel_id from channel where channel_account_id = %d", - intval($account_id) - ); - if ($x) { - foreach ($x as $xx) { - channel_remove($xx['channel_id'],$local,false); - } - } + $account_email = $r[0]['account_email']; - $r = q("delete from account where account_id = %d", - intval($account_id) - ); + $x = q( + "select channel_id from channel where channel_account_id = %d", + intval($account_id) + ); + if ($x) { + foreach ($x as $xx) { + channel_remove($xx['channel_id'], $local, false); + } + } - if ($unset_session) { - App::$session->nuke(); - notice( sprintf(t('Account \'%s\' deleted'),$account_email) . EOL); - goaway(z_root()); - } + $r = q( + "delete from account where account_id = %d", + intval($account_id) + ); - return $r; + if ($unset_session) { + App::$session->nuke(); + notice(sprintf(t('Account \'%s\' deleted'), $account_email) . EOL); + goaway(z_root()); + } + + return $r; } /** @@ -2193,160 +2324,172 @@ function account_remove($account_id, $local = true, $unset_session = true) { * @param bool $unset_session default false */ -function channel_remove($channel_id, $local = true, $unset_session = false) { +function channel_remove($channel_id, $local = true, $unset_session = false) +{ - if (! $channel_id) { - return; - } + if (! $channel_id) { + return; + } - // global removal (all clones) not currently supported - // hence this operation _may_ leave orphan data on remote servers - - $local = true; + // global removal (all clones) not currently supported + // hence this operation _may_ leave orphan data on remote servers - logger('Removing channel: ' . $channel_id); - logger('local only: ' . intval($local)); + $local = true; - - $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id)); - if (! $r) { - logger('channel not found: ' . $channel_id); - return; - } + logger('Removing channel: ' . $channel_id); + logger('local only: ' . intval($local)); - $channel = $r[0]; - /** - * @hooks channel_remove - * Called when removing a channel. - * * \e array with entry from channel tabel for $channel_id - */ + $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id)); + if (! $r) { + logger('channel not found: ' . $channel_id); + return; + } - call_hooks('channel_remove', $channel); + $channel = $r[0]; - $r = q("select iid from iconfig left join item on item.id = iconfig.iid + /** + * @hooks channel_remove + * Called when removing a channel. + * * \e array with entry from channel tabel for $channel_id + */ + + call_hooks('channel_remove', $channel); + + $r = q( + "select iid from iconfig left join item on item.id = iconfig.iid where item.uid = %d", - intval($channel_id) - ); - if ($r) { - foreach ($r as $rr) { - q("delete from iconfig where iid = %d", - intval($rr['iid']) - ); - } - } + intval($channel_id) + ); + if ($r) { + foreach ($r as $rr) { + q( + "delete from iconfig where iid = %d", + intval($rr['iid']) + ); + } + } - q("DELETE FROM app WHERE app_channel = %d", intval($channel_id)); - q("DELETE FROM atoken WHERE atoken_uid = %d", intval($channel_id)); - q("DELETE FROM chatroom WHERE cr_uid = %d", intval($channel_id)); - q("DELETE FROM conv WHERE uid = %d", intval($channel_id)); + q("DELETE FROM app WHERE app_channel = %d", intval($channel_id)); + q("DELETE FROM atoken WHERE atoken_uid = %d", intval($channel_id)); + q("DELETE FROM chatroom WHERE cr_uid = %d", intval($channel_id)); + q("DELETE FROM conv WHERE uid = %d", intval($channel_id)); - q("DELETE FROM pgrp WHERE uid = %d", intval($channel_id)); - q("DELETE FROM pgrp_member WHERE uid = %d", intval($channel_id)); - q("DELETE FROM event WHERE uid = %d", intval($channel_id)); - q("DELETE FROM menu WHERE menu_channel_id = %d", intval($channel_id)); - q("DELETE FROM menu_item WHERE mitem_channel_id = %d", intval($channel_id)); + q("DELETE FROM pgrp WHERE uid = %d", intval($channel_id)); + q("DELETE FROM pgrp_member WHERE uid = %d", intval($channel_id)); + q("DELETE FROM event WHERE uid = %d", intval($channel_id)); + q("DELETE FROM menu WHERE menu_channel_id = %d", intval($channel_id)); + q("DELETE FROM menu_item WHERE mitem_channel_id = %d", intval($channel_id)); - q("DELETE FROM notify WHERE uid = %d", intval($channel_id)); - q("DELETE FROM obj WHERE obj_channel = %d", intval($channel_id)); + q("DELETE FROM notify WHERE uid = %d", intval($channel_id)); + q("DELETE FROM obj WHERE obj_channel = %d", intval($channel_id)); - q("DELETE FROM photo WHERE uid = %d", intval($channel_id)); - q("DELETE FROM attach WHERE uid = %d", intval($channel_id)); - q("DELETE FROM profile WHERE uid = %d", intval($channel_id)); - q("DELETE FROM source WHERE src_channel_id = %d", intval($channel_id)); + q("DELETE FROM photo WHERE uid = %d", intval($channel_id)); + q("DELETE FROM attach WHERE uid = %d", intval($channel_id)); + q("DELETE FROM profile WHERE uid = %d", intval($channel_id)); + q("DELETE FROM source WHERE src_channel_id = %d", intval($channel_id)); - $r = q("select hash FROM attach WHERE uid = %d", intval($channel_id)); - if ($r) { - foreach ($r as $rv) { - attach_delete($channel_id,$rv['hash']); - } - } + $r = q("select hash FROM attach WHERE uid = %d", intval($channel_id)); + if ($r) { + foreach ($r as $rv) { + attach_delete($channel_id, $rv['hash']); + } + } - - q("delete from abook where abook_xchan = '%s' and abook_self = 1 ", - dbesc($channel['channel_hash']) - ); - $r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d", - dbesc(datetime_convert()), - intval($channel_id) - ); + q( + "delete from abook where abook_xchan = '%s' and abook_self = 1 ", + dbesc($channel['channel_hash']) + ); - // remove items - - Run::Summon( [ 'Channel_purge', $channel_id ] ); + $r = q( + "update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d", + dbesc(datetime_convert()), + intval($channel_id) + ); - // if this was the default channel, set another one as default + // remove items - if (App::$account['account_default_channel'] == $channel_id) { - $r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1", - intval(App::$account['account_id']), - intval(PAGE_REMOVED)); - if ($r) { - $rr = q("update account set account_default_channel = %d where account_id = %d", - intval($r[0]['channel_id']), - intval(App::$account['account_id']) - ); - logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']); - } - else { - $rr = q("update account set account_default_channel = 0 where account_id = %d", - intval(App::$account['account_id']) - ); - } - } + Run::Summon([ 'Channel_purge', $channel_id ]); - logger('deleting hublocs',LOGGER_DEBUG); + // if this was the default channel, set another one as default - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ", - dbesc($channel['channel_hash']), - dbesc(z_root()) - ); + if (App::$account['account_default_channel'] == $channel_id) { + $r = q( + "select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1", + intval(App::$account['account_id']), + intval(PAGE_REMOVED) + ); + if ($r) { + $rr = q( + "update account set account_default_channel = %d where account_id = %d", + intval($r[0]['channel_id']), + intval(App::$account['account_id']) + ); + logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']); + } else { + $rr = q( + "update account set account_default_channel = 0 where account_id = %d", + intval(App::$account['account_id']) + ); + } + } - // Do we have any valid hublocs remaining? + logger('deleting hublocs', LOGGER_DEBUG); - $hublocs = 0; + $r = q( + "update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ", + dbesc($channel['channel_hash']), + dbesc(z_root()) + ); - $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", - dbesc($channel['channel_hash']) - ); - if ($r) { - $hublocs = count($r); - } - - if (! $hublocs) { - $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ", - dbesc($channel['channel_hash']) - ); - // send a cleanup message to other servers - Run::Summon( [ 'Notifier', 'purge_all', $channel_id ] ); - } + // Do we have any valid hublocs remaining? - //remove from file system + $hublocs = 0; - $f = 'store/' . $channel['channel_address']; - // This shouldn't happen but make sure the address isn't empty because that could do bad things - if (is_dir($f) && $channel['channel_address']) { - @rrmdir($f); - } + $r = q( + "select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", + dbesc($channel['channel_hash']) + ); + if ($r) { + $hublocs = count($r); + } - Run::Summon([ 'Directory', $channel_id ]); + if (! $hublocs) { + $r = q( + "update xchan set xchan_deleted = 1 where xchan_hash = '%s' ", + dbesc($channel['channel_hash']) + ); + // send a cleanup message to other servers + Run::Summon([ 'Notifier', 'purge_all', $channel_id ]); + } - if ($channel_id == local_channel() && $unset_session) { - App::$session->nuke(); - goaway(z_root()); - } + //remove from file system + + $f = 'store/' . $channel['channel_address']; + // This shouldn't happen but make sure the address isn't empty because that could do bad things + if (is_dir($f) && $channel['channel_address']) { + @rrmdir($f); + } + + Run::Summon([ 'Directory', $channel_id ]); + + if ($channel_id == local_channel() && $unset_session) { + App::$session->nuke(); + goaway(z_root()); + } } // execute this at least a week after removing a channel -function channel_remove_final($channel_id) { +function channel_remove_final($channel_id) +{ - q("delete from abook where abook_channel = %d", intval($channel_id)); - q("delete from abconfig where chan = %d", intval($channel_id)); - q("delete from pconfig where uid = %d", intval($channel_id)); - q("delete from channel where channel_id = %d", intval($channel_id)); + q("delete from abook where abook_channel = %d", intval($channel_id)); + q("delete from abconfig where chan = %d", intval($channel_id)); + q("delete from pconfig where uid = %d", intval($channel_id)); + q("delete from channel where channel_id = %d", intval($channel_id)); } @@ -2359,117 +2502,129 @@ function channel_remove_final($channel_id) { * @param int $channel_id * @return bool */ -function channel_codeallowed($channel_id) { - if(! intval($channel_id)) - return false; +function channel_codeallowed($channel_id) +{ + if (! intval($channel_id)) { + return false; + } - $x = channelx_by_n($channel_id); - if(($x) && ($x['channel_pageflags'] & PAGE_ALLOWCODE)) - return true; + $x = channelx_by_n($channel_id); + if (($x) && ($x['channel_pageflags'] & PAGE_ALLOWCODE)) { + return true; + } - return false; + return false; } -function anon_identity_init($reqvars) { +function anon_identity_init($reqvars) +{ - $x = [ - 'request_vars' => $reqvars, - 'xchan' => null, - 'success' => 'unset' - ]; - /** - * @hooks anon_identity_init - * * \e array \b request_vars - * * \e string \b xchan - return value - * * \e string|int \b success - Must be a number, so xchan return value gets used - */ - call_hooks('anon_identity_init', $x); + $x = [ + 'request_vars' => $reqvars, + 'xchan' => null, + 'success' => 'unset' + ]; + /** + * @hooks anon_identity_init + * * \e array \b request_vars + * * \e string \b xchan - return value + * * \e string|int \b success - Must be a number, so xchan return value gets used + */ + call_hooks('anon_identity_init', $x); - if($x['success'] !== 'unset' && intval($x['success']) && $x['xchan']) - return $x['xchan']; + if ($x['success'] !== 'unset' && intval($x['success']) && $x['xchan']) { + return $x['xchan']; + } - // allow a captcha handler to over-ride - if($x['success'] !== 'unset' && (intval($x['success']) === 0)) - return false; + // allow a captcha handler to over-ride + if ($x['success'] !== 'unset' && (intval($x['success']) === 0)) { + return false; + } - $anon_name = strip_tags(trim($reqvars['anonname'])); - $anon_email = strip_tags(trim($reqvars['anonmail'])); - $anon_url = strip_tags(trim($reqvars['anonurl'])); + $anon_name = strip_tags(trim($reqvars['anonname'])); + $anon_email = strip_tags(trim($reqvars['anonmail'])); + $anon_url = strip_tags(trim($reqvars['anonurl'])); - if(! ($anon_name && $anon_email)) { - logger('anonymous commenter did not complete form'); - return false; - } + if (! ($anon_name && $anon_email)) { + logger('anonymous commenter did not complete form'); + return false; + } - if(! validate_email($anon_email)) { - logger('enonymous email not valid'); - return false; - } + if (! validate_email($anon_email)) { + logger('enonymous email not valid'); + return false; + } - if(! $anon_url) - $anon_url = z_root(); + if (! $anon_url) { + $anon_url = z_root(); + } - $hash = hash('md5',$anon_email); + $hash = hash('md5', $anon_email); - $x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1", - dbesc($anon_email), - dbesc($hash) - ); + $x = q( + "select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1", + dbesc($anon_email), + dbesc($hash) + ); - if(! $x) { - xchan_store_lowlevel([ - 'xchan_guid' => $anon_email, - 'xchan_hash' => $hash, - 'xchan_name' => $anon_name, - 'xchan_url' => $anon_url, - 'xchan_network' => 'anon', - 'xchan_updated' => datetime_convert(), - 'xchan_name_date' => datetime_convert() - ]); + if (! $x) { + xchan_store_lowlevel([ + 'xchan_guid' => $anon_email, + 'xchan_hash' => $hash, + 'xchan_name' => $anon_name, + 'xchan_url' => $anon_url, + 'xchan_network' => 'anon', + 'xchan_updated' => datetime_convert(), + 'xchan_name_date' => datetime_convert() + ]); - $x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1", - dbesc($anon_email), - dbesc($hash) - ); + $x = q( + "select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1", + dbesc($anon_email), + dbesc($hash) + ); - $photo = z_root() . '/' . get_default_profile_photo(300); - $photos = import_remote_xchan_photo($photo,$hash); - if ($photos) { - $r = q("update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' ", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($anon_email), - dbesc($hash) - ); - } - } + $photo = z_root() . '/' . get_default_profile_photo(300); + $photos = import_remote_xchan_photo($photo, $hash); + if ($photos) { + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' ", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($anon_email), + dbesc($hash) + ); + } + } - return $x[0]; + return $x[0]; } -function channel_url($channel) { +function channel_url($channel) +{ - // data validation - if this is wrong, log the call stack so we can find the issue + // data validation - if this is wrong, log the call stack so we can find the issue - if (! is_array($channel)) { - btlogger('not a channel array: ' . print_r($channel,true)); - } + if (! is_array($channel)) { + btlogger('not a channel array: ' . print_r($channel, true)); + } - if ($channel['channel_address'] === App::get_hostname() || intval($channel['channel_system'])) { - return z_root(); - } + if ($channel['channel_address'] === App::get_hostname() || intval($channel['channel_system'])) { + return z_root(); + } - return (($channel) ? z_root() . '/channel/' . $channel['channel_address'] : z_root()); + return (($channel) ? z_root() . '/channel/' . $channel['channel_address'] : z_root()); } -function is_group($uid) { - $role = get_pconfig($uid,'system','permissions_role'); - $rolesettings = PermissionRoles::role_perms($role); - return ((isset($rolesettings['channel_type']) && $rolesettings['channel_type'] === 'group') ? true : false); +function is_group($uid) +{ + $role = get_pconfig($uid, 'system', 'permissions_role'); + $rolesettings = PermissionRoles::role_perms($role); + return ((isset($rolesettings['channel_type']) && $rolesettings['channel_type'] === 'group') ? true : false); } diff --git a/include/cli_startup.php b/include/cli_startup.php index cf99836d6..faf4792b2 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -4,9 +4,9 @@ require_once('boot.php'); // Everything we need to boot standalone 'background' processes -function cli_startup() { +function cli_startup() +{ - sys_boot(); - App::set_baseurl(get_config('system','baseurl')); - -} \ No newline at end of file + sys_boot(); + App::set_baseurl(get_config('system', 'baseurl')); +} diff --git a/include/config.php b/include/config.php index 0be791715..214ed56d9 100644 --- a/include/config.php +++ b/include/config.php @@ -1,4 +1,5 @@ ((array_key_exists('abook_account',$arr)) ? $arr['abook_account'] : 0), - 'abook_channel' => ((array_key_exists('abook_channel',$arr)) ? $arr['abook_channel'] : 0), - 'abook_xchan' => ((array_key_exists('abook_xchan',$arr)) ? $arr['abook_xchan'] : ''), - 'abook_alias' => ((array_key_exists('abook_alias',$arr)) ? $arr['abook_alias'] : ''), - 'abook_my_perms' => ((array_key_exists('abook_my_perms',$arr)) ? $arr['abook_my_perms'] : 0), - 'abook_their_perms' => ((array_key_exists('abook_their_perms',$arr)) ? $arr['abook_their_perms'] : 0), - 'abook_closeness' => ((array_key_exists('abook_closeness',$arr)) ? $arr['abook_closeness'] : 99), - 'abook_created' => ((array_key_exists('abook_created',$arr)) ? $arr['abook_created'] : NULL_DATE), - 'abook_updated' => ((array_key_exists('abook_updated',$arr)) ? $arr['abook_updated'] : NULL_DATE), - 'abook_connected' => ((array_key_exists('abook_connected',$arr)) ? $arr['abook_connected'] : NULL_DATE), - 'abook_dob' => ((array_key_exists('abook_dob',$arr)) ? $arr['abook_dob'] : NULL_DATE), - 'abook_flags' => ((array_key_exists('abook_flags',$arr)) ? $arr['abook_flags'] : 0), - 'abook_censor' => ((array_key_exists('abook_censor',$arr)) ? $arr['abook_censor'] : 0), - 'abook_blocked' => ((array_key_exists('abook_blocked',$arr)) ? $arr['abook_blocked'] : 0), - 'abook_ignored' => ((array_key_exists('abook_ignored',$arr)) ? $arr['abook_ignored'] : 0), - 'abook_hidden' => ((array_key_exists('abook_hidden',$arr)) ? $arr['abook_hidden'] : 0), - 'abook_archived' => ((array_key_exists('abook_archived',$arr)) ? $arr['abook_archived'] : 0), - 'abook_pending' => ((array_key_exists('abook_pending',$arr)) ? $arr['abook_pending'] : 0), - 'abook_unconnected' => ((array_key_exists('abook_unconnected',$arr)) ? $arr['abook_unconnected'] : 0), - 'abook_self' => ((array_key_exists('abook_self',$arr)) ? $arr['abook_self'] : 0), - 'abook_feed' => ((array_key_exists('abook_feed',$arr)) ? $arr['abook_feed'] : 0), - 'abook_not_here' => ((array_key_exists('abook_not_here',$arr)) ? $arr['abook_not_here'] : 0), - 'abook_profile' => ((array_key_exists('abook_profile',$arr)) ? $arr['abook_profile'] : ''), - 'abook_incl' => ((array_key_exists('abook_incl',$arr)) ? $arr['abook_incl'] : ''), - 'abook_excl' => ((array_key_exists('abook_excl',$arr)) ? $arr['abook_excl'] : ''), - 'abook_instance' => ((array_key_exists('abook_instance',$arr)) ? $arr['abook_instance'] : '') - ]; - - return create_table_from_array('abook',$store); + $store = [ + 'abook_account' => ((array_key_exists('abook_account', $arr)) ? $arr['abook_account'] : 0), + 'abook_channel' => ((array_key_exists('abook_channel', $arr)) ? $arr['abook_channel'] : 0), + 'abook_xchan' => ((array_key_exists('abook_xchan', $arr)) ? $arr['abook_xchan'] : ''), + 'abook_alias' => ((array_key_exists('abook_alias', $arr)) ? $arr['abook_alias'] : ''), + 'abook_my_perms' => ((array_key_exists('abook_my_perms', $arr)) ? $arr['abook_my_perms'] : 0), + 'abook_their_perms' => ((array_key_exists('abook_their_perms', $arr)) ? $arr['abook_their_perms'] : 0), + 'abook_closeness' => ((array_key_exists('abook_closeness', $arr)) ? $arr['abook_closeness'] : 99), + 'abook_created' => ((array_key_exists('abook_created', $arr)) ? $arr['abook_created'] : NULL_DATE), + 'abook_updated' => ((array_key_exists('abook_updated', $arr)) ? $arr['abook_updated'] : NULL_DATE), + 'abook_connected' => ((array_key_exists('abook_connected', $arr)) ? $arr['abook_connected'] : NULL_DATE), + 'abook_dob' => ((array_key_exists('abook_dob', $arr)) ? $arr['abook_dob'] : NULL_DATE), + 'abook_flags' => ((array_key_exists('abook_flags', $arr)) ? $arr['abook_flags'] : 0), + 'abook_censor' => ((array_key_exists('abook_censor', $arr)) ? $arr['abook_censor'] : 0), + 'abook_blocked' => ((array_key_exists('abook_blocked', $arr)) ? $arr['abook_blocked'] : 0), + 'abook_ignored' => ((array_key_exists('abook_ignored', $arr)) ? $arr['abook_ignored'] : 0), + 'abook_hidden' => ((array_key_exists('abook_hidden', $arr)) ? $arr['abook_hidden'] : 0), + 'abook_archived' => ((array_key_exists('abook_archived', $arr)) ? $arr['abook_archived'] : 0), + 'abook_pending' => ((array_key_exists('abook_pending', $arr)) ? $arr['abook_pending'] : 0), + 'abook_unconnected' => ((array_key_exists('abook_unconnected', $arr)) ? $arr['abook_unconnected'] : 0), + 'abook_self' => ((array_key_exists('abook_self', $arr)) ? $arr['abook_self'] : 0), + 'abook_feed' => ((array_key_exists('abook_feed', $arr)) ? $arr['abook_feed'] : 0), + 'abook_not_here' => ((array_key_exists('abook_not_here', $arr)) ? $arr['abook_not_here'] : 0), + 'abook_profile' => ((array_key_exists('abook_profile', $arr)) ? $arr['abook_profile'] : ''), + 'abook_incl' => ((array_key_exists('abook_incl', $arr)) ? $arr['abook_incl'] : ''), + 'abook_excl' => ((array_key_exists('abook_excl', $arr)) ? $arr['abook_excl'] : ''), + 'abook_instance' => ((array_key_exists('abook_instance', $arr)) ? $arr['abook_instance'] : '') + ]; + return create_table_from_array('abook', $store); } -function rconnect_url($channel_id,$xchan) { +function rconnect_url($channel_id, $xchan) +{ - if (! $xchan) { - return z_root() . '/fedi_id/' . $channel_id; - } + if (! $xchan) { + return z_root() . '/fedi_id/' . $channel_id; + } - $r = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1", - intval($channel_id), - dbesc($xchan) - ); - - // Already connected - if ($r) { - return EMPTY_STR; - } - - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($xchan) - ); + $r = q( + "select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + intval($channel_id), + dbesc($xchan) + ); - if (($r) && ($r[0]['xchan_follow'])) { - return $r[0]['xchan_follow']; - } + // Already connected + if ($r) { + return EMPTY_STR; + } - $r = q("select hubloc_url from hubloc where hubloc_hash = '%s' and hubloc_primary = 1 limit 1", - dbesc($xchan) - ); + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($xchan) + ); - if ($r) { - return $r[0]['hubloc_url'] . '/follow?f=&url=%s'; - } - - return EMPTY_STR; + if (($r) && ($r[0]['xchan_follow'])) { + return $r[0]['xchan_follow']; + } + $r = q( + "select hubloc_url from hubloc where hubloc_hash = '%s' and hubloc_primary = 1 limit 1", + dbesc($xchan) + ); + + if ($r) { + return $r[0]['hubloc_url'] . '/follow?f=&url=%s'; + } + + return EMPTY_STR; } -function abook_connections($channel_id, $sql_conditions = '') { - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d +function abook_connections($channel_id, $sql_conditions = '') +{ + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 $sql_conditions", - intval($channel_id) - ); - return(($r) ? $r : []); -} - - -function abook_by_hash($channel_id, $hash) { - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d - and abook_self = 0 and abook_xchan = '%s'", - intval($channel_id), - dbesc($hash) - ); - return(($r) ? array_shift($r) : false); -} - -function abook_self($channel_id) { - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d - and abook_self = 1 limit 1", - intval($channel_id) - ); - return(($r) ? $r[0] : []); -} - - -function vcard_from_xchan($xchan, $observer = null, $mode = '') { - - if (! $xchan) { - if (App::$poi) { - $xchan = App::$poi; - } - elseif (is_array(App::$profile) && App::$profile['channel_hash']) { - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc(App::$profile['channel_hash']) - ); - if($r) { - $xchan = $r[0]; - } - } - } - - if (! $xchan) { - return; - } - - $connect = false; - if (local_channel()) { - $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", - dbesc($xchan['xchan_hash']), - intval(local_channel()) - ); - if (! $r) { - $connect = t('Connect'); - } - } - - // don't provide a connect button for transient or one-way identities - - if (in_array($xchan['xchan_network'],[ 'rss','anon','token','unknown' ])) { - $connect = false; - } - - if (array_key_exists('channel_id',$xchan)) { - App::$profile_uid = $xchan['channel_id']; - } - - $url = (($observer) - ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($xchan['xchan_url']) . '&addr=' . $xchan['xchan_addr'] - : $xchan['xchan_url'] - ); - - return replace_macros(get_markup_template('xchan_vcard.tpl'), [ - '$name' => $xchan['xchan_name'], - '$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']), - '$follow' => urlencode(($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']), - '$link' => zid($xchan['xchan_url']), - '$connect' => $connect, - '$newwin' => (($mode === 'chanview') ? t('New window') : EMPTY_STR), - '$newtit' => t('Open the selected location in a different window or browser tab'), - '$url' => $url, - ]); + intval($channel_id) + ); + return(($r) ? $r : []); } -function abook_toggle_flag($abook,$flag) { - $field = EMPTY_STR; +function abook_by_hash($channel_id, $hash) +{ + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d + and abook_self = 0 and abook_xchan = '%s'", + intval($channel_id), + dbesc($hash) + ); + return(($r) ? array_shift($r) : false); +} - switch ($flag) { - case ABOOK_FLAG_BLOCKED: - $field = 'abook_blocked'; - break; - case ABOOK_FLAG_IGNORED: - $field = 'abook_ignored'; - break; - case ABOOK_FLAG_CENSORED: - $field = 'abook_censor'; - break; - case ABOOK_FLAG_HIDDEN: - $field = 'abook_hidden'; - break; - case ABOOK_FLAG_ARCHIVED: - $field = 'abook_archived'; - break; - case ABOOK_FLAG_PENDING: - $field = 'abook_pending'; - break; - case ABOOK_FLAG_UNCONNECTED: - $field = 'abook_unconnected'; - break; - case ABOOK_FLAG_SELF: - $field = 'abook_self'; - break; - case ABOOK_FLAG_FEED: - $field = 'abook_feed'; - break; - default: - break; - } - if (! $field) { - return; - } +function abook_self($channel_id) +{ + $r = q( + "select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d + and abook_self = 1 limit 1", + intval($channel_id) + ); + return(($r) ? $r[0] : []); +} - $r = q("UPDATE abook set $field = (1 - $field) where abook_id = %d and abook_channel = %d", - intval($abook['abook_id']), - intval($abook['abook_channel']) - ); - // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days. +function vcard_from_xchan($xchan, $observer = null, $mode = '') +{ - if(($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) { - $r = q("update abook set abook_connected = '%s', abook_updated = '%s' + if (! $xchan) { + if (App::$poi) { + $xchan = App::$poi; + } elseif (is_array(App::$profile) && App::$profile['channel_hash']) { + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc(App::$profile['channel_hash']) + ); + if ($r) { + $xchan = $r[0]; + } + } + } + + if (! $xchan) { + return; + } + + $connect = false; + if (local_channel()) { + $r = q( + "select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc($xchan['xchan_hash']), + intval(local_channel()) + ); + if (! $r) { + $connect = t('Connect'); + } + } + + // don't provide a connect button for transient or one-way identities + + if (in_array($xchan['xchan_network'], [ 'rss','anon','token','unknown' ])) { + $connect = false; + } + + if (array_key_exists('channel_id', $xchan)) { + App::$profile_uid = $xchan['channel_id']; + } + + $url = (($observer) + ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($xchan['xchan_url']) . '&addr=' . $xchan['xchan_addr'] + : $xchan['xchan_url'] + ); + + return replace_macros(get_markup_template('xchan_vcard.tpl'), [ + '$name' => $xchan['xchan_name'], + '$photo' => ((is_array(App::$profile) && array_key_exists('photo', App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']), + '$follow' => urlencode(($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']), + '$link' => zid($xchan['xchan_url']), + '$connect' => $connect, + '$newwin' => (($mode === 'chanview') ? t('New window') : EMPTY_STR), + '$newtit' => t('Open the selected location in a different window or browser tab'), + '$url' => $url, + ]); +} + +function abook_toggle_flag($abook, $flag) +{ + + $field = EMPTY_STR; + + switch ($flag) { + case ABOOK_FLAG_BLOCKED: + $field = 'abook_blocked'; + break; + case ABOOK_FLAG_IGNORED: + $field = 'abook_ignored'; + break; + case ABOOK_FLAG_CENSORED: + $field = 'abook_censor'; + break; + case ABOOK_FLAG_HIDDEN: + $field = 'abook_hidden'; + break; + case ABOOK_FLAG_ARCHIVED: + $field = 'abook_archived'; + break; + case ABOOK_FLAG_PENDING: + $field = 'abook_pending'; + break; + case ABOOK_FLAG_UNCONNECTED: + $field = 'abook_unconnected'; + break; + case ABOOK_FLAG_SELF: + $field = 'abook_self'; + break; + case ABOOK_FLAG_FEED: + $field = 'abook_feed'; + break; + default: + break; + } + if (! $field) { + return; + } + + $r = q( + "UPDATE abook set $field = (1 - $field) where abook_id = %d and abook_channel = %d", + intval($abook['abook_id']), + intval($abook['abook_channel']) + ); + + // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days. + + if (($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) { + $r = q( + "update abook set abook_connected = '%s', abook_updated = '%s' where abook_id = %d and abook_channel = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($abook['abook_id']), - intval($abook['abook_channel']) - ); - } - - return $r; + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($abook['abook_id']), + intval($abook['abook_channel']) + ); + } + return $r; } @@ -234,731 +248,765 @@ function abook_toggle_flag($abook,$flag) { */ -function mark_orphan_hubsxchans() { +function mark_orphan_hubsxchans() +{ - return; + return; - $dirmode = intval(get_config('system','directory_mode')); - if ($dirmode == DIRECTORY_MODE_NORMAL) { - return; - } + $dirmode = intval(get_config('system', 'directory_mode')); + if ($dirmode == DIRECTORY_MODE_NORMAL) { + return; + } - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_deleted = 0 + $r = q( + "update hubloc set hubloc_deleted = 1 where hubloc_deleted = 0 and hubloc_network = 'zot6' and hubloc_connected < %s - interval %s", - db_utcnow(), db_quoteinterval('36 day') - ); + db_utcnow(), + db_quoteinterval('36 day') + ); - $r = q("select hubloc_id, hubloc_hash from hubloc where hubloc_deleted = 1 and hubloc_orphancheck = 0"); + $r = q("select hubloc_id, hubloc_hash from hubloc where hubloc_deleted = 1 and hubloc_orphancheck = 0"); - if ($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { + // see if any other hublocs are still alive for this channel - // see if any other hublocs are still alive for this channel + $x = q( + "select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", + dbesc($rr['hubloc_hash']) + ); + if ($x) { + // yes - if the xchan was marked as an orphan, undo it - $x = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", - dbesc($rr['hubloc_hash']) - ); - if ($x) { + $y = q( + "update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", + dbesc($rr['hubloc_hash']) + ); + } else { + // nope - mark the xchan as an orphan - // yes - if the xchan was marked as an orphan, undo it + $y = q( + "update xchan set xchan_orphan = 1 where xchan_hash = '%s'", + dbesc($rr['hubloc_hash']) + ); + } - $y = q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", - dbesc($rr['hubloc_hash']) - ); - } - else { - - // nope - mark the xchan as an orphan - - $y = q("update xchan set xchan_orphan = 1 where xchan_hash = '%s'", - dbesc($rr['hubloc_hash']) - ); - } - - // mark that we've checked this entry so we don't need to do it again - - $y = q("update hubloc set hubloc_orphancheck = 1 where hubloc_id = %d", - dbesc($rr['hubloc_id']) - ); - } - } + // mark that we've checked this entry so we don't need to do it again + $y = q( + "update hubloc set hubloc_orphancheck = 1 where hubloc_id = %d", + dbesc($rr['hubloc_id']) + ); + } + } } -function remove_all_xchan_resources($xchan, $channel_id = 0) { +function remove_all_xchan_resources($xchan, $channel_id = 0) +{ - // $channel_id is reserved for future use. + // $channel_id is reserved for future use. - if (intval($channel_id) === 0) { + if (intval($channel_id) === 0) { + if (! $xchan) { + return; + } - if (! $xchan) { - return; - } + // this function is only to be executed on remote servers where only the xchan exists and there is no associated channel. - // this function is only to be executed on remote servers where only the xchan exists and there is no associated channel. - - $c = q("select channel_id from channel where channel_hash = '%s'", - dbesc($xchan) - ); + $c = q( + "select channel_id from channel where channel_hash = '%s'", + dbesc($xchan) + ); - if ($c) { - return; - } + if ($c) { + return; + } - $dirmode = intval(get_config('system','directory_mode')); + $dirmode = intval(get_config('system', 'directory_mode')); - // note: we will not remove "guest" submitted files/photos this xchan created in the file spaces of others. - // We will however remove all their posts and comments. - - $r = q("select id from item where ( author_xchan = '%s' or owner_xchan = '%s' ) ", - dbesc($xchan), - dbesc($xchan) - ); - if ($r) { - foreach ($r as $rr) { - drop_item($rr['id'],false); - } - } - $r = q("delete from event where event_xchan = '%s'", - dbesc($xchan) - ); - $r = q("delete from pgrp_member where xchan = '%s'", - dbesc($xchan) - ); + // note: we will not remove "guest" submitted files/photos this xchan created in the file spaces of others. + // We will however remove all their posts and comments. - $r = q("delete from xlink where ( xlink_xchan = '%s' or xlink_link = '%s' )", - dbesc($xchan), - dbesc($xchan) - ); + $r = q( + "select id from item where ( author_xchan = '%s' or owner_xchan = '%s' ) ", + dbesc($xchan), + dbesc($xchan) + ); + if ($r) { + foreach ($r as $rr) { + drop_item($rr['id'], false); + } + } + $r = q( + "delete from event where event_xchan = '%s'", + dbesc($xchan) + ); + $r = q( + "delete from pgrp_member where xchan = '%s'", + dbesc($xchan) + ); - $r = q("delete from abook where abook_xchan = '%s'", - dbesc($xchan) - ); + $r = q( + "delete from xlink where ( xlink_xchan = '%s' or xlink_link = '%s' )", + dbesc($xchan), + dbesc($xchan) + ); - $r = q("delete from abconfig where xchan = '%s'", - dbesc($xchan) - ); + $r = q( + "delete from abook where abook_xchan = '%s'", + dbesc($xchan) + ); - if ($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { + $r = q( + "delete from abconfig where xchan = '%s'", + dbesc($xchan) + ); - $r = q("delete from xchan where xchan_hash = '%s'", - dbesc($xchan) - ); - $r = q("delete from hubloc where hubloc_hash = '%s'", - dbesc($xchan) - ); - $r = q("delete from xprof where xprof_hash = '%s'", - dbesc($xchan) - ); + if ($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { + $r = q( + "delete from xchan where xchan_hash = '%s'", + dbesc($xchan) + ); + $r = q( + "delete from hubloc where hubloc_hash = '%s'", + dbesc($xchan) + ); + $r = q( + "delete from xprof where xprof_hash = '%s'", + dbesc($xchan) + ); + } else { + // directory servers need to keep the record around for sync purposes - mark it deleted + $r = q( + "update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", + dbesc($xchan) + ); - } - else { - - // directory servers need to keep the record around for sync purposes - mark it deleted - - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", - dbesc($xchan) - ); - - $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'", - dbesc($xchan) - ); - } - } + $r = q( + "update xchan set xchan_deleted = 1 where xchan_hash = '%s'", + dbesc($xchan) + ); + } + } } -function contact_remove($channel_id, $abook_id, $atoken_sync = false) { +function contact_remove($channel_id, $abook_id, $atoken_sync = false) +{ - if ((! $channel_id) || (! $abook_id)) { - return false; - } + if ((! $channel_id) || (! $abook_id)) { + return false; + } - logger('removing connection ' . $abook_id . ' for channel ' . $channel_id,LOGGER_DEBUG); + logger('removing connection ' . $abook_id . ' for channel ' . $channel_id, LOGGER_DEBUG); - $x = [ - 'channel_id' => $channel_id, - 'abook_id' => $abook_id - ]; - - call_hooks('connection_remove',$x); + $x = [ + 'channel_id' => $channel_id, + 'abook_id' => $abook_id + ]; - $archive = get_pconfig($channel_id, 'system','archive_removed_contacts'); - if ($archive) { - q("update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d", - intval($abook_id), - intval($channel_id) - ); - return true; - } + call_hooks('connection_remove', $x); - $r = q("select * from abook where abook_id = %d and abook_channel = %d limit 1", - intval($abook_id), - intval($channel_id) - ); + $archive = get_pconfig($channel_id, 'system', 'archive_removed_contacts'); + if ($archive) { + q( + "update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d", + intval($abook_id), + intval($channel_id) + ); + return true; + } - if (! $r) { - return false; - } - - $abook = $r[0]; + $r = q( + "select * from abook where abook_id = %d and abook_channel = %d limit 1", + intval($abook_id), + intval($channel_id) + ); - if (intval($abook['abook_self'])) { - return false; - } + if (! $r) { + return false; + } - // if this is an atoken, delete the atoken record + $abook = $r[0]; - if ($atoken_sync) { - $xchan = q("select * from xchan where xchan_hash = '%s'", - dbesc($abook['abook_xchan']) - ); - if ($xchan && strpos($xchan[0]['xchan_addr'],'guest:') === 0 && strpos($abook['abook_xchan'],'.')){ - $atoken_guid = substr($abook['abook_xchan'],strrpos($abook['abook_xchan'],'.') + 1); - if ($atoken_guid) { - atoken_delete_and_sync($channel_id,$atoken_guid); - } - } - } + if (intval($abook['abook_self'])) { + return false; + } - // remove items in the background as this can take some time + // if this is an atoken, delete the atoken record - Run::Summon( [ 'Delxitems', $channel_id, $abook['abook_xchan'] ] ); + if ($atoken_sync) { + $xchan = q( + "select * from xchan where xchan_hash = '%s'", + dbesc($abook['abook_xchan']) + ); + if ($xchan && strpos($xchan[0]['xchan_addr'], 'guest:') === 0 && strpos($abook['abook_xchan'], '.')) { + $atoken_guid = substr($abook['abook_xchan'], strrpos($abook['abook_xchan'], '.') + 1); + if ($atoken_guid) { + atoken_delete_and_sync($channel_id, $atoken_guid); + } + } + } - $r = q("delete from abook where abook_id = %d and abook_channel = %d", - intval($abook['abook_id']), - intval($channel_id) - ); + // remove items in the background as this can take some time - $r = q("delete from event where event_xchan = '%s' and uid = %d", - dbesc($abook['abook_xchan']), - intval($channel_id) - ); + Run::Summon([ 'Delxitems', $channel_id, $abook['abook_xchan'] ]); - $r = q("delete from pgrp_member where xchan = '%s' and uid = %d", - dbesc($abook['abook_xchan']), - intval($channel_id) - ); + $r = q( + "delete from abook where abook_id = %d and abook_channel = %d", + intval($abook['abook_id']), + intval($channel_id) + ); - $r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' ) and channel_id = %d ", - dbesc($abook['abook_xchan']), - dbesc($abook['abook_xchan']), - intval($channel_id) - ); + $r = q( + "delete from event where event_xchan = '%s' and uid = %d", + dbesc($abook['abook_xchan']), + intval($channel_id) + ); - $r = q("delete from abconfig where chan = %d and xchan = '%s'", - intval($channel_id), - dbesc($abook['abook_xchan']) - ); + $r = q( + "delete from pgrp_member where xchan = '%s' and uid = %d", + dbesc($abook['abook_xchan']), + intval($channel_id) + ); - return true; + $r = q( + "delete from mail where ( from_xchan = '%s' or to_xchan = '%s' ) and channel_id = %d ", + dbesc($abook['abook_xchan']), + dbesc($abook['abook_xchan']), + intval($channel_id) + ); + + $r = q( + "delete from abconfig where chan = %d and xchan = '%s'", + intval($channel_id), + dbesc($abook['abook_xchan']) + ); + + return true; } -function remove_abook_items($channel_id,$xchan_hash) { +function remove_abook_items($channel_id, $xchan_hash) +{ - $r = q("select id, parent from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0", - dbesc($xchan_hash), - dbesc($xchan_hash), - intval($channel_id) - ); - if (! $r) { - return; - } + $r = q( + "select id, parent from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0", + dbesc($xchan_hash), + dbesc($xchan_hash), + intval($channel_id) + ); + if (! $r) { + return; + } - $already_saved = []; - foreach ($r as $rr) { - $w = $x = $y = null; - - // optimise so we only process newly seen parent items - if (in_array($rr['parent'],$already_saved)) { - continue; - } - // if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation - // should be retained - if ($rr['id'] != $rr['parent']) { - $w = q("select id, item_retained, item_starred from item where id = %d", - intval($rr['parent']) - ); - if ($w) { - // see if the conversation was filed - $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", - intval(TERM_OBJ_POST), - intval($w[0]['id']), - intval(TERM_FILE) - ); - if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) { - $already_saved[] = $rr['parent']; - continue; - } - } - } - // see if this item was filed - $y = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", - intval(TERM_OBJ_POST), - intval($rr['id']), - intval(TERM_FILE) - ); - if ($y) { - continue; - } - drop_item($rr['id'],false); - } + $already_saved = []; + foreach ($r as $rr) { + $w = $x = $y = null; + + // optimise so we only process newly seen parent items + if (in_array($rr['parent'], $already_saved)) { + continue; + } + // if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation + // should be retained + if ($rr['id'] != $rr['parent']) { + $w = q( + "select id, item_retained, item_starred from item where id = %d", + intval($rr['parent']) + ); + if ($w) { + // see if the conversation was filed + $x = q( + "select uid from term where otype = %d and oid = %d and ttype = %d limit 1", + intval(TERM_OBJ_POST), + intval($w[0]['id']), + intval(TERM_FILE) + ); + if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) { + $already_saved[] = $rr['parent']; + continue; + } + } + } + // see if this item was filed + $y = q( + "select uid from term where otype = %d and oid = %d and ttype = %d limit 1", + intval(TERM_OBJ_POST), + intval($rr['id']), + intval(TERM_FILE) + ); + if ($y) { + continue; + } + drop_item($rr['id'], false); + } } -function random_profile() { - $randfunc = db_getfunc('rand'); +function random_profile() +{ + $randfunc = db_getfunc('rand'); - $checkrandom = get_config('randprofile','check'); // False by default - $retryrandom = intval(get_config('randprofile','retry')); - if ($retryrandom == 0) { - $retryrandom = 5; - } - - for ($i = 0; $i < $retryrandom; $i++) { + $checkrandom = get_config('randprofile', 'check'); // False by default + $retryrandom = intval(get_config('randprofile', 'retry')); + if ($retryrandom == 0) { + $retryrandom = 5; + } - $r = q("select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where + for ($i = 0; $i < $retryrandom; $i++) { + $r = q( + "select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_hidden = 0 and xchan_network = 'zot6' and xchan_deleted = 0 and hubloc_connected > %s - interval %s order by $randfunc limit 1", - db_utcnow(), - db_quoteinterval('30 day') - ); + db_utcnow(), + db_quoteinterval('30 day') + ); - if (!$r) { - return EMPTY_STR; // Couldn't get a random channel - } - if ($checkrandom) { - $x = z_fetch_url($r[0]['xchan_url']); - if ($x['success']) { - return $r[0]['xchan_hash']; - } - else { - logger('Random channel turned out to be bad.'); - } - } - else { - return $r[0]['xchan_hash']; - } - - } - return EMPTY_STR; + if (!$r) { + return EMPTY_STR; // Couldn't get a random channel + } + if ($checkrandom) { + $x = z_fetch_url($r[0]['xchan_url']); + if ($x['success']) { + return $r[0]['xchan_hash']; + } else { + logger('Random channel turned out to be bad.'); + } + } else { + return $r[0]['xchan_hash']; + } + } + return EMPTY_STR; } -function update_vcard($arr,$vcard = null) { +function update_vcard($arr, $vcard = null) +{ - // logger('update_vcard: ' . print_r($arr,true)); + // logger('update_vcard: ' . print_r($arr,true)); - $fn = $arr['fn']; - - - // This isn't strictly correct and could be a cause for concern. - // 'N' => array_reverse(explode(' ', $fn)) + $fn = $arr['fn']; - // What we really want is - // 'N' => Adams;John;Quincy;Reverend,Dr.;III - // which is a very difficult parsing problem especially if you allow - // the surname to contain spaces. The only way to be sure to get it - // right is to provide a form to input all the various fields and not - // try to extract it from the FN. + // This isn't strictly correct and could be a cause for concern. + // 'N' => array_reverse(explode(' ', $fn)) - if (! $vcard) { - $vcard = new VCard([ - 'FN' => $fn, - 'N' => array_reverse(explode(' ', $fn)) - ]); - } - else { - $vcard->FN = $fn; - $vcard->N = array_reverse(explode(' ', $fn)); - } - $org = $arr['org']; - if($org) { - $vcard->ORG = $org; - } + // What we really want is + // 'N' => Adams;John;Quincy;Reverend,Dr.;III + // which is a very difficult parsing problem especially if you allow + // the surname to contain spaces. The only way to be sure to get it + // right is to provide a form to input all the various fields and not + // try to extract it from the FN. - $title = $arr['title']; - if($title) { - $vcard->TITLE = $title; - } + if (! $vcard) { + $vcard = new VCard([ + 'FN' => $fn, + 'N' => array_reverse(explode(' ', $fn)) + ]); + } else { + $vcard->FN = $fn; + $vcard->N = array_reverse(explode(' ', $fn)); + } - $tel = $arr['tel']; - $tel_type = $arr['tel_type']; - if($tel) { - $i = 0; - foreach($tel as $item) { - if($item) { - $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); - } - $i++; - } - } + $org = $arr['org']; + if ($org) { + $vcard->ORG = $org; + } - $email = $arr['email']; - $email_type = $arr['email_type']; - if($email) { - $i = 0; - foreach($email as $item) { - if($item) { - $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); - } - $i++; - } - } + $title = $arr['title']; + if ($title) { + $vcard->TITLE = $title; + } - $impp = $arr['impp']; - $impp_type = $arr['impp_type']; - if($impp) { - $i = 0; - foreach($impp as $item) { - if($item) { - $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); - } - $i++; - } - } + $tel = $arr['tel']; + $tel_type = $arr['tel_type']; + if ($tel) { + $i = 0; + foreach ($tel as $item) { + if ($item) { + $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); + } + $i++; + } + } - $url = $arr['url']; - $url_type = $arr['url_type']; - if($url) { - $i = 0; - foreach($url as $item) { - if($item) { - $vcard->add('URL', $item, ['type' => $url_type[$i]]); - } - $i++; - } - } + $email = $arr['email']; + $email_type = $arr['email_type']; + if ($email) { + $i = 0; + foreach ($email as $item) { + if ($item) { + $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); + } + $i++; + } + } - $adr = $arr['adr']; - $adr_type = $arr['adr_type']; + $impp = $arr['impp']; + $impp_type = $arr['impp_type']; + if ($impp) { + $i = 0; + foreach ($impp as $item) { + if ($item) { + $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); + } + $i++; + } + } - if($adr) { - $i = 0; - foreach($adr as $item) { - if($item) { - $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); - } - $i++; - } - } + $url = $arr['url']; + $url_type = $arr['url_type']; + if ($url) { + $i = 0; + foreach ($url as $item) { + if ($item) { + $vcard->add('URL', $item, ['type' => $url_type[$i]]); + } + $i++; + } + } - $note = $arr['note']; - if($note) { - $vcard->NOTE = $note; - } + $adr = $arr['adr']; + $adr_type = $arr['adr_type']; - return $vcard->serialize(); + if ($adr) { + $i = 0; + foreach ($adr as $item) { + if ($item) { + $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); + } + $i++; + } + } + $note = $arr['note']; + if ($note) { + $vcard->NOTE = $note; + } + + return $vcard->serialize(); } -function get_vcard_array($vc,$id) { +function get_vcard_array($vc, $id) +{ - $photo = ''; - if($vc->PHOTO) { - $photo_value = strtolower($vc->PHOTO->getValueType()); // binary or uri - if($photo_value === 'binary') { - $photo_type = strtolower($vc->PHOTO['TYPE']); // mime jpeg, png or gif - $photo = 'data:image/' . $photo_type . ';base64,' . base64_encode((string)$vc->PHOTO); - } - else { - $url = parse_url((string)$vc->PHOTO); - $photo = 'data:' . $url['path']; - } - } + $photo = ''; + if ($vc->PHOTO) { + $photo_value = strtolower($vc->PHOTO->getValueType()); // binary or uri + if ($photo_value === 'binary') { + $photo_type = strtolower($vc->PHOTO['TYPE']); // mime jpeg, png or gif + $photo = 'data:image/' . $photo_type . ';base64,' . base64_encode((string)$vc->PHOTO); + } else { + $url = parse_url((string)$vc->PHOTO); + $photo = 'data:' . $url['path']; + } + } - $fn = ''; - if($vc->FN) { - $fn = (string) escape_tags($vc->FN); - } + $fn = ''; + if ($vc->FN) { + $fn = (string) escape_tags($vc->FN); + } - $org = ''; - if($vc->ORG) { - $org = (string) escape_tags($vc->ORG); - } + $org = ''; + if ($vc->ORG) { + $org = (string) escape_tags($vc->ORG); + } - $title = ''; - if($vc->TITLE) { - $title = (string) escape_tags($vc->TITLE); - } + $title = ''; + if ($vc->TITLE) { + $title = (string) escape_tags($vc->TITLE); + } - $tels = []; - if($vc->TEL) { - foreach($vc->TEL as $tel) { - $type = (($tel['TYPE']) ? vcard_translate_type((string)$tel['TYPE']) : ''); - $tels[] = [ - 'type' => $type, - 'nr' => (string) escape_tags($tel) - ]; - } - } - $emails = []; - if($vc->EMAIL) { - foreach($vc->EMAIL as $email) { - $type = (($email['TYPE']) ? vcard_translate_type((string)$email['TYPE']) : ''); - $emails[] = [ - 'type' => $type, - 'address' => (string) escape_tags($email) - ]; - } - } + $tels = []; + if ($vc->TEL) { + foreach ($vc->TEL as $tel) { + $type = (($tel['TYPE']) ? vcard_translate_type((string)$tel['TYPE']) : ''); + $tels[] = [ + 'type' => $type, + 'nr' => (string) escape_tags($tel) + ]; + } + } + $emails = []; + if ($vc->EMAIL) { + foreach ($vc->EMAIL as $email) { + $type = (($email['TYPE']) ? vcard_translate_type((string)$email['TYPE']) : ''); + $emails[] = [ + 'type' => $type, + 'address' => (string) escape_tags($email) + ]; + } + } - $impps = []; - if($vc->IMPP) { - foreach($vc->IMPP as $impp) { - $type = (($impp['TYPE']) ? vcard_translate_type((string)$impp['TYPE']) : ''); - $impps[] = [ - 'type' => $type, - 'address' => (string) escape_tags($impp) - ]; - } - } + $impps = []; + if ($vc->IMPP) { + foreach ($vc->IMPP as $impp) { + $type = (($impp['TYPE']) ? vcard_translate_type((string)$impp['TYPE']) : ''); + $impps[] = [ + 'type' => $type, + 'address' => (string) escape_tags($impp) + ]; + } + } - $urls = []; - if($vc->URL) { - foreach($vc->URL as $url) { - $type = (($url['TYPE']) ? vcard_translate_type((string)$url['TYPE']) : ''); - $urls[] = [ - 'type' => $type, - 'address' => (string) escape_tags($url) - ]; - } - } + $urls = []; + if ($vc->URL) { + foreach ($vc->URL as $url) { + $type = (($url['TYPE']) ? vcard_translate_type((string)$url['TYPE']) : ''); + $urls[] = [ + 'type' => $type, + 'address' => (string) escape_tags($url) + ]; + } + } - $adrs = []; - if($vc->ADR) { - foreach($vc->ADR as $adr) { - $type = (($adr['TYPE']) ? vcard_translate_type((string)$adr['TYPE']) : ''); - $entry = [ - 'type' => $type, - 'address' => $adr->getParts() - ]; + $adrs = []; + if ($vc->ADR) { + foreach ($vc->ADR as $adr) { + $type = (($adr['TYPE']) ? vcard_translate_type((string)$adr['TYPE']) : ''); + $entry = [ + 'type' => $type, + 'address' => $adr->getParts() + ]; - if(is_array($entry['address'])) { - array_walk($entry['address'],'array_escape_tags'); - } - else { - $entry['address'] = (string) escape_tags($entry['address']); - } + if (is_array($entry['address'])) { + array_walk($entry['address'], 'array_escape_tags'); + } else { + $entry['address'] = (string) escape_tags($entry['address']); + } - $adrs[] = $entry; - - } - } + $adrs[] = $entry; + } + } - $note = ''; - if($vc->NOTE) { - $note = (string) escape_tags($vc->NOTE); - } + $note = ''; + if ($vc->NOTE) { + $note = (string) escape_tags($vc->NOTE); + } - $card = [ - 'id' => $id, - 'photo' => $photo, - 'fn' => $fn, - 'org' => $org, - 'title' => $title, - 'tels' => $tels, - 'emails' => $emails, - 'impps' => $impps, - 'urls' => $urls, - 'adrs' => $adrs, - 'note' => $note - ]; - - return $card; + $card = [ + 'id' => $id, + 'photo' => $photo, + 'fn' => $fn, + 'org' => $org, + 'title' => $title, + 'tels' => $tels, + 'emails' => $emails, + 'impps' => $impps, + 'urls' => $urls, + 'adrs' => $adrs, + 'note' => $note + ]; + return $card; } -function vcard_translate_type($type) { +function vcard_translate_type($type) +{ - if(!$type) - return; + if (!$type) { + return; + } - $type = strtoupper($type); + $type = strtoupper($type); - $map = [ - 'CELL' => t('Mobile'), - 'HOME' => t('Home'), - 'HOME,VOICE' => t('Home, Voice'), - 'HOME,FAX' => t('Home, Fax'), - 'WORK' => t('Work'), - 'WORK,VOICE' => t('Work, Voice'), - 'WORK,FAX' => t('Work, Fax'), - 'OTHER' => t('Other') - ]; + $map = [ + 'CELL' => t('Mobile'), + 'HOME' => t('Home'), + 'HOME,VOICE' => t('Home, Voice'), + 'HOME,FAX' => t('Home, Fax'), + 'WORK' => t('Work'), + 'WORK,VOICE' => t('Work, Voice'), + 'WORK,FAX' => t('Work, Fax'), + 'OTHER' => t('Other') + ]; - if (array_key_exists($type, $map)) { - return [$type, $map[$type]]; - } - else { - return [$type, t('Other') . ' (' . $type . ')']; - } + if (array_key_exists($type, $map)) { + return [$type, $map[$type]]; + } else { + return [$type, t('Other') . ' (' . $type . ')']; + } } -function vcard_query(&$r) { +function vcard_query(&$r) +{ - $arr = []; + $arr = []; - if($r && is_array($r) && count($r)) { - $uid = $r[0]['abook_channel']; - foreach($r as $rv) { - if($rv['abook_xchan'] && (! in_array("'" . dbesc($rv['abook_xchan']) . "'",$arr))) - $arr[] = "'" . dbesc($rv['abook_xchan']) . "'"; - } - } + if ($r && is_array($r) && count($r)) { + $uid = $r[0]['abook_channel']; + foreach ($r as $rv) { + if ($rv['abook_xchan'] && (! in_array("'" . dbesc($rv['abook_xchan']) . "'", $arr))) { + $arr[] = "'" . dbesc($rv['abook_xchan']) . "'"; + } + } + } - if($arr) { - $a = q("select * from abconfig where chan = %d and xchan in (" . protect_sprintf(implode(',', $arr)) . ") and cat = 'system' and k = 'vcard'", - intval($uid) - ); - if($a) { - foreach($a as $av) { - for($x = 0; $x < count($r); $x ++) { - if($r[$x]['abook_xchan'] == $av['xchan']) { - $vctmp = Reader::read($av['v']); - $r[$x]['vcard'] = (($vctmp) ? get_vcard_array($vctmp,$r[$x]['abook_id']) : [] ); - } - } - } - } - } + if ($arr) { + $a = q( + "select * from abconfig where chan = %d and xchan in (" . protect_sprintf(implode(',', $arr)) . ") and cat = 'system' and k = 'vcard'", + intval($uid) + ); + if ($a) { + foreach ($a as $av) { + for ($x = 0; $x < count($r); $x++) { + if ($r[$x]['abook_xchan'] == $av['xchan']) { + $vctmp = Reader::read($av['v']); + $r[$x]['vcard'] = (($vctmp) ? get_vcard_array($vctmp, $r[$x]['abook_id']) : [] ); + } + } + } + } + } } -function contact_profile_assign($current) { +function contact_profile_assign($current) +{ - $o = ''; + $o = ''; - $o .= "\r\n"; - $r = q("SELECT profile_guid, profile_name FROM profile WHERE uid = %d", - intval($_SESSION['uid'])); + $r = q( + "SELECT profile_guid, profile_name FROM profile WHERE uid = %d", + intval($_SESSION['uid']) + ); - if($r) { - foreach($r as $rr) { - $selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : ""); - $o .= "\r\n"; - } - } - $o .= "\r\n"; - return $o; + if ($r) { + foreach ($r as $rr) { + $selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : ""); + $o .= "\r\n"; + } + } + $o .= "\r\n"; + return $o; } -function contact_block() { - $o = ''; +function contact_block() +{ + $o = ''; - if(! App::$profile['uid']) - return; + if (! App::$profile['uid']) { + return; + } - if(! perm_is_allowed(App::$profile['uid'],get_observer_hash(),'view_contacts')) - return; + if (! perm_is_allowed(App::$profile['uid'], get_observer_hash(), 'view_contacts')) { + return; + } - $shown = get_pconfig(App::$profile['uid'],'system','display_friend_count'); + $shown = get_pconfig(App::$profile['uid'], 'system', 'display_friend_count'); - if($shown === false) - $shown = 25; - if($shown == 0) - return; + if ($shown === false) { + $shown = 25; + } + if ($shown == 0) { + return; + } - $is_owner = ((local_channel() && local_channel() == App::$profile['uid']) ? true : false); - $sql_extra = ''; + $is_owner = ((local_channel() && local_channel() == App::$profile['uid']) ? true : false); + $sql_extra = ''; - $abook_flags = " and abook_pending = 0 and abook_self = 0 "; + $abook_flags = " and abook_pending = 0 and abook_self = 0 "; - if(! $is_owner) { - $abook_flags .= " and abook_hidden = 0 "; - $sql_extra = " and xchan_hidden = 0 "; - } + if (! $is_owner) { + $abook_flags .= " and abook_hidden = 0 "; + $sql_extra = " and xchan_hidden = 0 "; + } - if((! is_array(App::$profile)) || (App::$profile['hide_friends'])) - return $o; + if ((! is_array(App::$profile)) || (App::$profile['hide_friends'])) { + return $o; + } - $r = q("SELECT COUNT(abook_id) AS total FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d + $r = q( + "SELECT COUNT(abook_id) AS total FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra", - intval(App::$profile['uid']) - ); - if(count($r)) { - $total = intval($r[0]['total']); - } - if(! $total) { - $contacts = t('No connections'); - $micropro = null; - } else { + intval(App::$profile['uid']) + ); + if (count($r)) { + $total = intval($r[0]['total']); + } + if (! $total) { + $contacts = t('No connections'); + $micropro = null; + } else { + $randfunc = db_getfunc('RAND'); - $randfunc = db_getfunc('RAND'); + $r = q( + "SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d", + intval(App::$profile['uid']), + intval($shown) + ); - $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d", - intval(App::$profile['uid']), - intval($shown) - ); + if (count($r)) { + $contacts = t('Connections'); + $micropro = array(); + foreach ($r as $rr) { + // There is no setting to discover if you are bi-directionally connected + // Use the ability to post comments as an indication that this relationship is more + // than wishful thinking; even though soapbox channels and feeds will disable it. - if(count($r)) { - $contacts = t('Connections'); - $micropro = Array(); - foreach($r as $rr) { + if (! their_perms_contains(App::$profile['uid'], $rr['xchan_hash'], 'post_comments')) { + $rr['oneway'] = true; + } + $micropro[] = micropro($rr, true, 'mpfriend'); + } + } + } - // There is no setting to discover if you are bi-directionally connected - // Use the ability to post comments as an indication that this relationship is more - // than wishful thinking; even though soapbox channels and feeds will disable it. + $tpl = get_markup_template('contact_block.tpl'); + $o = replace_macros($tpl, array( + '$contacts' => $contacts, + '$nickname' => App::$profile['channel_address'], + '$viewconnections' => (($total > $shown) ? sprintf(t('View all %s connections'), $total) : ''), + '$micropro' => $micropro, + )); - if(! their_perms_contains(App::$profile['uid'],$rr['xchan_hash'],'post_comments')) { - $rr['oneway'] = true; - } - $micropro[] = micropro($rr,true,'mpfriend'); - } - } - } + $arr = array('contacts' => $r, 'output' => $o); - $tpl = get_markup_template('contact_block.tpl'); - $o = replace_macros($tpl, array( - '$contacts' => $contacts, - '$nickname' => App::$profile['channel_address'], - '$viewconnections' => (($total > $shown) ? sprintf(t('View all %s connections'),$total) : ''), - '$micropro' => $micropro, - )); - - $arr = array('contacts' => $r, 'output' => $o); - - call_hooks('contact_block_end', $arr); - return $o; + call_hooks('contact_block_end', $arr); + return $o; } -function micropro($contact, $redirect = false, $class = '', $mode = false) { +function micropro($contact, $redirect = false, $class = '', $mode = false) +{ - if($contact['click']) - $url = '#'; - else - $url = chanlink_hash($contact['xchan_hash']); + if ($contact['click']) { + $url = '#'; + } else { + $url = chanlink_hash($contact['xchan_hash']); + } - $tpl = 'micropro_img.tpl'; - if($mode === true) - $tpl = 'micropro_txt.tpl'; - if($mode === 'card') - $tpl = 'micropro_card.tpl'; + $tpl = 'micropro_img.tpl'; + if ($mode === true) { + $tpl = 'micropro_txt.tpl'; + } + if ($mode === 'card') { + $tpl = 'micropro_card.tpl'; + } - return replace_macros(get_markup_template($tpl), array( - '$click' => (($contact['click']) ? $contact['click'] : ''), - '$class' => $class . (($contact['archived']) ? ' archived' : ''), - '$oneway' => (($contact['oneway']) ? true : false), - '$url' => $url, - '$photo' => $contact['xchan_photo_s'], - '$name' => $contact['xchan_name'], - '$addr' => $contact['xchan_addr'], - '$title' => $contact['xchan_name'] . ' [' . $contact['xchan_addr'] . ']', - '$network' => sprintf(t('Network: %s'), $contact['xchan_network']) - )); + return replace_macros(get_markup_template($tpl), array( + '$click' => (($contact['click']) ? $contact['click'] : ''), + '$class' => $class . (($contact['archived']) ? ' archived' : ''), + '$oneway' => (($contact['oneway']) ? true : false), + '$url' => $url, + '$photo' => $contact['xchan_photo_s'], + '$name' => $contact['xchan_name'], + '$addr' => $contact['xchan_addr'], + '$title' => $contact['xchan_name'] . ' [' . $contact['xchan_addr'] . ']', + '$network' => sprintf(t('Network: %s'), $contact['xchan_network']) + )); } diff --git a/include/conversation.php b/include/conversation.php index c4eeb1398..91a7f1217 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1,4 +1,6 @@ - $new_body, 'images' => $saved_image); + return array('body' => $new_body, 'images' => $saved_image); } -function item_redir_and_replace_images($body, $images, $cid) { +function item_redir_and_replace_images($body, $images, $cid) +{ - $origbody = $body; - $newbody = ''; + $origbody = $body; + $newbody = ''; - $observer = App::get_observer(); - $obhash = (($observer) ? $observer['xchan_hash'] : ''); - $obaddr = (($observer) ? $observer['xchan_addr'] : ''); + $observer = App::get_observer(); + $obhash = (($observer) ? $observer['xchan_hash'] : ''); + $obaddr = (($observer) ? $observer['xchan_addr'] : ''); - for($i = 0; $i < count($images); $i++) { - $search = '/\[url\=(.*?)\]\[!#saved_image' . $i . '#!\]\[\/url\]' . '/is'; - $replace = '[url=' . magiclink_url($obhash,$obaddr,'$1') . '][!#saved_image' . $i . '#!][/url]' ; + for ($i = 0; $i < count($images); $i++) { + $search = '/\[url\=(.*?)\]\[!#saved_image' . $i . '#!\]\[\/url\]' . '/is'; + $replace = '[url=' . magiclink_url($obhash, $obaddr, '$1') . '][!#saved_image' . $i . '#!][/url]' ; - $img_end = strpos($origbody, '[!#saved_image' . $i . '#!][/url]') + strlen('[!#saved_image' . $i . '#!][/url]'); - $process_part = substr($origbody, 0, $img_end); - $origbody = substr($origbody, $img_end); + $img_end = strpos($origbody, '[!#saved_image' . $i . '#!][/url]') + strlen('[!#saved_image' . $i . '#!][/url]'); + $process_part = substr($origbody, 0, $img_end); + $origbody = substr($origbody, $img_end); - $process_part = preg_replace($search, $replace, $process_part); - $newbody = $newbody . $process_part; - } - $newbody = $newbody . $origbody; + $process_part = preg_replace($search, $replace, $process_part); + $newbody = $newbody . $process_part; + } + $newbody = $newbody . $origbody; - $cnt = 0; - foreach($images as $image) { - // We're depending on the property of 'foreach' (specified on the PHP website) that - // it loops over the array starting from the first element and going sequentially - // to the last element - $newbody = str_replace('[!#saved_image' . $cnt . '#!]', '[img]' . $image . '[/img]', $newbody); - $cnt++; - } + $cnt = 0; + foreach ($images as $image) { + // We're depending on the property of 'foreach' (specified on the PHP website) that + // it loops over the array starting from the first element and going sequentially + // to the last element + $newbody = str_replace('[!#saved_image' . $cnt . '#!]', '[img]' . $image . '[/img]', $newbody); + $cnt++; + } - return $newbody; + return $newbody; } @@ -91,207 +94,209 @@ function item_redir_and_replace_images($body, $images, $cid) { * Render actions localized */ -function localize_item(&$item){ +function localize_item(&$item) +{ - if (activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE) || $item['verb'] === 'Announce') { - - if (! $item['obj']) { - return; - } + if (activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE) || $item['verb'] === 'Announce') { + if (! $item['obj']) { + return; + } - if (intval($item['item_thread_top'])) { - return; - } + if (intval($item['item_thread_top'])) { + return; + } - $obj = ((is_array($item['obj'])) ? $item['obj'] : json_decode($item['obj'],true)); - if (! is_array($obj)) { - logger('localize_item: failed to decode object: ' . print_r($item['obj'],true)); - return; - } - - if (isset($obj['author']) && $obj['author'] && $obj['author']['link']) { - $author_link = get_rel_link($obj['author']['link'],'alternate'); - } - else { - $author_link = ''; - } + $obj = ((is_array($item['obj'])) ? $item['obj'] : json_decode($item['obj'], true)); + if (! is_array($obj)) { + logger('localize_item: failed to decode object: ' . print_r($item['obj'], true)); + return; + } - $author_name = (($obj['author'] && $obj['author']['name']) ? $obj['author']['name'] : ''); + if (isset($obj['author']) && $obj['author'] && $obj['author']['link']) { + $author_link = get_rel_link($obj['author']['link'], 'alternate'); + } else { + $author_link = ''; + } - $item_url = get_rel_link($obj['link'],'alternate'); + $author_name = (($obj['author'] && $obj['author']['name']) ? $obj['author']['name'] : ''); - $Bphoto = ''; + $item_url = get_rel_link($obj['link'], 'alternate'); - switch ($obj['type']) { - case ACTIVITY_OBJ_PHOTO: - $post_type = t('photo'); - break; - case ACTIVITY_OBJ_EVENT: - $post_type = t('event'); - break; - case ACTIVITY_OBJ_PERSON: - $post_type = t('channel'); - $author_name = $obj['title']; - if ($obj['link']) { - $author_link = get_rel_link($obj['link'],'alternate'); - $Bphoto = get_rel_link($obj['link'],'photo'); - } - if ($obj['url']) { + $Bphoto = ''; - } - break; - case ACTIVITY_OBJ_THING: - $post_type = $obj['title']; - if($obj['owner']) { - if(array_key_exists('name',$obj['owner'])) - $obj['owner']['name']; - if(array_key_exists('link',$obj['owner'])) - $author_link = get_rel_link($obj['owner']['link'],'alternate'); - } - if($obj['link']) { - $Bphoto = get_rel_link($obj['link'],'photo'); - } - break; + switch ($obj['type']) { + case ACTIVITY_OBJ_PHOTO: + $post_type = t('photo'); + break; + case ACTIVITY_OBJ_EVENT: + $post_type = t('event'); + break; + case ACTIVITY_OBJ_PERSON: + $post_type = t('channel'); + $author_name = $obj['title']; + if ($obj['link']) { + $author_link = get_rel_link($obj['link'], 'alternate'); + $Bphoto = get_rel_link($obj['link'], 'photo'); + } + if ($obj['url']) { + } + break; + case ACTIVITY_OBJ_THING: + $post_type = $obj['title']; + if ($obj['owner']) { + if (array_key_exists('name', $obj['owner'])) { + $obj['owner']['name']; + } + if (array_key_exists('link', $obj['owner'])) { + $author_link = get_rel_link($obj['owner']['link'], 'alternate'); + } + } + if ($obj['link']) { + $Bphoto = get_rel_link($obj['link'], 'photo'); + } + break; - case ACTIVITY_OBJ_NOTE: - default: - $post_type = t('post'); - if($obj['id'] != $obj['parent']) - $post_type = t('comment'); - break; - } + case ACTIVITY_OBJ_NOTE: + default: + $post_type = t('post'); + if ($obj['id'] != $obj['parent']) { + $post_type = t('comment'); + } + break; + } - // If we couldn't parse something useful, don't bother translating. - // We need something better than zid here, probably magic_link(), but it needs writing + // If we couldn't parse something useful, don't bother translating. + // We need something better than zid here, probably magic_link(), but it needs writing - if($author_link && $author_name && $item_url) { - $author = '[zrl=' . chanlink_url($item['author']['xchan_url']) . ']' . $item['author']['xchan_name'] . '[/zrl]'; - $objauthor = '[zrl=' . chanlink_url($author_link) . ']' . $author_name . '[/zrl]'; - - $plink = '[zrl=' . zid($item_url) . ']' . $post_type . '[/zrl]'; + if ($author_link && $author_name && $item_url) { + $author = '[zrl=' . chanlink_url($item['author']['xchan_url']) . ']' . $item['author']['xchan_name'] . '[/zrl]'; + $objauthor = '[zrl=' . chanlink_url($author_link) . ']' . $author_name . '[/zrl]'; - if(activity_match($item['verb'],ACTIVITY_LIKE)) { - $bodyverb = t('%1$s likes %2$s\'s %3$s'); - } - elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) { - $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - } - elseif ($item['verb'] === 'Announce') { - $bodyverb = t('%1$s repeated %2$s\'s %3$s'); - } + $plink = '[zrl=' . zid($item_url) . ']' . $post_type . '[/zrl]'; - // short version, in notification strings the author will be displayed separately + if (activity_match($item['verb'], ACTIVITY_LIKE)) { + $bodyverb = t('%1$s likes %2$s\'s %3$s'); + } elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) { + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); + } elseif ($item['verb'] === 'Announce') { + $bodyverb = t('%1$s repeated %2$s\'s %3$s'); + } - if(activity_match($item['verb'],ACTIVITY_LIKE)) { - $shortbodyverb = t('likes %1$s\'s %2$s'); - } - elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) { - $shortbodyverb = t('doesn\'t like %1$s\'s %2$s'); - } - elseif ($item['verb'] === 'Announce') { - $shortbodyverb = t('repeated %1$s\'s %2$s'); - } + // short version, in notification strings the author will be displayed separately - if ($shortbodyverb) { - $item['shortlocalize'] = sprintf($shortbodyverb, $objauthor, $plink); - } - - $item['body'] = $item['localize'] = sprintf($bodyverb, $author, $objauthor, $plink); - if ($Bphoto != "") { - $item['body'] .= "\n\n\n" . '[zrl=' . chanlink_url($author_link) . '][zmg width="80" height="80"]' . $Bphoto . '[/zmg][/zrl]'; - } + if (activity_match($item['verb'], ACTIVITY_LIKE)) { + $shortbodyverb = t('likes %1$s\'s %2$s'); + } elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) { + $shortbodyverb = t('doesn\'t like %1$s\'s %2$s'); + } elseif ($item['verb'] === 'Announce') { + $shortbodyverb = t('repeated %1$s\'s %2$s'); + } - } - else { -// logger('localize_item like failed: link ' . $author_link . ' name ' . $author_name . ' url ' . $item_url); - } + if ($shortbodyverb) { + $item['shortlocalize'] = sprintf($shortbodyverb, $objauthor, $plink); + } - } + $item['body'] = $item['localize'] = sprintf($bodyverb, $author, $objauthor, $plink); + if ($Bphoto != "") { + $item['body'] .= "\n\n\n" . '[zrl=' . chanlink_url($author_link) . '][zmg width="80" height="80"]' . $Bphoto . '[/zmg][/zrl]'; + } + } else { +// logger('localize_item like failed: link ' . $author_link . ' name ' . $author_name . ' url ' . $item_url); + } + } - if (activity_match($item['verb'],ACTIVITY_FRIEND)) { + if (activity_match($item['verb'], ACTIVITY_FRIEND)) { + if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON) { + return; + } - if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON) - return; - - $Aname = $item['author']['xchan_name']; - $Alink = $item['author']['xchan_url']; + $Aname = $item['author']['xchan_name']; + $Alink = $item['author']['xchan_url']; - $obj= json_decode($item['obj'],true); - - $Blink = $Bphoto = ''; + $obj = json_decode($item['obj'], true); - if($obj['link']) { - $Blink = get_rel_link($obj['link'],'alternate'); - $Bphoto = get_rel_link($obj['link'],'photo'); - } - $Bname = $obj['title']; + $Blink = $Bphoto = ''; + + if ($obj['link']) { + $Blink = get_rel_link($obj['link'], 'alternate'); + $Bphoto = get_rel_link($obj['link'], 'photo'); + } + $Bname = $obj['title']; - $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; - $B = '[zrl=' . chanlink_url($Blink) . ']' . $Bname . '[/zrl]'; - if ($Bphoto!="") $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]'; + $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; + $B = '[zrl=' . chanlink_url($Blink) . ']' . $Bname . '[/zrl]'; + if ($Bphoto != "") { + $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]'; + } - $item['body'] = $item['localize'] = sprintf( t('%1$s is now connected with %2$s'), $A, $B); - $item['body'] .= "\n\n\n" . $Bphoto; - } + $item['body'] = $item['localize'] = sprintf(t('%1$s is now connected with %2$s'), $A, $B); + $item['body'] .= "\n\n\n" . $Bphoto; + } - if (stristr($item['verb'], ACTIVITY_POKE)) { + if (stristr($item['verb'], ACTIVITY_POKE)) { - /** @FIXME for obscured private posts, until then leave untranslated */ - return; + /** @FIXME for obscured private posts, until then leave untranslated */ + return; - $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1)); - if(! $verb) - return; + $verb = urldecode(substr($item['verb'], strpos($item['verb'], '#') + 1)); + if (! $verb) { + return; + } - if ($item['obj_type']=="" || $item['obj_type']!== ACTIVITY_OBJ_PERSON) return; + if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON) { + return; + } - $Aname = $item['author']['xchan_name']; - $Alink = $item['author']['xchan_url']; + $Aname = $item['author']['xchan_name']; + $Alink = $item['author']['xchan_url']; - $obj= json_decode($item['obj'],true); + $obj = json_decode($item['obj'], true); - $Blink = $Bphoto = ''; + $Blink = $Bphoto = ''; - if($obj['link']) { - $Blink = get_rel_link($obj['link'],'alternate'); - $Bphoto = get_rel_link($obj['link'],'photo'); - } - $Bname = $obj['title']; + if ($obj['link']) { + $Blink = get_rel_link($obj['link'], 'alternate'); + $Bphoto = get_rel_link($obj['link'], 'photo'); + } + $Bname = $obj['title']; - $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; - $B = '[zrl=' . chanlink_url($Blink) . ']' . $Bname . '[/zrl]'; - if ($Bphoto!="") $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]'; + $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; + $B = '[zrl=' . chanlink_url($Blink) . ']' . $Bname . '[/zrl]'; + if ($Bphoto != "") { + $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]'; + } - // we can't have a translation string with three positions but no distinguishable text - // So here is the translate string. + // we can't have a translation string with three positions but no distinguishable text + // So here is the translate string. - $txt = t('%1$s poked %2$s'); + $txt = t('%1$s poked %2$s'); - // now translate the verb + // now translate the verb - $txt = str_replace( t('poked'), t($verb), $txt); + $txt = str_replace(t('poked'), t($verb), $txt); - // then do the sprintf on the translation string + // then do the sprintf on the translation string - $item['body'] = $item['localize'] = sprintf($txt, $A, $B); - $item['body'] .= "\n\n\n" . $Bphoto; - } - if (stristr($item['verb'],ACTIVITY_MOOD)) { - $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1)); - if(! $verb) - return; + $item['body'] = $item['localize'] = sprintf($txt, $A, $B); + $item['body'] .= "\n\n\n" . $Bphoto; + } + if (stristr($item['verb'], ACTIVITY_MOOD)) { + $verb = urldecode(substr($item['verb'], strpos($item['verb'], '#') + 1)); + if (! $verb) { + return; + } - $Aname = $item['author']['xchan_name']; - $Alink = $item['author']['xchan_url']; + $Aname = $item['author']['xchan_name']; + $Alink = $item['author']['xchan_url']; - $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; - - $txt = t('%1$s is %2$s','mood'); + $A = '[zrl=' . chanlink_url($Alink) . ']' . $Aname . '[/zrl]'; - $item['body'] = sprintf($txt, $A, t($verb)); - } + $txt = t('%1$s is %2$s', 'mood'); + + $item['body'] = sprintf($txt, $A, t($verb)); + } } /** @@ -302,20 +307,22 @@ function localize_item(&$item){ * @return number */ -function count_descendants($item) { +function count_descendants($item) +{ - $total = count($item['children']); + $total = count($item['children']); - if($total > 0) { - foreach($item['children'] as $child) { - if(! visible_activity($child)) - $total --; + if ($total > 0) { + foreach ($item['children'] as $child) { + if (! visible_activity($child)) { + $total--; + } - $total += count_descendants($child); - } - } + $total += count_descendants($child); + } + } - return $total; + return $total; } /** @@ -324,41 +331,43 @@ function count_descendants($item) { * likes (etc.) can apply to other things besides posts. Check if they are post * children, in which case we handle them specially. Activities which are unrecognised * as having special meaning and hidden will be treated as posts or comments and visible - * in the stream. + * in the stream. * * @param array $item * @return bool */ -function visible_activity($item) { - $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, 'Undo' ]; +function visible_activity($item) +{ + $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, 'Undo' ]; - if(intval($item['item_notshown'])) - return false; + if (intval($item['item_notshown'])) { + return false; + } - if ($item['obj_type'] === 'Answer') { - return false; - } + if ($item['obj_type'] === 'Answer') { + return false; + } - // This is an experiment at group federation with microblog platforms. - // We need the Announce or "boost" for group replies by non-connections to end up in the personal timeline - // of those patforms. Hide them on our own platform because they make the conversation look like dung. - // Performance wise this is a mess because we need to send two activities for every group comment. - - if ($item['verb'] === 'Announce' && $item['author_xchan'] === $item['owner_xchan']) { - return false; - } + // This is an experiment at group federation with microblog platforms. + // We need the Announce or "boost" for group replies by non-connections to end up in the personal timeline + // of those patforms. Hide them on our own platform because they make the conversation look like dung. + // Performance wise this is a mess because we need to send two activities for every group comment. - foreach($hidden_activities as $act) { - if((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) { - return false; - } - } + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $item['owner_xchan']) { + return false; + } - if(in_array($item['obj_type'],[ 'Event', 'Invite' ]) && in_array($item['verb'], [ 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'Ignore' ])) { - return false; - } + foreach ($hidden_activities as $act) { + if ((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) { + return false; + } + } - return true; + if (in_array($item['obj_type'], [ 'Event', 'Invite' ]) && in_array($item['verb'], [ 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'Ignore' ])) { + return false; + } + + return true; } /** @@ -379,658 +388,638 @@ function visible_activity($item) { * @param string $prepared_item * @return string */ -function conversation($items, $mode, $update, $page_mode = 'traditional', $prepared_item = '') { - - $content_html = ''; - $o = ''; - - require_once('bbcode.php'); - - $ssl_state = ((local_channel()) ? true : false); - - if (local_channel()) - load_pconfig(local_channel(),''); - - $profile_owner = 0; - $page_writeable = false; - $live_update_div = ''; - $jsreload = ''; - - $preview = (($page_mode === 'preview') ? true : false); - $previewing = (($preview) ? ' preview ' : ''); - $preview_lbl = t('This is an unsaved preview'); - - if (in_array($mode, [ 'stream', 'pubstream'])) { - - $profile_owner = local_channel(); - $page_writeable = ((local_channel()) ? true : false); - - if (!$update) { - // The special div is needed for liveUpdate to kick in for this page. - // We only launch liveUpdate if you aren't filtering in some incompatible - // way and also you aren't writing a comment (discovered in javascript). - - $live_update_div = '
                    ' . "\r\n" - . "\r\n"; - } - } - - elseif ($mode === 'hq') { - $profile_owner = local_channel(); - $page_writeable = true; - $live_update_div = '
                    ' . "\r\n"; - } - - elseif ($mode === 'channel') { - $profile_owner = App::$profile['profile_uid']; - $page_writeable = ($profile_owner == local_channel()); - - if (!$update) { - $tab = notags(trim($_GET['tab'])); - if ($tab === 'posts') { - // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, - // because browser prefetching might change it on us. We have to deliver it with the page. - - $live_update_div = '
                    ' . "\r\n" - . "\r\n"; - } - } - } - - elseif ($mode === 'cards') { - $profile_owner = App::$profile['profile_uid']; - $page_writeable = ($profile_owner == local_channel()); - $live_update_div = '
                    ' . "\r\n" - . "\r\n"; - $jsreload = $_SESSION['return_url']; - } - - elseif ($mode === 'articles') { - $profile_owner = App::$profile['profile_uid']; - $page_writeable = ($profile_owner == local_channel()); - $live_update_div = '
                    ' . "\r\n" - . "\r\n"; - $jsreload = $_SESSION['return_url']; - } - - - elseif ($mode === 'display') { - $profile_owner = local_channel(); - $page_writeable = false; - $live_update_div = '
                    ' . "\r\n"; - } - - elseif ($mode === 'page') { - $profile_owner = App::$profile['uid']; - $page_writeable = ($profile_owner == local_channel()); - $live_update_div = '
                    ' . "\r\n"; - } - - elseif ($mode === 'search') { - $live_update_div = '' . "\r\n"; - } - - elseif ($mode === 'moderate') { - $profile_owner = local_channel(); - } - - elseif ($mode === 'photos') { - $profile_owner = App::$profile['profile_uid']; - $page_writeable = ($profile_owner == local_channel()); - $live_update_div = '
                    ' . "\r\n"; - // for photos we've already formatted the top-level item (the photo) - $content_html = App::$data['photo_html']; - } - - $page_dropping = ((local_channel() && local_channel() == $profile_owner) ? true : false); - - if (! feature_enabled($profile_owner,'multi_delete')) - $page_dropping = false; - - $uploading = ((local_channel()) ? true : false); - - $channel = App::get_channel(); - $observer = App::get_observer(); - - if($update && isset($_SESSION['return_url'])) { - $return_url = $_SESSION['return_url']; - } - else { - $return_url = $_SESSION['return_url'] = App::$query_string; - } - - load_contact_links(local_channel()); - - $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview); - call_hooks('conversation_start',$cb); - - $items = $cb['items']; - - $conv_responses = [ - 'like' => [ 'title' => t('Likes','title') ], - 'dislike' => [ 'title' => t('Dislikes','title') ], - 'attendyes' => [ 'title' => t('Attending','title') ], - 'attendno' => [ 'title' => t('Not attending','title') ], - 'attendmaybe' => [ 'title' => t('Might attend' ,'title') ] - ]; - - - // array with html for each thread (parent+comments) - $threads = []; - $threadsid = -1; - - $page_template = get_markup_template("conversation.tpl"); - - if($items) { - - if(in_array($mode, [ 'stream-new', 'search', 'community', 'moderate' ])) { - - // "New Item View" on stream page or search page results - // - just loop through the items and format them minimally for display - - $tpl = 'search_item.tpl'; - - foreach($items as $item) { - - $x = [ - 'mode' => $mode, - 'item' => $item - ]; - call_hooks('stream_item',$x); - - $item = $x['item']; - - $threadsid++; - - $comment = ''; - $owner_url = ''; - $owner_photo = ''; - $owner_name = ''; - $sparkle = ''; - $is_new = false; - - if($mode === 'search' || $mode === 'community') { - if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) - && ($item['id'] != $item['parent'])) - continue; - } - - $sp = false; -// $profile_link = best_link_url($item,$sp); -// if($sp) -// $sparkle = ' sparkle'; -// else -// $profile_link = zid($profile_link); - - $profile_name = $item['author']['xchan_name']; - $profile_link = $item['author']['xchan_url']; - $profile_avatar = $item['author']['xchan_photo_m']; - - if($item['mid'] === $item['parent_mid'] && $item['author_xchan'] !== $item['owner_xchan']) { - $owner_name = $item['owner']['xchan_name']; - $owner_url = $item['owner']['xchan_url']; - $owner_photo = $item['owner']['xchan_photo']; - } - - - $location = format_location($item); - - localize_item($item); - if($mode === 'stream-new') - $dropping = true; - else - $dropping = false; - - $drop = array( - 'pagedropping' => $page_dropping, - 'dropping' => $dropping, - 'select' => t('Select'), - 'delete' => t('Delete'), - ); - - $star = array( - 'toggle' => t("Toggle Star Status"), - 'isstarred' => ((intval($item['item_starred'])) ? true : false), - ); - - $lock = (($item['item_private'] || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) - ? t('Private Message') - : false - ); - - $likebuttons = false; - $shareable = false; - - $verified = (intval($item['item_verified']) ? t('Message signature validated') : ''); - $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : ''); - - $unverified = ''; - -// $tags=[]; -// $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN,TERM_COMMUNITYTAG)); -// if(count($terms)) -// foreach($terms as $tag) -// $tags[] = format_term_for_display($tag); - - $body = prepare_body($item,true); - - $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); - - if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) - $is_new = true; - - $conv_link_mid = (($mode == 'moderate') ? $item['parent_mid'] : $item['mid']); - - $conv_link = ((in_array($item['item_type'],[ ITEM_TYPE_CARD, ITEM_TYPE_ARTICLE] )) ? $item['plink'] : z_root() . '/display/' . gen_link_id($conv_link_mid)); - - $allowed_type = (in_array($item['item_type'], get_config('system', 'pin_types', [ ITEM_TYPE_POST ])) ? true : false); - $pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []); - $pinned = ((! empty($pinned_items) && in_array($item['mid'], $pinned_items)) ? true : false); - - $tmp_item = array( - 'template' => $tpl, - 'toplevel' => 'toplevel_item', - 'item_type' => intval($item['item_type']), - 'mode' => $mode, - 'approve' => t('Approve'), - 'delete' => t('Delete'), - 'preview_lbl' => $preview_lbl, - 'id' => (($preview) ? 'P0' : $item['item_id']), - 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, $profile_url), - 'profile_url' => $profile_link, - 'thread_action_menu' => thread_action_menu($item,$mode), - 'thread_author_menu' => thread_author_menu($item,$mode), - 'name' => $profile_name, - 'sparkle' => $sparkle, - 'lock' => $lock, - 'thumb' => $profile_avatar, - 'title' => $item['title'], - 'body' => $body['html'], - 'event' => $body['event'], - 'photo' => $body['photo'], - 'tags' => $body['tags'], - 'categories' => $body['categories'], - 'mentions' => $body['mentions'], - 'attachments' => $body['attachments'], - 'folders' => $body['folders'], - 'verified' => $verified, - 'unverified' => $unverified, - 'forged' => $forged, - 'repeated' => ($item['verb'] === 'Announce'), - 'txt_cats' => t('Categories:'), - 'txt_folders' => t('Filed under:'), - 'has_cats' => (($body['categories']) ? 'true' : ''), - 'has_folders' => (($body['folders']) ? 'true' : ''), - 'text' => strip_tags($body['html']), - 'via' => t('via'), - 'ago' => relative_date($item['created']), - 'app' => $item['app'], - 'str_app' => sprintf( t('from %s'), $item['app']), - 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), - 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), - 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), - 'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''), - 'location' => $location, - 'divider' => false, - 'indent' => '', - 'owner_name' => $owner_name, - 'owner_url' => $owner_url, - 'owner_photo' => $owner_photo, - 'plink' => get_plink($item,false), - 'edpost' => false, - 'star' => ((feature_enabled(local_channel(),'star_posts')) ? $star : ''), - 'drop' => $drop, - 'vote' => $likebuttons, - 'like' => '', - 'dislike' => '', - 'comment' => '', - 'pinned' => ($pinned ? t('Pinned post') : ''), - 'pinnable' => (($item['mid'] === $item['parent_mid'] && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0) ? '1' : ''), - 'pinme' => ($pinned ? t('Unpin this post') : t('Pin this post')), - 'conv' => (($preview) ? '' : array('href'=> $conv_link, 'title'=> t('View Conversation'))), - 'previewing' => $previewing, - 'wait' => t('Please wait'), - 'thread_level' => 1, - 'has_tags' => $has_tags, - 'is_new' => $is_new - ); - - $arr = array('item' => $item, 'output' => $tmp_item); - call_hooks('display_item', $arr); - -// $threads[$threadsid]['id'] = $item['item_id']; - $threads[] = $arr['output']; - } - } - else { - - // Normal View -// logger('conv: items: ' . print_r($items,true)); - - $conv = new ThreadStream($mode, $preview, $uploading, $prepared_item); - - // In the display mode we don't have a profile owner. - - if($mode === 'display' && $items) - $conv->set_profile_owner($items[0]['uid']); - - // get all the topmost parents - // this shouldn't be needed, as we should have only them in our array - // But for now, this array respects the old style, just in case - - $threads = []; - foreach($items as $item) { - - - $x = [ 'mode' => $mode, 'item' => $item ]; - call_hooks('stream_item',$x); - - $item = $x['item']; - - builtin_activity_puller($item, $conv_responses); - - if(! visible_activity($item)) { - continue; - } - - - $item['pagedrop'] = $page_dropping; - - if($item['id'] == $item['parent']) { - - $item_object = new ThreadItem($item); - $conv->add_thread($item_object); - if(($page_mode === 'list') || ($page_mode === 'pager_list')) { - $item_object->set_template('conv_list.tpl'); - $item_object->set_display_mode('list'); - } - if($mode === 'cards' || $mode === 'articles') { - $item_object->set_reload($jsreload); - } - - } - } - - $threads = $conv->get_template_data($conv_responses); - if(!$threads) { - logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); - $threads = []; - } - //logger('threads: ' . print_r($threads,true), LOGGER_DATA); - } - } - - if(in_array($page_mode, [ 'traditional', 'preview', 'pager_list'] )) { - $page_template = get_markup_template("threaded_conversation.tpl"); - } - elseif($update) { - $page_template = get_markup_template("convobj.tpl"); - } - else { - $page_template = get_markup_template("conv_frame.tpl"); - $threads = null; - } - -// if($page_mode === 'preview') -// logger('preview: ' . print_r($threads,true)); +function conversation($items, $mode, $update, $page_mode = 'traditional', $prepared_item = '') +{ + + $content_html = ''; + $o = ''; + + require_once('bbcode.php'); + + $ssl_state = ((local_channel()) ? true : false); + + if (local_channel()) { + load_pconfig(local_channel(), ''); + } + + $profile_owner = 0; + $page_writeable = false; + $live_update_div = ''; + $jsreload = ''; + + $preview = (($page_mode === 'preview') ? true : false); + $previewing = (($preview) ? ' preview ' : ''); + $preview_lbl = t('This is an unsaved preview'); + + if (in_array($mode, [ 'stream', 'pubstream'])) { + $profile_owner = local_channel(); + $page_writeable = ((local_channel()) ? true : false); + + if (!$update) { + // The special div is needed for liveUpdate to kick in for this page. + // We only launch liveUpdate if you aren't filtering in some incompatible + // way and also you aren't writing a comment (discovered in javascript). + + $live_update_div = '
                    ' . "\r\n" + . "\r\n"; + } + } elseif ($mode === 'hq') { + $profile_owner = local_channel(); + $page_writeable = true; + $live_update_div = '
                    ' . "\r\n"; + } elseif ($mode === 'channel') { + $profile_owner = App::$profile['profile_uid']; + $page_writeable = ($profile_owner == local_channel()); + + if (!$update) { + $tab = notags(trim($_GET['tab'])); + if ($tab === 'posts') { + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, + // because browser prefetching might change it on us. We have to deliver it with the page. + + $live_update_div = '
                    ' . "\r\n" + . "\r\n"; + } + } + } elseif ($mode === 'cards') { + $profile_owner = App::$profile['profile_uid']; + $page_writeable = ($profile_owner == local_channel()); + $live_update_div = '
                    ' . "\r\n" + . "\r\n"; + $jsreload = $_SESSION['return_url']; + } elseif ($mode === 'articles') { + $profile_owner = App::$profile['profile_uid']; + $page_writeable = ($profile_owner == local_channel()); + $live_update_div = '
                    ' . "\r\n" + . "\r\n"; + $jsreload = $_SESSION['return_url']; + } elseif ($mode === 'display') { + $profile_owner = local_channel(); + $page_writeable = false; + $live_update_div = '
                    ' . "\r\n"; + } elseif ($mode === 'page') { + $profile_owner = App::$profile['uid']; + $page_writeable = ($profile_owner == local_channel()); + $live_update_div = '
                    ' . "\r\n"; + } elseif ($mode === 'search') { + $live_update_div = '' . "\r\n"; + } elseif ($mode === 'moderate') { + $profile_owner = local_channel(); + } elseif ($mode === 'photos') { + $profile_owner = App::$profile['profile_uid']; + $page_writeable = ($profile_owner == local_channel()); + $live_update_div = '
                    ' . "\r\n"; + // for photos we've already formatted the top-level item (the photo) + $content_html = App::$data['photo_html']; + } + + $page_dropping = ((local_channel() && local_channel() == $profile_owner) ? true : false); + + if (! feature_enabled($profile_owner, 'multi_delete')) { + $page_dropping = false; + } + + $uploading = ((local_channel()) ? true : false); + + $channel = App::get_channel(); + $observer = App::get_observer(); + + if ($update && isset($_SESSION['return_url'])) { + $return_url = $_SESSION['return_url']; + } else { + $return_url = $_SESSION['return_url'] = App::$query_string; + } + + load_contact_links(local_channel()); + + $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview); + call_hooks('conversation_start', $cb); + + $items = $cb['items']; + + $conv_responses = [ + 'like' => [ 'title' => t('Likes', 'title') ], + 'dislike' => [ 'title' => t('Dislikes', 'title') ], + 'attendyes' => [ 'title' => t('Attending', 'title') ], + 'attendno' => [ 'title' => t('Not attending', 'title') ], + 'attendmaybe' => [ 'title' => t('Might attend', 'title') ] + ]; + + + // array with html for each thread (parent+comments) + $threads = []; + $threadsid = -1; + + $page_template = get_markup_template("conversation.tpl"); + + if ($items) { + if (in_array($mode, [ 'stream-new', 'search', 'community', 'moderate' ])) { + // "New Item View" on stream page or search page results + // - just loop through the items and format them minimally for display + + $tpl = 'search_item.tpl'; + + foreach ($items as $item) { + $x = [ + 'mode' => $mode, + 'item' => $item + ]; + call_hooks('stream_item', $x); + + $item = $x['item']; + + $threadsid++; + + $comment = ''; + $owner_url = ''; + $owner_photo = ''; + $owner_name = ''; + $sparkle = ''; + $is_new = false; + + if ($mode === 'search' || $mode === 'community') { + if ( + ((activity_match($item['verb'], ACTIVITY_LIKE)) || (activity_match($item['verb'], ACTIVITY_DISLIKE))) + && ($item['id'] != $item['parent']) + ) { + continue; + } + } + + $sp = false; +// $profile_link = best_link_url($item,$sp); +// if($sp) +// $sparkle = ' sparkle'; +// else +// $profile_link = zid($profile_link); + + $profile_name = $item['author']['xchan_name']; + $profile_link = $item['author']['xchan_url']; + $profile_avatar = $item['author']['xchan_photo_m']; + + if ($item['mid'] === $item['parent_mid'] && $item['author_xchan'] !== $item['owner_xchan']) { + $owner_name = $item['owner']['xchan_name']; + $owner_url = $item['owner']['xchan_url']; + $owner_photo = $item['owner']['xchan_photo']; + } + + + $location = format_location($item); + + localize_item($item); + if ($mode === 'stream-new') { + $dropping = true; + } else { + $dropping = false; + } + + $drop = array( + 'pagedropping' => $page_dropping, + 'dropping' => $dropping, + 'select' => t('Select'), + 'delete' => t('Delete'), + ); + + $star = array( + 'toggle' => t("Toggle Star Status"), + 'isstarred' => ((intval($item['item_starred'])) ? true : false), + ); + + $lock = (($item['item_private'] || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + ? t('Private Message') + : false + ); + + $likebuttons = false; + $shareable = false; + + $verified = (intval($item['item_verified']) ? t('Message signature validated') : ''); + $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : ''); + + $unverified = ''; + +// $tags=[]; +// $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN,TERM_COMMUNITYTAG)); +// if(count($terms)) +// foreach($terms as $tag) +// $tags[] = format_term_for_display($tag); + + $body = prepare_body($item, true); + + $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); + + if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) { + $is_new = true; + } + + $conv_link_mid = (($mode == 'moderate') ? $item['parent_mid'] : $item['mid']); + + $conv_link = ((in_array($item['item_type'], [ ITEM_TYPE_CARD, ITEM_TYPE_ARTICLE])) ? $item['plink'] : z_root() . '/display/' . gen_link_id($conv_link_mid)); + + $allowed_type = (in_array($item['item_type'], get_config('system', 'pin_types', [ ITEM_TYPE_POST ])) ? true : false); + $pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []); + $pinned = ((! empty($pinned_items) && in_array($item['mid'], $pinned_items)) ? true : false); + + $tmp_item = array( + 'template' => $tpl, + 'toplevel' => 'toplevel_item', + 'item_type' => intval($item['item_type']), + 'mode' => $mode, + 'approve' => t('Approve'), + 'delete' => t('Delete'), + 'preview_lbl' => $preview_lbl, + 'id' => (($preview) ? 'P0' : $item['item_id']), + 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, $profile_url), + 'profile_url' => $profile_link, + 'thread_action_menu' => thread_action_menu($item, $mode), + 'thread_author_menu' => thread_author_menu($item, $mode), + 'name' => $profile_name, + 'sparkle' => $sparkle, + 'lock' => $lock, + 'thumb' => $profile_avatar, + 'title' => $item['title'], + 'body' => $body['html'], + 'event' => $body['event'], + 'photo' => $body['photo'], + 'tags' => $body['tags'], + 'categories' => $body['categories'], + 'mentions' => $body['mentions'], + 'attachments' => $body['attachments'], + 'folders' => $body['folders'], + 'verified' => $verified, + 'unverified' => $unverified, + 'forged' => $forged, + 'repeated' => ($item['verb'] === 'Announce'), + 'txt_cats' => t('Categories:'), + 'txt_folders' => t('Filed under:'), + 'has_cats' => (($body['categories']) ? 'true' : ''), + 'has_folders' => (($body['folders']) ? 'true' : ''), + 'text' => strip_tags($body['html']), + 'via' => t('via'), + 'ago' => relative_date($item['created']), + 'app' => $item['app'], + 'str_app' => sprintf(t('from %s'), $item['app']), + 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), + 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), + 'editedtime' => (($item['edited'] != $item['created']) ? sprintf(t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), + 'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf(t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')) : ''), + 'location' => $location, + 'divider' => false, + 'indent' => '', + 'owner_name' => $owner_name, + 'owner_url' => $owner_url, + 'owner_photo' => $owner_photo, + 'plink' => get_plink($item, false), + 'edpost' => false, + 'star' => ((feature_enabled(local_channel(), 'star_posts')) ? $star : ''), + 'drop' => $drop, + 'vote' => $likebuttons, + 'like' => '', + 'dislike' => '', + 'comment' => '', + 'pinned' => ($pinned ? t('Pinned post') : ''), + 'pinnable' => (($item['mid'] === $item['parent_mid'] && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0) ? '1' : ''), + 'pinme' => ($pinned ? t('Unpin this post') : t('Pin this post')), + 'conv' => (($preview) ? '' : array('href' => $conv_link, 'title' => t('View Conversation'))), + 'previewing' => $previewing, + 'wait' => t('Please wait'), + 'thread_level' => 1, + 'has_tags' => $has_tags, + 'is_new' => $is_new + ); + + $arr = array('item' => $item, 'output' => $tmp_item); + call_hooks('display_item', $arr); + +// $threads[$threadsid]['id'] = $item['item_id']; + $threads[] = $arr['output']; + } + } else { + // Normal View +// logger('conv: items: ' . print_r($items,true)); + + $conv = new ThreadStream($mode, $preview, $uploading, $prepared_item); + + // In the display mode we don't have a profile owner. + + if ($mode === 'display' && $items) { + $conv->set_profile_owner($items[0]['uid']); + } + + // get all the topmost parents + // this shouldn't be needed, as we should have only them in our array + // But for now, this array respects the old style, just in case + + $threads = []; + foreach ($items as $item) { + $x = [ 'mode' => $mode, 'item' => $item ]; + call_hooks('stream_item', $x); + + $item = $x['item']; + + builtin_activity_puller($item, $conv_responses); + + if (! visible_activity($item)) { + continue; + } + + + $item['pagedrop'] = $page_dropping; + + if ($item['id'] == $item['parent']) { + $item_object = new ThreadItem($item); + $conv->add_thread($item_object); + if (($page_mode === 'list') || ($page_mode === 'pager_list')) { + $item_object->set_template('conv_list.tpl'); + $item_object->set_display_mode('list'); + } + if ($mode === 'cards' || $mode === 'articles') { + $item_object->set_reload($jsreload); + } + } + } + + $threads = $conv->get_template_data($conv_responses); + if (!$threads) { + logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); + $threads = []; + } + //logger('threads: ' . print_r($threads,true), LOGGER_DATA); + } + } + + if (in_array($page_mode, [ 'traditional', 'preview', 'pager_list'])) { + $page_template = get_markup_template("threaded_conversation.tpl"); + } elseif ($update) { + $page_template = get_markup_template("convobj.tpl"); + } else { + $page_template = get_markup_template("conv_frame.tpl"); + $threads = null; + } + +// if($page_mode === 'preview') +// logger('preview: ' . print_r($threads,true)); // Do not un-comment if smarty3 is in use -// logger('page_template: ' . $page_template); +// logger('page_template: ' . $page_template); -// logger('nouveau: ' . print_r($threads,true)); +// logger('nouveau: ' . print_r($threads,true)); // logger('page_template: ' . print_r($page_template,true)); - $o .= replace_macros($page_template, array( - '$baseurl' => z_root(), - '$photo_item' => $content_html, - '$live_update' => $live_update_div, - '$remove' => t('remove'), - '$mode' => $mode, - '$user' => App::$user, - '$threads' => $threads, - '$wait' => t('Loading...'), - '$dropping' => ($page_dropping?t('Delete Selected Items'):False), - )); + $o .= replace_macros($page_template, array( + '$baseurl' => z_root(), + '$photo_item' => $content_html, + '$live_update' => $live_update_div, + '$remove' => t('remove'), + '$mode' => $mode, + '$user' => App::$user, + '$threads' => $threads, + '$wait' => t('Loading...'), + '$dropping' => ($page_dropping ? t('Delete Selected Items') : false), + )); - return $o; + return $o; } -function best_link_url($item) { +function best_link_url($item) +{ - $best_url = ''; - $sparkle = false; + $best_url = ''; + $sparkle = false; - $clean_url = normalise_link($item['author-link']); + $clean_url = normalise_link($item['author-link']); - if((local_channel()) && (local_channel() == $item['uid'])) { - if(isset(App::$contacts) && x(App::$contacts,$clean_url)) { - if(App::$contacts[$clean_url]['network'] === NETWORK_DFRN) { - $best_url = z_root() . '/redir/' . App::$contacts[$clean_url]['id']; - $sparkle = true; - } - else - $best_url = App::$contacts[$clean_url]['url']; - } - } - if(! $best_url) { - if(strlen($item['author-link'])) - $best_url = $item['author-link']; - else - $best_url = $item['url']; - } + if ((local_channel()) && (local_channel() == $item['uid'])) { + if (isset(App::$contacts) && x(App::$contacts, $clean_url)) { + if (App::$contacts[$clean_url]['network'] === NETWORK_DFRN) { + $best_url = z_root() . '/redir/' . App::$contacts[$clean_url]['id']; + $sparkle = true; + } else { + $best_url = App::$contacts[$clean_url]['url']; + } + } + } + if (! $best_url) { + if (strlen($item['author-link'])) { + $best_url = $item['author-link']; + } else { + $best_url = $item['url']; + } + } - return $best_url; + return $best_url; } -function thread_action_menu($item,$mode = '') { +function thread_action_menu($item, $mode = '') +{ - $menu = []; - - if((local_channel()) && local_channel() == $item['uid']) { - $menu[] = [ - 'menu' => 'view_source', - 'title' => t('View Source'), - 'icon' => 'code', - 'action' => 'viewsrc(' . $item['id'] . '); return false;', - 'href' => '#' - ]; + $menu = []; - if(! in_array($mode, [ 'stream-new', 'search', 'community'])) { - if($item['parent'] == $item['id'] && (get_observer_hash() != $item['author_xchan'])) { - $menu[] = [ - 'menu' => 'follow_thread', - 'title' => t('Follow Thread'), - 'icon' => 'plus', - 'action' => 'dosubthread(' . $item['id'] . '); return false;', - 'href' => '#' - ]; - } + if ((local_channel()) && local_channel() == $item['uid']) { + $menu[] = [ + 'menu' => 'view_source', + 'title' => t('View Source'), + 'icon' => 'code', + 'action' => 'viewsrc(' . $item['id'] . '); return false;', + 'href' => '#' + ]; - $menu[] = [ - 'menu' => 'unfollow_thread', - 'title' => t('Unfollow Thread'), - 'icon' => 'minus', - 'action' => 'dounsubthread(' . $item['id'] . '); return false;', - 'href' => '#' - ]; - } + if (! in_array($mode, [ 'stream-new', 'search', 'community'])) { + if ($item['parent'] == $item['id'] && (get_observer_hash() != $item['author_xchan'])) { + $menu[] = [ + 'menu' => 'follow_thread', + 'title' => t('Follow Thread'), + 'icon' => 'plus', + 'action' => 'dosubthread(' . $item['id'] . '); return false;', + 'href' => '#' + ]; + } - } + $menu[] = [ + 'menu' => 'unfollow_thread', + 'title' => t('Unfollow Thread'), + 'icon' => 'minus', + 'action' => 'dounsubthread(' . $item['id'] . '); return false;', + 'href' => '#' + ]; + } + } - $args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ]; - call_hooks('thread_action_menu', $args); + $args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ]; + call_hooks('thread_action_menu', $args); - return $args['menu']; + return $args['menu']; } -function author_is_pmable($xchan, $abook) { +function author_is_pmable($xchan, $abook) +{ - $x = [ 'xchan' => $xchan, 'abook' => $abook, 'result' => 'unset' ]; - call_hooks('author_is_pmable',$x); - if($x['result'] !== 'unset') - return $x['result']; - - if($xchan['xchan_network'] === 'zot6' && get_observer_hash()) - return true; - return false; + $x = [ 'xchan' => $xchan, 'abook' => $abook, 'result' => 'unset' ]; + call_hooks('author_is_pmable', $x); + if ($x['result'] !== 'unset') { + return $x['result']; + } + if ($xchan['xchan_network'] === 'zot6' && get_observer_hash()) { + return true; + } + return false; } -function thread_author_menu($item, $mode = '') { +function thread_author_menu($item, $mode = '') +{ - $menu = []; + $menu = []; - $local_channel = local_channel(); - - if($local_channel) { - if(! count(App::$contacts)) - load_contact_links($local_channel); - $channel = App::get_channel(); - $channel_hash = (($channel) ? $channel['channel_hash'] : ''); - } + $local_channel = local_channel(); - $profile_link = chanlink_hash($item['author_xchan']); - $contact = false; + if ($local_channel) { + if (! count(App::$contacts)) { + load_contact_links($local_channel); + } + $channel = App::get_channel(); + $channel_hash = (($channel) ? $channel['channel_hash'] : ''); + } - if($channel['channel_hash'] !== $item['author_xchan']) { - if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts)) { - $contact = App::$contacts[$item['author_xchan']]; - } - else { - if($local_channel && (! in_array($item['author']['xchan_network'],[ 'rss', 'anon','token','unknown' ]))) { - $follow_url = z_root() . '/follow/?f=&url=' . urlencode(($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']) . '&interactive=0'; - } - } - } + $profile_link = chanlink_hash($item['author_xchan']); + $contact = false; - $poke_label = ucfirst( t(get_pconfig($local_channel,'system','pokeverb','poke')) ); + if ($channel['channel_hash'] !== $item['author_xchan']) { + if (App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) { + $contact = App::$contacts[$item['author_xchan']]; + } else { + if ($local_channel && (! in_array($item['author']['xchan_network'], [ 'rss', 'anon','token','unknown' ]))) { + $follow_url = z_root() . '/follow/?f=&url=' . urlencode(($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']) . '&interactive=0'; + } + } + } - if($contact) { - if (! (isset($contact['abook_self']) && intval($contact['abook_self']))) { - $contact_url = z_root() . '/connedit/' . $contact['abook_id']; - } - $posts_link = z_root() . '/stream/?cid=' . $contact['abook_id']; - $clean_url = $item['author']['xchan_url']; - } + $poke_label = ucfirst(t(get_pconfig($local_channel, 'system', 'pokeverb', 'poke'))); - $can_dm = false; + if ($contact) { + if (! (isset($contact['abook_self']) && intval($contact['abook_self']))) { + $contact_url = z_root() . '/connedit/' . $contact['abook_id']; + } + $posts_link = z_root() . '/stream/?cid=' . $contact['abook_id']; + $clean_url = $item['author']['xchan_url']; + } - if ($local_channel && $contact) { - $can_dm = perm_is_allowed($local_channel,$item['author_xchan'],'send_stream'); - } - elseif ($item['author']['xchan_network'] === 'activitypub') { - $can_dm = true; - } -// if ($can_dm) { -// $pm_url = z_root() . '/rpost?to=' . urlencode($item['author_xchan']); -// } - - if($profile_link) { - $menu[] = [ - 'menu' => 'view_profile', - 'title' => t('Visit'), - 'icon' => 'fw', - 'action' => '', - 'href' => $profile_link - ]; - } + $can_dm = false; - if(isset($posts_link) && $posts_link) { - $menu[] = [ - 'menu' => 'view_posts', - 'title' => t('Recent Activity'), - 'icon' => 'fw', - 'action' => '', - 'href' => $posts_link - ]; - } + if ($local_channel && $contact) { + $can_dm = perm_is_allowed($local_channel, $item['author_xchan'], 'send_stream'); + } elseif ($item['author']['xchan_network'] === 'activitypub') { + $can_dm = true; + } +// if ($can_dm) { +// $pm_url = z_root() . '/rpost?to=' . urlencode($item['author_xchan']); +// } - if(isset($follow_url) && $follow_url) { - $menu[] = [ - 'menu' => 'follow', - 'title' => t('Connect'), - 'icon' => 'fw', - 'action' => 'doFollowAuthor(\'' . $follow_url . '\'); return false;', - 'href' => '#', - ]; - } + if ($profile_link) { + $menu[] = [ + 'menu' => 'view_profile', + 'title' => t('Visit'), + 'icon' => 'fw', + 'action' => '', + 'href' => $profile_link + ]; + } - if(isset($contact_url) && $contact_url) { - $menu[] = [ - 'menu' => 'connedit', - 'title' => t('Edit Connection'), - 'icon' => 'fw', - 'action' => '', - 'href' => $contact_url - ]; - } + if (isset($posts_link) && $posts_link) { + $menu[] = [ + 'menu' => 'view_posts', + 'title' => t('Recent Activity'), + 'icon' => 'fw', + 'action' => '', + 'href' => $posts_link + ]; + } - if(isset($pm_url) && $pm_url) { - $menu[] = [ - 'menu' => 'prv_message', - 'title' => t('Direct Message'), - 'icon' => 'fw', - 'action' => '', - 'href' => $pm_url - ]; - } + if (isset($follow_url) && $follow_url) { + $menu[] = [ + 'menu' => 'follow', + 'title' => t('Connect'), + 'icon' => 'fw', + 'action' => 'doFollowAuthor(\'' . $follow_url . '\'); return false;', + 'href' => '#', + ]; + } - if (Apps::system_app_installed($local_channel,'Poke')) { - $menu[] = [ - 'menu' => 'poke', - 'title' => $poke_label, - 'icon' => 'fw', - 'action' => 'doPoke(\'' . urlencode($item['author_xchan']) . '\'); return false;', - 'href' => '#' - ]; - } + if (isset($contact_url) && $contact_url) { + $menu[] = [ + 'menu' => 'connedit', + 'title' => t('Edit Connection'), + 'icon' => 'fw', + 'action' => '', + 'href' => $contact_url + ]; + } - if (local_channel()) { - $menu[] = [ - 'menu' => 'superblocksite', - 'title' => t('Block author\'s site'), - 'icon' => 'fw', - 'action' => 'blocksite(\'' . urlencode($item['author_xchan']) . '\',' . $item['id'] . '); return false;', - 'href' => '#' - ]; - $menu[] = [ - 'menu' => 'superblock', - 'title' => t('Block author'), - 'icon' => 'fw', - 'action' => 'superblock(\'' . urlencode($item['author_xchan']) . '\',' . $item['id'] . '); return false;', - 'href' => '#' - ]; - } + if (isset($pm_url) && $pm_url) { + $menu[] = [ + 'menu' => 'prv_message', + 'title' => t('Direct Message'), + 'icon' => 'fw', + 'action' => '', + 'href' => $pm_url + ]; + } - $args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ]; - call_hooks('thread_author_menu', $args); + if (Apps::system_app_installed($local_channel, 'Poke')) { + $menu[] = [ + 'menu' => 'poke', + 'title' => $poke_label, + 'icon' => 'fw', + 'action' => 'doPoke(\'' . urlencode($item['author_xchan']) . '\'); return false;', + 'href' => '#' + ]; + } - return $args['menu']; + if (local_channel()) { + $menu[] = [ + 'menu' => 'superblocksite', + 'title' => t('Block author\'s site'), + 'icon' => 'fw', + 'action' => 'blocksite(\'' . urlencode($item['author_xchan']) . '\',' . $item['id'] . '); return false;', + 'href' => '#' + ]; + $menu[] = [ + 'menu' => 'superblock', + 'title' => t('Block author'), + 'icon' => 'fw', + 'action' => 'superblock(\'' . urlencode($item['author_xchan']) . '\',' . $item['id'] . '); return false;', + 'href' => '#' + ]; + } + $args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ]; + call_hooks('thread_author_menu', $args); + + return $args['menu']; } @@ -1045,72 +1034,78 @@ function thread_author_menu($item, $mode = '') { * @param array $item * @param array &$conv_responses (already created with builtin activity structure) */ -function builtin_activity_puller($item, &$conv_responses) { +function builtin_activity_puller($item, &$conv_responses) +{ - // if this item is a post or comment there's nothing for us to do here, just return. + // if this item is a post or comment there's nothing for us to do here, just return. - if(in_array($item['verb'],['Create'])) - return; + if (in_array($item['verb'], ['Create'])) { + return; + } - foreach($conv_responses as $mode => $v) { + foreach ($conv_responses as $mode => $v) { + $url = ''; - $url = ''; + switch ($mode) { + case 'like': + $verb = ACTIVITY_LIKE; + break; + case 'dislike': + $verb = ACTIVITY_DISLIKE; + break; + case 'attendyes': + $verb = 'Accept'; + break; + case 'attendno': + $verb = 'Reject'; + break; + case 'attendmaybe': + $verb = 'TentativeAccept'; + break; + default: + return; + break; + } - switch($mode) { - case 'like': - $verb = ACTIVITY_LIKE; - break; - case 'dislike': - $verb = ACTIVITY_DISLIKE; - break; - case 'attendyes': - $verb = 'Accept'; - break; - case 'attendno': - $verb = 'Reject'; - break; - case 'attendmaybe': - $verb = 'TentativeAccept'; - break; - default: - return; - break; - } + if ((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) { + $name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown')); + $url = (($item['author_xchan'] && $item['author']['xchan_photo_s']) + ? '' . '' . urlencode($name) . ' ' . $name . '' + : '' . $name . '' + ); - if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) { + if (! $item['thr_parent']) { + $item['thr_parent'] = $item['parent_mid']; + } - $name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown')); - $url = (($item['author_xchan'] && $item['author']['xchan_photo_s']) - ? '' . '' . urlencode($name) . ' ' . $name . '' - : '' . $name . '' - ); + if ( + ! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) + && (is_array($conv_responses[$mode][$item['thr_parent'] . '-l']))) + ) { + $conv_responses[$mode][$item['thr_parent'] . '-l'] = []; + } - if(! $item['thr_parent']) - $item['thr_parent'] = $item['parent_mid']; + // only list each unique author once + if (in_array($url, $conv_responses[$mode][$item['thr_parent'] . '-l'])) { + continue; + } - if(! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) - && (is_array($conv_responses[$mode][$item['thr_parent'] . '-l'])))) - $conv_responses[$mode][$item['thr_parent'] . '-l'] = []; + if (! isset($conv_responses[$mode][$item['thr_parent']])) { + $conv_responses[$mode][$item['thr_parent']] = 1; + } else { + $conv_responses[$mode][$item['thr_parent']] ++; + } - // only list each unique author once - if(in_array($url,$conv_responses[$mode][$item['thr_parent'] . '-l'])) - continue; + $conv_responses[$mode][$item['thr_parent'] . '-l'][] = $url; + if (get_observer_hash() && get_observer_hash() === $item['author_xchan']) { + $conv_responses[$mode][$item['thr_parent'] . '-m'] = true; + } - if(! isset($conv_responses[$mode][$item['thr_parent']])) - $conv_responses[$mode][$item['thr_parent']] = 1; - else - $conv_responses[$mode][$item['thr_parent']] ++; - - $conv_responses[$mode][$item['thr_parent'] . '-l'][] = $url; - if(get_observer_hash() && get_observer_hash() === $item['author_xchan']) { - $conv_responses[$mode][$item['thr_parent'] . '-m'] = true; - } - - // there can only be one activity verb per item so if we found anything, we can stop looking - return; - } - } + // there can only be one activity verb per item so if we found anything, we can stop looking + return; + } + } } @@ -1123,632 +1118,649 @@ function builtin_activity_puller($item, &$conv_responses) { * @param int $id item id * @return string formatted text */ -function format_like($cnt, $arr, $type, $id) { - $o = ''; - if ($cnt == 1) { - $o .= (($type === 'like') ? sprintf( t('%s likes this.'), $arr[0]) : sprintf( t('%s doesn\'t like this.'), $arr[0])) . EOL ; - } else { - $spanatts = 'class="fakelink" onclick="openClose(\'' . $type . 'list-' . $id . '\');"'; - $o .= (($type === 'like') ? - sprintf( tt('%2$d people like this.','%2$d people like this.',$cnt), $spanatts, $cnt) - : - sprintf( tt('%2$d people don\'t like this.','%2$d people don\'t like this.',$cnt), $spanatts, $cnt) ); - $o .= EOL; - $total = count($arr); - if($total >= MAX_LIKERS) - $arr = array_slice($arr, 0, MAX_LIKERS - 1); - if($total < MAX_LIKERS) - $arr[count($arr)-1] = t('and') . ' ' . $arr[count($arr)-1]; - $str = implode(', ', $arr); - if($total >= MAX_LIKERS) - $str .= sprintf( tt(', and %d other people',', and %d other people',$total - MAX_LIKERS), $total - MAX_LIKERS ); - $str = (($type === 'like') ? sprintf( t('%s like this.'), $str) : sprintf( t('%s don\'t like this.'), $str)); - $o .= "\t" . ''; - } +function format_like($cnt, $arr, $type, $id) +{ + $o = ''; + if ($cnt == 1) { + $o .= (($type === 'like') ? sprintf(t('%s likes this.'), $arr[0]) : sprintf(t('%s doesn\'t like this.'), $arr[0])) . EOL ; + } else { + $spanatts = 'class="fakelink" onclick="openClose(\'' . $type . 'list-' . $id . '\');"'; + $o .= (($type === 'like') ? + sprintf(tt('%2$d people like this.', '%2$d people like this.', $cnt), $spanatts, $cnt) + : + sprintf(tt('%2$d people don\'t like this.', '%2$d people don\'t like this.', $cnt), $spanatts, $cnt) ); + $o .= EOL; + $total = count($arr); + if ($total >= MAX_LIKERS) { + $arr = array_slice($arr, 0, MAX_LIKERS - 1); + } + if ($total < MAX_LIKERS) { + $arr[count($arr) - 1] = t('and') . ' ' . $arr[count($arr) - 1]; + } + $str = implode(', ', $arr); + if ($total >= MAX_LIKERS) { + $str .= sprintf(tt(', and %d other people', ', and %d other people', $total - MAX_LIKERS), $total - MAX_LIKERS); + } + $str = (($type === 'like') ? sprintf(t('%s like this.'), $str) : sprintf(t('%s don\'t like this.'), $str)); + $o .= "\t" . ''; + } - return $o; + return $o; } /** * Wrapper to allow addons to replace the status editor if desired. */ -function status_editor($x, $popup = false, $module='') { +function status_editor($x, $popup = false, $module = '') +{ $hook_info = ['editor_html' => '', 'x' => $x, 'popup' => $popup, 'module' => $module]; - call_hooks('status_editor',$hook_info); + call_hooks('status_editor', $hook_info); if ($hook_info['editor_html'] == '') { - return z_status_editor($x, $popup); - } - else { - return $hook_info['editor_html']; + return z_status_editor($x, $popup); + } else { + return $hook_info['editor_html']; } } /** - * This is our general purpose content editor. + * This is our general purpose content editor. * It was once nicknamed "jot" and you may see references to "jot" littered throughout the code. - * They are referring to the content editor or components thereof. + * They are referring to the content editor or components thereof. */ -function z_status_editor($x, $popup = false) { +function z_status_editor($x, $popup = false) +{ - $o = ''; + $o = ''; - $c = channelx_by_n($x['profile_uid']); - if($c && $c['channel_moved']) - return $o; + $c = channelx_by_n($x['profile_uid']); + if ($c && $c['channel_moved']) { + return $o; + } - $plaintext = true; - $webpage = false; - $feature_voting = false; + $plaintext = true; + $webpage = false; + $feature_voting = false; - $feature_comment_control = Apps::system_app_installed($x['profile_uid'], 'Comment Control'); - if(x($x, 'disable_comment_control')) - $feature_comment_control = false; + $feature_comment_control = Apps::system_app_installed($x['profile_uid'], 'Comment Control'); + if (x($x, 'disable_comment_control')) { + $feature_comment_control = false; + } - $feature_expire = ((Apps::system_app_installed($x['profile_uid'], 'Expire Posts') && (! $webpage)) ? true : false); - if(x($x, 'hide_expire')) - $feature_expire = false; + $feature_expire = ((Apps::system_app_installed($x['profile_uid'], 'Expire Posts') && (! $webpage)) ? true : false); + if (x($x, 'hide_expire')) { + $feature_expire = false; + } - $feature_future = ((Apps::system_app_installed($x['profile_uid'], 'Future Posting') && (! $webpage)) ? true : false); - if(x($x, 'hide_future')) - $feature_future = false; + $feature_future = ((Apps::system_app_installed($x['profile_uid'], 'Future Posting') && (! $webpage)) ? true : false); + if (x($x, 'hide_future')) { + $feature_future = false; + } - $feature_markup = ((Apps::system_app_installed($x['profile_uid'], 'Markup') && (! $webpage)) ? true : false); - if(x($x, 'hide_markup')) - $feature_markup = false; + $feature_markup = ((Apps::system_app_installed($x['profile_uid'], 'Markup') && (! $webpage)) ? true : false); + if (x($x, 'hide_markup')) { + $feature_markup = false; + } - $geotag = (($x['allow_location']) ? replace_macros(get_markup_template('jot_geotag.tpl'), []) : ''); - $setloc = t('Set your location'); - $clearloc = ((get_pconfig($x['profile_uid'], 'system', 'use_browser_location')) ? t('Clear browser location') : ''); - if(x($x, 'hide_location')) - $geotag = $setloc = $clearloc = ''; + $geotag = (($x['allow_location']) ? replace_macros(get_markup_template('jot_geotag.tpl'), []) : ''); + $setloc = t('Set your location'); + $clearloc = ((get_pconfig($x['profile_uid'], 'system', 'use_browser_location')) ? t('Clear browser location') : ''); + if (x($x, 'hide_location')) { + $geotag = $setloc = $clearloc = ''; + } - $summaryenabled = ((array_key_exists('allow_summary',$x)) ? intval($x['allow_summary']) : false); + $summaryenabled = ((array_key_exists('allow_summary', $x)) ? intval($x['allow_summary']) : false); - $mimetype = ((x($x,'mimetype')) ? $x['mimetype'] : 'text/bbcode'); + $mimetype = ((x($x, 'mimetype')) ? $x['mimetype'] : 'text/bbcode'); - $mimeselect = ((x($x,'mimeselect')) ? $x['mimeselect'] : false); - if($mimeselect) - $mimeselect = mimetype_select($x['profile_uid'], $mimetype); - else - $mimeselect = ''; + $mimeselect = ((x($x, 'mimeselect')) ? $x['mimeselect'] : false); + if ($mimeselect) { + $mimeselect = mimetype_select($x['profile_uid'], $mimetype); + } else { + $mimeselect = ''; + } - $weblink = (($mimetype === 'text/bbcode') ? t('Insert web link') : false); - if(x($x, 'hide_weblink')) - $weblink = false; - - $embedPhotos = t('Embed (existing) photo from your photo albums'); + $weblink = (($mimetype === 'text/bbcode') ? t('Insert web link') : false); + if (x($x, 'hide_weblink')) { + $weblink = false; + } - $writefiles = (($mimetype === 'text/bbcode') ? perm_is_allowed($x['profile_uid'], get_observer_hash(), 'write_storage') : false); - if(x($x, 'hide_attach')) - $writefiles = false; - if(perm_is_allowed($x['profile_uid'],get_observer_hash(),'moderated')) { - $writefiles = false; - } + $embedPhotos = t('Embed (existing) photo from your photo albums'); - $layout = ((x($x,'layout')) ? $x['layout'] : ''); + $writefiles = (($mimetype === 'text/bbcode') ? perm_is_allowed($x['profile_uid'], get_observer_hash(), 'write_storage') : false); + if (x($x, 'hide_attach')) { + $writefiles = false; + } + if (perm_is_allowed($x['profile_uid'], get_observer_hash(), 'moderated')) { + $writefiles = false; + } - $layoutselect = ((x($x,'layoutselect')) ? $x['layoutselect'] : false); - if($layoutselect) - $layoutselect = layout_select($x['profile_uid'], $layout); - else - $layoutselect = ''; + $layout = ((x($x, 'layout')) ? $x['layout'] : ''); - if(array_key_exists('channel_select',$x) && $x['channel_select']) { - require_once('include/channel.php'); - $id_select = identity_selector(); - } - else - $id_select = ''; + $layoutselect = ((x($x, 'layoutselect')) ? $x['layoutselect'] : false); + if ($layoutselect) { + $layoutselect = layout_select($x['profile_uid'], $layout); + } else { + $layoutselect = ''; + } - $webpage = ((x($x,'webpage')) ? $x['webpage'] : ''); + if (array_key_exists('channel_select', $x) && $x['channel_select']) { + require_once('include/channel.php'); + $id_select = identity_selector(); + } else { + $id_select = ''; + } - $reset = ((x($x,'reset')) ? $x['reset'] : ''); - - $feature_auto_save_draft = ((feature_enabled($x['profile_uid'], 'auto_save_draft')) ? "true" : "false"); - - $tpl = get_markup_template('jot-header.tpl'); + $webpage = ((x($x, 'webpage')) ? $x['webpage'] : ''); - if (! isset(App::$page['htmlhead'])) { - App::$page['htmlhead'] = EMPTY_STR; - } + $reset = ((x($x, 'reset')) ? $x['reset'] : ''); - App::$page['htmlhead'] .= replace_macros($tpl, array( - '$baseurl' => z_root(), - '$webpage' => $webpage, - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$pretext' => ((x($x,'pretext')) ? $x['pretext'] : ''), - '$geotag' => $geotag, - '$nickname' => $x['nickname'], - '$linkurl' => t('Please enter a link URL:'), - '$term' => t('Tag term:'), - '$whereareu' => t('Where are you right now?'), - '$editor_autocomplete'=> ((x($x,'editor_autocomplete')) ? $x['editor_autocomplete'] : ''), - '$bbco_autocomplete'=> ((x($x,'bbco_autocomplete')) ? $x['bbco_autocomplete'] : ''), - '$modalchooseimages' => t('Choose images to embed'), - '$modalchoosealbum' => t('Choose an album'), - '$modaldiffalbum' => t('Choose a different album...'), - '$modalerrorlist' => t('Error getting album list'), - '$modalerrorlink' => t('Error getting photo link'), - '$modalerroralbum' => t('Error getting album'), - '$auto_save_draft' => $feature_auto_save_draft, - '$confirmdelete' => t('Delete this item?'), - '$reset' => $reset - )); + $feature_auto_save_draft = ((feature_enabled($x['profile_uid'], 'auto_save_draft')) ? "true" : "false"); - $tpl = get_markup_template('jot.tpl'); + $tpl = get_markup_template('jot-header.tpl'); - $preview = t('Preview'); - if(x($x, 'hide_preview')) - $preview = ''; + if (! isset(App::$page['htmlhead'])) { + App::$page['htmlhead'] = EMPTY_STR; + } - $defexpire = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_expire')) && (! $webpage)) ? $z : ''); - if($defexpire) - $defexpire = datetime_convert('UTC',date_default_timezone_get(),$defexpire,'Y-m-d H:i'); - else { - $defexpire = ((($z = intval(get_pconfig($x['profile_uid'], 'system', 'selfexpiredays'))) && (! $webpage)) ? $z : ''); - if($defexpire) - $defexpire = datetime_convert('UTC',date_default_timezone_get(),"now + $defexpire days",'Y-m-d H:i'); - } + App::$page['htmlhead'] .= replace_macros($tpl, array( + '$baseurl' => z_root(), + '$webpage' => $webpage, + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => ((x($x, 'pretext')) ? $x['pretext'] : ''), + '$geotag' => $geotag, + '$nickname' => $x['nickname'], + '$linkurl' => t('Please enter a link URL:'), + '$term' => t('Tag term:'), + '$whereareu' => t('Where are you right now?'), + '$editor_autocomplete' => ((x($x, 'editor_autocomplete')) ? $x['editor_autocomplete'] : ''), + '$bbco_autocomplete' => ((x($x, 'bbco_autocomplete')) ? $x['bbco_autocomplete'] : ''), + '$modalchooseimages' => t('Choose images to embed'), + '$modalchoosealbum' => t('Choose an album'), + '$modaldiffalbum' => t('Choose a different album...'), + '$modalerrorlist' => t('Error getting album list'), + '$modalerrorlink' => t('Error getting photo link'), + '$modalerroralbum' => t('Error getting album'), + '$auto_save_draft' => $feature_auto_save_draft, + '$confirmdelete' => t('Delete this item?'), + '$reset' => $reset + )); + + $tpl = get_markup_template('jot.tpl'); + + $preview = t('Preview'); + if (x($x, 'hide_preview')) { + $preview = ''; + } + + $defexpire = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_expire')) && (! $webpage)) ? $z : ''); + if ($defexpire) { + $defexpire = datetime_convert('UTC', date_default_timezone_get(), $defexpire, 'Y-m-d H:i'); + } else { + $defexpire = ((($z = intval(get_pconfig($x['profile_uid'], 'system', 'selfexpiredays'))) && (! $webpage)) ? $z : ''); + if ($defexpire) { + $defexpire = datetime_convert('UTC', date_default_timezone_get(), "now + $defexpire days", 'Y-m-d H:i'); + } + } - $defclosecomm = ((($z = get_pconfig($x['profile_uid'], 'system', 'close_comments',0)) && (! $webpage)) ? intval($z) : ''); - if($defclosecomm) { - $closecommdays = intval($defclosecomm); - } - else { - $closecommdays = EMPTY_STR; - } + $defclosecomm = ((($z = get_pconfig($x['profile_uid'], 'system', 'close_comments', 0)) && (! $webpage)) ? intval($z) : ''); + if ($defclosecomm) { + $closecommdays = intval($defclosecomm); + } else { + $closecommdays = EMPTY_STR; + } - $defcommuntil = (($closecommdays) ? datetime_convert('UTC', date_default_timezone_get(), 'now + ' . $closecommdays . ' days') : EMPTY_STR); + $defcommuntil = (($closecommdays) ? datetime_convert('UTC', date_default_timezone_get(), 'now + ' . $closecommdays . ' days') : EMPTY_STR); - $defpublish = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_publish')) && (! $webpage)) ? $z : ''); - if($defpublish) - $defpublish = datetime_convert('UTC',date_default_timezone_get(),$defpublish,'Y-m-d H:i'); + $defpublish = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_publish')) && (! $webpage)) ? $z : ''); + if ($defpublish) { + $defpublish = datetime_convert('UTC', date_default_timezone_get(), $defpublish, 'Y-m-d H:i'); + } - $cipher = get_pconfig($x['profile_uid'], 'system', 'default_cipher'); - if(! $cipher) - $cipher = 'AES-128-CCM'; + $cipher = get_pconfig($x['profile_uid'], 'system', 'default_cipher'); + if (! $cipher) { + $cipher = 'AES-128-CCM'; + } - if(array_key_exists('catsenabled',$x)) - $catsenabled = $x['catsenabled']; - else - $catsenabled = ((Apps::system_app_installed($x['profile_uid'], 'Categories') && (! $webpage)) ? 'categories' : ''); + if (array_key_exists('catsenabled', $x)) { + $catsenabled = $x['catsenabled']; + } else { + $catsenabled = ((Apps::system_app_installed($x['profile_uid'], 'Categories') && (! $webpage)) ? 'categories' : ''); + } - // we only need the comment_perms for the editor, but this logic is complicated enough (from Settings/Channel) - // that we will just duplicate most of that code block + // we only need the comment_perms for the editor, but this logic is complicated enough (from Settings/Channel) + // that we will just duplicate most of that code block - $global_perms = Permissions::Perms(); + $global_perms = Permissions::Perms(); - $permiss = []; - - $perm_opts = [ - [ t('Restricted - from connections only'), PERMS_SPECIFIC ], - [ t('Semi-public - from anybody that can be identified'), PERMS_AUTHED ], - [ t('Public - from anybody on the internet'), PERMS_PUBLIC ] - ]; - - $limits = PermissionLimits::Get(local_channel()); - $anon_comments = get_config('system','anonymous_comments'); - - foreach($global_perms as $k => $perm) { - $options = []; - $can_be_public = ((strstr($k,'view') || ($k === 'post_comments' && $anon_comments)) ? true : false); - foreach($perm_opts as $opt) { - if($opt[1] == PERMS_PUBLIC && (! $can_be_public)) - continue; - $options[$opt[1]] = $opt[0]; - } - if($k === 'post_comments') { - $comment_perms = [ $k, t('Accept delivery of comments and likes on this post from'), $limits[$k],'',$options ]; - } - else { - $permiss[] = array($k,$perm,$limits[$k],'',$options); - } - } + $permiss = []; - $defcommpolicy = $limits['post_comments']; - - // avoid illegal offset errors - if(! array_key_exists('permissions',$x)) - $x['permissions'] = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ]; + $perm_opts = [ + [ t('Restricted - from connections only'), PERMS_SPECIFIC ], + [ t('Semi-public - from anybody that can be identified'), PERMS_AUTHED ], + [ t('Public - from anybody on the internet'), PERMS_PUBLIC ] + ]; - $jotplugins = ''; - call_hooks('jot_tool', $jotplugins); + $limits = PermissionLimits::Get(local_channel()); + $anon_comments = get_config('system', 'anonymous_comments'); - $jotcoll = jot_collections($c,((array_key_exists('collections',$x)) ? $x['collections'] : [])); - if(! $jotcoll) { - $jotcoll = EMPTY_STR; - } + foreach ($global_perms as $k => $perm) { + $options = []; + $can_be_public = ((strstr($k, 'view') || ($k === 'post_comments' && $anon_comments)) ? true : false); + foreach ($perm_opts as $opt) { + if ($opt[1] == PERMS_PUBLIC && (! $can_be_public)) { + continue; + } + $options[$opt[1]] = $opt[0]; + } + if ($k === 'post_comments') { + $comment_perms = [ $k, t('Accept delivery of comments and likes on this post from'), $limits[$k],'',$options ]; + } else { + $permiss[] = array($k,$perm,$limits[$k],'',$options); + } + } - $jotnets = EMPTY_STR; - if(x($x,'jotnets')) { - call_hooks('jot_networks', $jotnets); - } + $defcommpolicy = $limits['post_comments']; - $permanent_draft = ((intval($x['profile_uid']) && intval($x['profile_uid']) === local_channel() && Apps::system_app_installed($x['profile_uid'],'Drafts')) ? ('Save draft') : EMPTY_STR); + // avoid illegal offset errors + if (! array_key_exists('permissions', $x)) { + $x['permissions'] = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ]; + } - $sharebutton = (x($x,'button') ? $x['button'] : t('Share')); - $placeholdtext = (x($x,'content_label') ? $x['content_label'] : $sharebutton); + $jotplugins = ''; + call_hooks('jot_tool', $jotplugins); - $o .= replace_macros($tpl, array( - '$return_path' => ((x($x, 'return_path')) ? $x['return_path'] : App::$query_string), - '$action' => z_root() . '/item', - '$share' => $sharebutton, - '$placeholdtext' => $placeholdtext, - '$webpage' => $webpage, - '$placeholdpagetitle' => ((x($x,'ptlabel')) ? $x['ptlabel'] : t('Page link name')), - '$pagetitle' => (x($x,'pagetitle') ? $x['pagetitle'] : ''), - '$id_select' => $id_select, - '$id_seltext' => t('Post as'), - '$writefiles' => $writefiles, - '$text_style' => t('Text styles'), - '$bold' => t('Bold'), - '$italic' => t('Italic'), - '$underline' => t('Underline'), - '$quote' => t('Quote'), - '$code' => t('Code'), - '$attach' => t('Attach/Upload file'), - '$weblink' => $weblink, - '$linkurl' => t('Please enter a link location (URL)'), - '$weblink_style' => [ t('Insert link only'), t('Embed content if possible') ], - '$embedPhotos' => $embedPhotos, - '$embedPhotosModalTitle' => t('Embed an image from your albums'), - '$embedPhotosModalCancel' => t('Cancel'), - '$embedPhotosModalOK' => t('OK'), - '$setloc' => $setloc, - '$poll' => t('Toggle poll'), - '$poll_option_label' => t('Option'), - '$poll_add_option_label' => t('Add option'), - '$poll_expire_unit_label' => [t('Minutes'), t('Hours'), t('Days')], - '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers"), '', '', [t('No'), t('Yes')]], - '$feature_voting' => $feature_voting, - '$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0), - '$nocommenttitle' => t('Disable comments'), - '$nocommenttitlesub' => t('Toggle comments'), - '$comments_allowed' => [ 'comments_allowed', t('Allow comments on this post'), ((array_key_exists('item',$x)) ? 1 - $x['item']['item_nocomment'] : 1), '', [ t('No'), t('Yes')]], - - '$commentstate' => ((array_key_exists('item',$x)) ? 1 - $x['item']['item_nocomment'] : 1), - '$feature_comment_control' => $feature_comment_control, - '$commctrl' => t('Comment Control'), - '$comments_closed' => ((isset($x['item']) && isset($x['item']['comments_closed']) && $x['item']['comments_closed']) ? $x['item']['comments_closed'] : ''), - '$commclosedate' => t('Optional: disable comments after (date)'), - '$comment_perms' => $comment_perms, - '$defcommpolicy' => $defcommpolicy, - '$defcommuntil' => $defcommuntil, - '$clearloc' => $clearloc, - '$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''), - '$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')), - '$catsenabled' => $catsenabled, - '$category' => ((x($x, 'category')) ? $x['category'] : ''), - '$placeholdercategory' => t('Categories (optional, comma-separated list)'), - '$permset' => t('Permission settings'), - '$ptyp' => ((x($x, 'ptyp')) ? $x['ptyp'] : ''), - '$content' => ((x($x,'body')) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8') : ''), - '$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''), - '$post_id' => ((x($x, 'post_id')) ? $x['post_id'] : ''), - '$defloc' => $x['default_location'], - '$visitor' => $x['visitor'], - '$lockstate' => $x['lockstate'], - '$acl' => $x['acl'], - '$allow_cid' => acl2json($x['permissions']['allow_cid']), - '$allow_gid' => acl2json($x['permissions']['allow_gid']), - '$deny_cid' => acl2json($x['permissions']['deny_cid']), - '$deny_gid' => acl2json($x['permissions']['deny_gid']), - '$mimeselect' => $mimeselect, - '$layoutselect' => $layoutselect, - '$showacl' => ((array_key_exists('showacl', $x)) ? $x['showacl'] : true), - '$bang' => $x['bang'], - '$profile_uid' => $x['profile_uid'], - '$preview' => $preview, - '$source' => ((x($x, 'source')) ? $x['source'] : ''), - '$jotplugins' => $jotplugins, - '$jotcoll' => $jotcoll, - '$jotnets' => $jotnets, - '$jotnets_label' => t('Other networks and post services'), - '$jotcoll_label' => t('Collections'), - '$defexpire' => $defexpire, - '$feature_expire' => $feature_expire, - '$expires' => t('Set expiration date'), - '$save' => $permanent_draft, - '$is_draft' => ((array_key_exists('is_draft',$x) && intval($x['is_draft'])) ? true : false), - '$defpublish' => $defpublish, - '$feature_future' => $feature_future, - '$future_txt' => t('Set publish date'), - '$feature_markup' => $feature_markup, - '$feature_encrypt' => ((Apps::system_app_installed($x['profile_uid'],'Secrets')) ? true : false), - '$encrypt' => t('Encrypt text'), - '$cipher' => $cipher, - '$expiryModalOK' => t('OK'), - '$expiryModalCANCEL' => t('Cancel'), - '$commModalOK' => t('OK'), - '$commModalCANCEL' => t('Cancel'), - '$linkModalOK' => t('OK'), - '$linkModalCANCEL' => t('Cancel'), - '$close' => t('Close'), - '$expanded' => ((x($x, 'expanded')) ? $x['expanded'] : false), - '$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false), - '$parent' => ((array_key_exists('parent',$x) && $x['parent']) ? $x['parent'] : 0), - '$summaryenabled' => $summaryenabled, - '$summary' => ((x($x, 'summary')) ? htmlspecialchars($x['summary'], ENT_COMPAT,'UTF-8') : ''), - '$placeholdsummary' => t('Summary'), - '$discombed' => t('Load remote media players'), - '$discombed2' => t('This may subject viewers of this post to behaviour tracking'), - '$embedchecked' => ((get_pconfig($x['profile_uid'],'system','linkinfo_embed',true)) ? ' checked ' : ''), - '$disczot' => t('Find shareable objects (Zot)'), - '$reset' => $reset - )); + $jotcoll = jot_collections($c, ((array_key_exists('collections', $x)) ? $x['collections'] : [])); + if (! $jotcoll) { + $jotcoll = EMPTY_STR; + } - if ($popup === true) { - $o = ''; - } + $jotnets = EMPTY_STR; + if (x($x, 'jotnets')) { + call_hooks('jot_networks', $jotnets); + } - return $o; + $permanent_draft = ((intval($x['profile_uid']) && intval($x['profile_uid']) === local_channel() && Apps::system_app_installed($x['profile_uid'], 'Drafts')) ? ('Save draft') : EMPTY_STR); + + $sharebutton = (x($x, 'button') ? $x['button'] : t('Share')); + $placeholdtext = (x($x, 'content_label') ? $x['content_label'] : $sharebutton); + + $o .= replace_macros($tpl, array( + '$return_path' => ((x($x, 'return_path')) ? $x['return_path'] : App::$query_string), + '$action' => z_root() . '/item', + '$share' => $sharebutton, + '$placeholdtext' => $placeholdtext, + '$webpage' => $webpage, + '$placeholdpagetitle' => ((x($x, 'ptlabel')) ? $x['ptlabel'] : t('Page link name')), + '$pagetitle' => (x($x, 'pagetitle') ? $x['pagetitle'] : ''), + '$id_select' => $id_select, + '$id_seltext' => t('Post as'), + '$writefiles' => $writefiles, + '$text_style' => t('Text styles'), + '$bold' => t('Bold'), + '$italic' => t('Italic'), + '$underline' => t('Underline'), + '$quote' => t('Quote'), + '$code' => t('Code'), + '$attach' => t('Attach/Upload file'), + '$weblink' => $weblink, + '$linkurl' => t('Please enter a link location (URL)'), + '$weblink_style' => [ t('Insert link only'), t('Embed content if possible') ], + '$embedPhotos' => $embedPhotos, + '$embedPhotosModalTitle' => t('Embed an image from your albums'), + '$embedPhotosModalCancel' => t('Cancel'), + '$embedPhotosModalOK' => t('OK'), + '$setloc' => $setloc, + '$poll' => t('Toggle poll'), + '$poll_option_label' => t('Option'), + '$poll_add_option_label' => t('Add option'), + '$poll_expire_unit_label' => [t('Minutes'), t('Hours'), t('Days')], + '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers"), '', '', [t('No'), t('Yes')]], + '$feature_voting' => $feature_voting, + '$consensus' => ((array_key_exists('item', $x)) ? $x['item']['item_consensus'] : 0), + '$nocommenttitle' => t('Disable comments'), + '$nocommenttitlesub' => t('Toggle comments'), + '$comments_allowed' => [ 'comments_allowed', t('Allow comments on this post'), ((array_key_exists('item', $x)) ? 1 - $x['item']['item_nocomment'] : 1), '', [ t('No'), t('Yes')]], + + '$commentstate' => ((array_key_exists('item', $x)) ? 1 - $x['item']['item_nocomment'] : 1), + '$feature_comment_control' => $feature_comment_control, + '$commctrl' => t('Comment Control'), + '$comments_closed' => ((isset($x['item']) && isset($x['item']['comments_closed']) && $x['item']['comments_closed']) ? $x['item']['comments_closed'] : ''), + '$commclosedate' => t('Optional: disable comments after (date)'), + '$comment_perms' => $comment_perms, + '$defcommpolicy' => $defcommpolicy, + '$defcommuntil' => $defcommuntil, + '$clearloc' => $clearloc, + '$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8') : ''), + '$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')), + '$catsenabled' => $catsenabled, + '$category' => ((x($x, 'category')) ? $x['category'] : ''), + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), + '$permset' => t('Permission settings'), + '$ptyp' => ((x($x, 'ptyp')) ? $x['ptyp'] : ''), + '$content' => ((x($x, 'body')) ? htmlspecialchars($x['body'], ENT_COMPAT, 'UTF-8') : ''), + '$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''), + '$post_id' => ((x($x, 'post_id')) ? $x['post_id'] : ''), + '$defloc' => $x['default_location'], + '$visitor' => $x['visitor'], + '$lockstate' => $x['lockstate'], + '$acl' => $x['acl'], + '$allow_cid' => acl2json($x['permissions']['allow_cid']), + '$allow_gid' => acl2json($x['permissions']['allow_gid']), + '$deny_cid' => acl2json($x['permissions']['deny_cid']), + '$deny_gid' => acl2json($x['permissions']['deny_gid']), + '$mimeselect' => $mimeselect, + '$layoutselect' => $layoutselect, + '$showacl' => ((array_key_exists('showacl', $x)) ? $x['showacl'] : true), + '$bang' => $x['bang'], + '$profile_uid' => $x['profile_uid'], + '$preview' => $preview, + '$source' => ((x($x, 'source')) ? $x['source'] : ''), + '$jotplugins' => $jotplugins, + '$jotcoll' => $jotcoll, + '$jotnets' => $jotnets, + '$jotnets_label' => t('Other networks and post services'), + '$jotcoll_label' => t('Collections'), + '$defexpire' => $defexpire, + '$feature_expire' => $feature_expire, + '$expires' => t('Set expiration date'), + '$save' => $permanent_draft, + '$is_draft' => ((array_key_exists('is_draft', $x) && intval($x['is_draft'])) ? true : false), + '$defpublish' => $defpublish, + '$feature_future' => $feature_future, + '$future_txt' => t('Set publish date'), + '$feature_markup' => $feature_markup, + '$feature_encrypt' => ((Apps::system_app_installed($x['profile_uid'], 'Secrets')) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + '$expiryModalOK' => t('OK'), + '$expiryModalCANCEL' => t('Cancel'), + '$commModalOK' => t('OK'), + '$commModalCANCEL' => t('Cancel'), + '$linkModalOK' => t('OK'), + '$linkModalCANCEL' => t('Cancel'), + '$close' => t('Close'), + '$expanded' => ((x($x, 'expanded')) ? $x['expanded'] : false), + '$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false), + '$parent' => ((array_key_exists('parent', $x) && $x['parent']) ? $x['parent'] : 0), + '$summaryenabled' => $summaryenabled, + '$summary' => ((x($x, 'summary')) ? htmlspecialchars($x['summary'], ENT_COMPAT, 'UTF-8') : ''), + '$placeholdsummary' => t('Summary'), + '$discombed' => t('Load remote media players'), + '$discombed2' => t('This may subject viewers of this post to behaviour tracking'), + '$embedchecked' => ((get_pconfig($x['profile_uid'], 'system', 'linkinfo_embed', true)) ? ' checked ' : ''), + '$disczot' => t('Find shareable objects (Zot)'), + '$reset' => $reset + )); + + if ($popup === true) { + $o = ''; + } + + return $o; } -function jot_collections($channel,$collections) { +function jot_collections($channel, $collections) +{ - $output = EMPTY_STR; + $output = EMPTY_STR; - $r = q("select channel_address, channel_name from channel where channel_parent = '%s' and channel_removed = 0 order by channel_name asc", - dbesc($channel['channel_hash']) - ); - if(! $r) { - return $output; - } + $r = q( + "select channel_address, channel_name from channel where channel_parent = '%s' and channel_removed = 0 order by channel_name asc", + dbesc($channel['channel_hash']) + ); + if (! $r) { + return $output; + } - $size = ((count($r) < 4) ? count($r) : 4); + $size = ((count($r) < 4) ? count($r) : 4); - $output .= t('Post to Collections'); - $output .= ''; - - return $output; + $output .= t('Post to Collections'); + $output .= ''; + return $output; } -function get_item_children($arr, $parent) { +function get_item_children($arr, $parent) +{ - $children = []; - if (! $arr) { - return $children; - } + $children = []; + if (! $arr) { + return $children; + } - $thread_allow = get_config('system','thread_allow',true); - $thread_max = intval(get_config('system','thread_maxlevel',20)); - - foreach ($arr as $item) { - if (intval($item['id']) !== intval($item['parent'])) { - if ($thread_allow) { + $thread_allow = get_config('system', 'thread_allow', true); + $thread_max = intval(get_config('system', 'thread_maxlevel', 20)); - $thr_parent = $item['thr_parent']; + foreach ($arr as $item) { + if (intval($item['id']) !== intval($item['parent'])) { + if ($thread_allow) { + $thr_parent = $item['thr_parent']; - // Fallback to parent_mid if thr_parent is not set - if ($thr_parent === EMPTY_STR) { - $thr_parent = $item['parent_mid']; - } - - if ($thr_parent === $parent['mid']) { - $my_children = get_item_children($arr, $item); - if ($item['item_level'] > $thread_max) { - // Like and Dislike activities are allowed as children of the last supported level. - // After that they are ignored. - // Any other children deeper than $thread_max are flattened. - if(in_array($item['verb'], [ 'Like','Dislike' ])) { - if ($item['item_level'] > ($thread_max + 1)) { - continue; - } - } - $children = (($my_children) ? array_merge($children,$my_children) : $children); - } - else { - $item['children'] = $my_children; - } - $children[] = $item; - } - } - elseif (intval($item['parent']) === intval($parent['id'])) { - // threads are disabled. Anything that is in this conversation gets added to children. - $children[] = $item; - } - } - } - return $children; + // Fallback to parent_mid if thr_parent is not set + if ($thr_parent === EMPTY_STR) { + $thr_parent = $item['parent_mid']; + } + + if ($thr_parent === $parent['mid']) { + $my_children = get_item_children($arr, $item); + if ($item['item_level'] > $thread_max) { + // Like and Dislike activities are allowed as children of the last supported level. + // After that they are ignored. + // Any other children deeper than $thread_max are flattened. + if (in_array($item['verb'], [ 'Like','Dislike' ])) { + if ($item['item_level'] > ($thread_max + 1)) { + continue; + } + } + $children = (($my_children) ? array_merge($children, $my_children) : $children); + } else { + $item['children'] = $my_children; + } + $children[] = $item; + } + } elseif (intval($item['parent']) === intval($parent['id'])) { + // threads are disabled. Anything that is in this conversation gets added to children. + $children[] = $item; + } + } + } + return $children; } -function sort_item_children($items) { - $result = $items; - usort($result,'sort_thr_created_rev'); - foreach($result as $k => $i) { - if($result[$k]['children']) { - $result[$k]['children'] = sort_item_children($result[$k]['children']); - } - } - return $result; +function sort_item_children($items) +{ + $result = $items; + usort($result, 'sort_thr_created_rev'); + foreach ($result as $k => $i) { + if ($result[$k]['children']) { + $result[$k]['children'] = sort_item_children($result[$k]['children']); + } + } + return $result; } -function add_children_to_list($children, &$arr) { - foreach ($children as $y) { - $arr[] = $y; - if ($y['children']) { - add_children_to_list($y['children'], $arr); - } - } +function add_children_to_list($children, &$arr) +{ + foreach ($children as $y) { + $arr[] = $y; + if ($y['children']) { + add_children_to_list($y['children'], $arr); + } + } } /* * separate the incoming array into conversations, with the original post at index 0, * and the comments following in reverse date order (newest first). Likes and other hidden activities go to the end. * This lets us choose the most recent comments in each conversation (regardless of thread depth) - * to open by default - while collapsing everything else. + * to open by default - while collapsing everything else. */ -function flatten_and_order($arr) { - $narr = []; - $ret = []; - - foreach ($arr as $a) { - $narr[$a['parent']][] = $a; - } - - foreach ($narr as $n) { - usort($n,'sort_flatten'); - for($x = 0; $x < count($n); $x ++) { - $n[$x]['comment_order'] = $x; - $ret[] = $n[$x]; - } - } +function flatten_and_order($arr) +{ + $narr = []; + $ret = []; - return $ret; + foreach ($arr as $a) { + $narr[$a['parent']][] = $a; + } + + foreach ($narr as $n) { + usort($n, 'sort_flatten'); + for ($x = 0; $x < count($n); $x++) { + $n[$x]['comment_order'] = $x; + $ret[] = $n[$x]; + } + } + + return $ret; } -function conv_sort($arr, $order) { +function conv_sort($arr, $order) +{ - $parents = []; - $ret = []; - - if (! (is_array($arr) && count($arr))) { - return $ret; - } + $parents = []; + $ret = []; - $narr = []; - - foreach ($arr as $item) { + if (! (is_array($arr) && count($arr))) { + return $ret; + } - // perform view filtering if viewer is logged in locally - // This allows blocking and message filters to work on public stream items - // or other channel streams on this site which are not owned by the viewer - - if (local_channel()) { - - if (LibBlock::fetch_by_entity(local_channel(),$item['author_xchan']) || LibBlock::fetch_by_entity(local_channel(),$item['owner_xchan'])) { - continue; - } + $narr = []; - $message_filter_abook = []; - if (App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) { - $message_filter_abook[] = App::$contacts[$item['author_xchan']]; - } - if (App::$contacts && array_key_exists($item['owner_xchan'], App::$contacts)) { - $message_filter_abook[] = App::$contacts[$item['owner_xchan']]; - } + foreach ($arr as $item) { + // perform view filtering if viewer is logged in locally + // This allows blocking and message filters to work on public stream items + // or other channel streams on this site which are not owned by the viewer - if (! post_is_importable(local_channel(), $item, $message_filter_abook ? $message_filter_abook : false)) { - continue; - } + if (local_channel()) { + if (LibBlock::fetch_by_entity(local_channel(), $item['author_xchan']) || LibBlock::fetch_by_entity(local_channel(), $item['owner_xchan'])) { + continue; + } + + $message_filter_abook = []; + if (App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) { + $message_filter_abook[] = App::$contacts[$item['author_xchan']]; + } + if (App::$contacts && array_key_exists($item['owner_xchan'], App::$contacts)) { + $message_filter_abook[] = App::$contacts[$item['owner_xchan']]; + } + + if (! post_is_importable(local_channel(), $item, $message_filter_abook ? $message_filter_abook : false)) { + continue; + } - $matches = null; - $found = false; - - $cnt = preg_match_all("/\[share(.*?)portable_id='(.*?)'(.*?)\]/ism", $item['body'], $matches, PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $match) { - if (LibBlock::fetch_by_entity(local_channel(),$match[2])) { - $found = true; - } - } - } + $matches = null; + $found = false; - if ($found) { - continue; - } + $cnt = preg_match_all("/\[share(.*?)portable_id='(.*?)'(.*?)\]/ism", $item['body'], $matches, PREG_SET_ORDER); + if ($cnt) { + foreach ($matches as $match) { + if (LibBlock::fetch_by_entity(local_channel(), $match[2])) { + $found = true; + } + } + } + + if ($found) { + continue; + } - $matches = null; - $found = false; - $cnt = preg_match_all("/\[share(.*?)profile='(.*?)'(.*?)\]/ism", $item['body'], $matches, PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $match) { - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s'", - dbesc($match[2]) - ); - if ($r) { - if (LibBlock::fetch_by_entity(local_channel(),$r[0]['hubloc_hash'])) { - $found = true; - } - } - } - } + $matches = null; + $found = false; + $cnt = preg_match_all("/\[share(.*?)profile='(.*?)'(.*?)\]/ism", $item['body'], $matches, PREG_SET_ORDER); + if ($cnt) { + foreach ($matches as $match) { + $r = q( + "select hubloc_hash from hubloc where hubloc_id_url = '%s'", + dbesc($match[2]) + ); + if ($r) { + if (LibBlock::fetch_by_entity(local_channel(), $r[0]['hubloc_hash'])) { + $found = true; + } + } + } + } - if ($found) { - continue; - } + if ($found) { + continue; + } + } - } - - $narr[] = $item; - } + $narr[] = $item; + } - $data = [ 'items' => $narr, 'order' => $order ]; + $data = [ 'items' => $narr, 'order' => $order ]; - call_hooks('conv_sort', $data); + call_hooks('conv_sort', $data); - $arr = $data['items']; + $arr = $data['items']; - if (! (is_array($arr) && count($arr))) { - return $ret; - } + if (! (is_array($arr) && count($arr))) { + return $ret; + } - $arr = flatten_and_order($arr); + $arr = flatten_and_order($arr); - foreach ($arr as $x) { - if (intval($x['id']) === intval($x['parent'])) { - $parents[] = $x; - } - } + foreach ($arr as $x) { + if (intval($x['id']) === intval($x['parent'])) { + $parents[] = $x; + } + } - if (stristr($order,'created')) { - usort($parents,'sort_thr_created'); - } - elseif (stristr($order,'commented')) { - usort($parents,'sort_thr_commented'); - } - elseif (stristr($order,'updated')) { - usort($parents,'sort_thr_updated'); - } - elseif (stristr($order,'ascending')) { - usort($parents,'sort_thr_created_rev'); - } + if (stristr($order, 'created')) { + usort($parents, 'sort_thr_created'); + } elseif (stristr($order, 'commented')) { + usort($parents, 'sort_thr_commented'); + } elseif (stristr($order, 'updated')) { + usort($parents, 'sort_thr_updated'); + } elseif (stristr($order, 'ascending')) { + usort($parents, 'sort_thr_created_rev'); + } - if ($parents) { - foreach ($parents as $i => $_x) { - $parents[$i]['children'] = get_item_children($arr, $_x); - } - - foreach ($parents as $k => $v) { - if ($parents[$k]['children']) { - $parents[$k]['children'] = sort_item_children($parents[$k]['children']); - } - } + if ($parents) { + foreach ($parents as $i => $_x) { + $parents[$i]['children'] = get_item_children($arr, $_x); + } - } + foreach ($parents as $k => $v) { + if ($parents[$k]['children']) { + $parents[$k]['children'] = sort_item_children($parents[$k]['children']); + } + } + } - if ($parents) { - foreach ($parents as $x) { - $ret[] = $x; - if ($x['children']) { - add_children_to_list($x['children'], $ret); - } - } - } + if ($parents) { + foreach ($parents as $x) { + $ret[] = $x; + if ($x['children']) { + add_children_to_list($x['children'], $ret); + } + } + } - return $ret; + return $ret; } @@ -1756,122 +1768,134 @@ function conv_sort($arr, $order) { // We want the original post at index 0 and all the comments (regardless of thread depth) ordered newest to oldest. // likes and other invisible activities go to the end of the array beyond the oldest comment. -function sort_flatten($a,$b) { +function sort_flatten($a, $b) +{ - if ($a['parent'] === $a['id']) { - return -1; - } - if ($b['parent'] === $b['id']) { - return 1; - } + if ($a['parent'] === $a['id']) { + return -1; + } + if ($b['parent'] === $b['id']) { + return 1; + } - if (! visible_activity($a)) { - return 1; - } - if (! visible_activity($b)) { - return -1; - } + if (! visible_activity($a)) { + return 1; + } + if (! visible_activity($b)) { + return -1; + } - return strcmp($b['created'],$a['created']); + return strcmp($b['created'], $a['created']); } -function sort_thr_created($a,$b) { - return strcmp($b['created'],$a['created']); +function sort_thr_created($a, $b) +{ + return strcmp($b['created'], $a['created']); } -function sort_thr_created_rev($a,$b) { - return strcmp($a['created'],$b['created']); +function sort_thr_created_rev($a, $b) +{ + return strcmp($a['created'], $b['created']); } -function sort_thr_commented($a,$b) { - return strcmp($b['commented'],$a['commented']); +function sort_thr_commented($a, $b) +{ + return strcmp($b['commented'], $a['commented']); } -function sort_thr_updated($a,$b) { - $indexa = (($a['changed'] > $a['edited']) ? $a['changed'] : $a['edited']); - $indexb = (($b['changed'] > $b['edited']) ? $b['changed'] : $b['edited']); - return strcmp($indexb,$indexa); +function sort_thr_updated($a, $b) +{ + $indexa = (($a['changed'] > $a['edited']) ? $a['changed'] : $a['edited']); + $indexb = (($b['changed'] > $b['edited']) ? $b['changed'] : $b['edited']); + return strcmp($indexb, $indexa); } -function find_thread_parent_index($arr,$x) { - foreach($arr as $k => $v) - if($v['id'] == $x['parent']) - return $k; +function find_thread_parent_index($arr, $x) +{ + foreach ($arr as $k => $v) { + if ($v['id'] == $x['parent']) { + return $k; + } + } - return false; + return false; } -function format_location($item) { +function format_location($item) +{ - if(strpos($item['location'],'#') === 0) { - $location = substr($item['location'],1); - $location = ((strpos($location,'[') !== false) ? zidify_links(bbcode($location)) : $location); - } - else { - $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); - call_hooks('render_location',$locate); - $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_default($locate)); - } - return $location; + if (strpos($item['location'], '#') === 0) { + $location = substr($item['location'], 1); + $location = ((strpos($location, '[') !== false) ? zidify_links(bbcode($location)) : $location); + } else { + $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); + call_hooks('render_location', $locate); + $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_default($locate)); + } + return $location; } -function render_location_default($item) { +function render_location_default($item) +{ - $location = $item['location']; - $coord = $item['coord']; + $location = $item['location']; + $coord = $item['coord']; - if($coord) { - if($location) - $location .= ' (' . $coord . ')'; - else - $location = '' . $coord . ''; - } + if ($coord) { + if ($location) { + $location .= ' (' . $coord . ')'; + } else { + $location = '' . $coord . ''; + } + } - return $location; + return $location; } -function prepare_page($item) { +function prepare_page($item) +{ - $naked = 1; -// $naked = ((get_pconfig($item['uid'],'system','nakedpage')) ? 1 : 0); - $observer = App::get_observer(); - //240 chars is the longest we can have before we start hitting problems with suhosin sites - $preview = substr(urlencode($item['body']), 0, 240); - $link = z_root() . '/' . App::$cmd; - if(array_key_exists('webpage',App::$layout) && array_key_exists('authored',App::$layout['webpage'])) { - if(App::$layout['webpage']['authored'] === 'none') - $naked = 1; - // ... other possible options - } + $naked = 1; +// $naked = ((get_pconfig($item['uid'],'system','nakedpage')) ? 1 : 0); + $observer = App::get_observer(); + //240 chars is the longest we can have before we start hitting problems with suhosin sites + $preview = substr(urlencode($item['body']), 0, 240); + $link = z_root() . '/' . App::$cmd; + if (array_key_exists('webpage', App::$layout) && array_key_exists('authored', App::$layout['webpage'])) { + if (App::$layout['webpage']['authored'] === 'none') { + $naked = 1; + } + // ... other possible options + } - // prepare_body calls unobscure() as a side effect. Do it here so that - // the template will get passed an unobscured title. + // prepare_body calls unobscure() as a side effect. Do it here so that + // the template will get passed an unobscured title. - $body = prepare_body($item, true, [ 'newwin' => false ]); - if(App::$page['template'] == 'none') { - $tpl = 'page_display_empty.tpl'; + $body = prepare_body($item, true, [ 'newwin' => false ]); + if (App::$page['template'] == 'none') { + $tpl = 'page_display_empty.tpl'; - return replace_macros(get_markup_template($tpl), array( - '$body' => $body['html'] - )); - - } - - $tpl = get_pconfig($item['uid'], 'system', 'pagetemplate'); - if (! $tpl) - $tpl = 'page_display.tpl'; + return replace_macros(get_markup_template($tpl), array( + '$body' => $body['html'] + )); + } - return replace_macros(get_markup_template($tpl), array( - '$author' => (($naked) ? '' : $item['author']['xchan_name']), - '$auth_url' => (($naked) ? '' : zid($item['author']['xchan_url'])), - '$date' => (($naked) ? '' : datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'Y-m-d H:i')), - '$title' => zidify_links(smilies(bbcode($item['title']))), - '$body' => $body['html'], - '$preview' => $preview, - '$link' => $link, - )); + $tpl = get_pconfig($item['uid'], 'system', 'pagetemplate'); + if (! $tpl) { + $tpl = 'page_display.tpl'; + } + + return replace_macros(get_markup_template($tpl), array( + '$author' => (($naked) ? '' : $item['author']['xchan_name']), + '$auth_url' => (($naked) ? '' : zid($item['author']['xchan_url'])), + '$date' => (($naked) ? '' : datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'Y-m-d H:i')), + '$title' => zidify_links(smilies(bbcode($item['title']))), + '$body' => $body['html'], + '$preview' => $preview, + '$link' => $link, + )); } @@ -1883,263 +1907,270 @@ function prepare_page($item) { * @param string $nickname default null * @return void|string */ -function profile_tabs($a, $is_owner = false, $nickname = null){ +function profile_tabs($a, $is_owner = false, $nickname = null) +{ - // Don't provide any profile tabs if we're running as the sys channel + // Don't provide any profile tabs if we're running as the sys channel - if (App::$is_sys) - return; + if (App::$is_sys) { + return; + } - if (get_pconfig($uid, 'system', 'noprofiletabs')) - return; + if (get_pconfig($uid, 'system', 'noprofiletabs')) { + return; + } - $channel = App::get_channel(); + $channel = App::get_channel(); - if (is_null($nickname)) - $nickname = $channel['channel_address']; + if (is_null($nickname)) { + $nickname = $channel['channel_address']; + } - $uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel()); - $account_id = ((App::$profile['profile_uid']) ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']); + $uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel()); + $account_id = ((App::$profile['profile_uid']) ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']); - if ($uid == local_channel()) - return; + if ($uid == local_channel()) { + return; + } - if($uid == local_channel()) { - $cal_link = ''; - } - else { - $cal_link = '/cal/' . $nickname; - } + if ($uid == local_channel()) { + $cal_link = ''; + } else { + $cal_link = '/cal/' . $nickname; + } - require_once('include/security.php'); - $sql_options = item_permissions_sql($uid); + require_once('include/security.php'); + $sql_options = item_permissions_sql($uid); - $r = q("select item.* from item left join iconfig on item.id = iconfig.iid + $r = q( + "select item.* from item left join iconfig on item.id = iconfig.iid where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0 and item.item_deleted = 0 and ( iconfig.k = 'WEBPAGE' and item_type = %d ) $sql_options limit 1", - intval($uid), - dbesc('home'), - intval(ITEM_TYPE_WEBPAGE) - ); + intval($uid), + dbesc('home'), + intval(ITEM_TYPE_WEBPAGE) + ); - $has_webpages = (($r) ? true : false); + $has_webpages = (($r) ? true : false); - if (x($_GET, 'tab')) - $tab = notags(trim($_GET['tab'])); + if (x($_GET, 'tab')) { + $tab = notags(trim($_GET['tab'])); + } - $url = z_root() . '/channel/' . $nickname; - $pr = z_root() . '/profile/' . $nickname; + $url = z_root() . '/channel/' . $nickname; + $pr = z_root() . '/profile/' . $nickname; - $tabs = array( - array( - 'label' => t('Channel'), - 'url' => $url, - 'sel' => ((argv(0) == 'channel') ? 'active' : ''), - 'title' => t('Status Messages and Posts'), - 'id' => 'status-tab', - 'icon' => 'home' - ), - ); + $tabs = array( + array( + 'label' => t('Channel'), + 'url' => $url, + 'sel' => ((argv(0) == 'channel') ? 'active' : ''), + 'title' => t('Status Messages and Posts'), + 'id' => 'status-tab', + 'icon' => 'home' + ), + ); - $p = get_all_perms($uid,get_observer_hash()); + $p = get_all_perms($uid, get_observer_hash()); - if ($p['view_profile']) { - $tabs[] = array( - 'label' => t('About'), - 'url' => $pr, - 'sel' => ((argv(0) == 'profile') ? 'active' : ''), - 'title' => t('Profile Details'), - 'id' => 'profile-tab', - 'icon' => 'user' - ); - } - if ($p['view_storage']) { - $tabs[] = array( - 'label' => t('Photos'), - 'url' => z_root() . '/photos/' . $nickname, - 'sel' => ((argv(0) == 'photos') ? 'active' : ''), - 'title' => t('Photo Albums'), - 'id' => 'photo-tab', - 'icon' => 'photo' - ); - $tabs[] = array( - 'label' => t('Files'), - 'url' => z_root() . '/cloud/' . $nickname, - 'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''), - 'title' => t('Files and Storage'), - 'id' => 'files-tab', - 'icon' => 'folder-open' - ); - } + if ($p['view_profile']) { + $tabs[] = array( + 'label' => t('About'), + 'url' => $pr, + 'sel' => ((argv(0) == 'profile') ? 'active' : ''), + 'title' => t('Profile Details'), + 'id' => 'profile-tab', + 'icon' => 'user' + ); + } + if ($p['view_storage']) { + $tabs[] = array( + 'label' => t('Photos'), + 'url' => z_root() . '/photos/' . $nickname, + 'sel' => ((argv(0) == 'photos') ? 'active' : ''), + 'title' => t('Photo Albums'), + 'id' => 'photo-tab', + 'icon' => 'photo' + ); + $tabs[] = array( + 'label' => t('Files'), + 'url' => z_root() . '/cloud/' . $nickname, + 'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''), + 'title' => t('Files and Storage'), + 'id' => 'files-tab', + 'icon' => 'folder-open' + ); + } - if($p['view_stream'] && $cal_link) { - $tabs[] = array( - 'label' => t('Events'), - 'url' => z_root() . $cal_link, - 'sel' => ((argv(0) == 'cal' || argv(0) == 'events') ? 'active' : ''), - 'title' => t('Events'), - 'id' => 'event-tab', - 'icon' => 'calendar' - ); - } + if ($p['view_stream'] && $cal_link) { + $tabs[] = array( + 'label' => t('Events'), + 'url' => z_root() . $cal_link, + 'sel' => ((argv(0) == 'cal' || argv(0) == 'events') ? 'active' : ''), + 'title' => t('Events'), + 'id' => 'event-tab', + 'icon' => 'calendar' + ); + } - if ($p['chat'] && feature_enabled($uid,'ajaxchat')) { - $has_chats = Chatroom::list_count($uid); - if ($has_chats) { - $tabs[] = array( - 'label' => t('Chatrooms'), - 'url' => z_root() . '/chat/' . $nickname, - 'sel' => ((argv(0) == 'chat') ? 'active' : '' ), - 'title' => t('Chatrooms'), - 'id' => 'chat-tab', - 'icon' => 'comments-o' - ); - } - } + if ($p['chat'] && feature_enabled($uid, 'ajaxchat')) { + $has_chats = Chatroom::list_count($uid); + if ($has_chats) { + $tabs[] = array( + 'label' => t('Chatrooms'), + 'url' => z_root() . '/chat/' . $nickname, + 'sel' => ((argv(0) == 'chat') ? 'active' : '' ), + 'title' => t('Chatrooms'), + 'id' => 'chat-tab', + 'icon' => 'comments-o' + ); + } + } - require_once('include/menu.php'); - $has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK); + require_once('include/menu.php'); + $has_bookmarks = menu_list_count(local_channel(), '', MENU_BOOKMARK) + menu_list_count(local_channel(), '', MENU_SYSTEM | MENU_BOOKMARK); - if($is_owner && $has_bookmarks) { - $tabs[] = array( - 'label' => t('Bookmarks'), - 'url' => z_root() . '/bookmarks', - 'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''), - 'title' => t('Saved Bookmarks'), - 'id' => 'bookmarks-tab', - 'icon' => 'bookmark' - ); - } + if ($is_owner && $has_bookmarks) { + $tabs[] = array( + 'label' => t('Bookmarks'), + 'url' => z_root() . '/bookmarks', + 'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''), + 'title' => t('Saved Bookmarks'), + 'id' => 'bookmarks-tab', + 'icon' => 'bookmark' + ); + } - if(feature_enabled($uid,'cards')) { - $tabs[] = array( - 'label' => t('Cards'), - 'url' => z_root() . '/cards/' . $nickname, - 'sel' => ((argv(0) == 'cards') ? 'active' : ''), - 'title' => t('View Cards'), - 'id' => 'cards-tab', - 'icon' => 'list' - ); - } + if (feature_enabled($uid, 'cards')) { + $tabs[] = array( + 'label' => t('Cards'), + 'url' => z_root() . '/cards/' . $nickname, + 'sel' => ((argv(0) == 'cards') ? 'active' : ''), + 'title' => t('View Cards'), + 'id' => 'cards-tab', + 'icon' => 'list' + ); + } - if(feature_enabled($uid,'articles')) { - $tabs[] = array( - 'label' => t('articles'), - 'url' => z_root() . '/articles/' . $nickname, - 'sel' => ((argv(0) == 'articles') ? 'active' : ''), - 'title' => t('View Articles'), - 'id' => 'articles-tab', - 'icon' => 'file-text-o' - ); - } - - if($has_webpages && feature_enabled($uid,'webpages')) { - $tabs[] = array( - 'label' => t('Webpages'), - 'url' => z_root() . '/page/' . $nickname . '/home', - 'sel' => ((argv(0) == 'webpages') ? 'active' : ''), - 'title' => t('View Webpages'), - 'id' => 'webpages-tab', - 'icon' => 'newspaper-o' - ); - } + if (feature_enabled($uid, 'articles')) { + $tabs[] = array( + 'label' => t('articles'), + 'url' => z_root() . '/articles/' . $nickname, + 'sel' => ((argv(0) == 'articles') ? 'active' : ''), + 'title' => t('View Articles'), + 'id' => 'articles-tab', + 'icon' => 'file-text-o' + ); + } + + if ($has_webpages && feature_enabled($uid, 'webpages')) { + $tabs[] = array( + 'label' => t('Webpages'), + 'url' => z_root() . '/page/' . $nickname . '/home', + 'sel' => ((argv(0) == 'webpages') ? 'active' : ''), + 'title' => t('View Webpages'), + 'id' => 'webpages-tab', + 'icon' => 'newspaper-o' + ); + } - if ($p['view_wiki']) { - if(feature_enabled($uid,'wiki')) { - $tabs[] = array( - 'label' => t('Wikis'), - 'url' => z_root() . '/wiki/' . $nickname, - 'sel' => ((argv(0) == 'wiki') ? 'active' : ''), - 'title' => t('Wiki'), - 'id' => 'wiki-tab', - 'icon' => 'pencil-square-o' - ); - } - } + if ($p['view_wiki']) { + if (feature_enabled($uid, 'wiki')) { + $tabs[] = array( + 'label' => t('Wikis'), + 'url' => z_root() . '/wiki/' . $nickname, + 'sel' => ((argv(0) == 'wiki') ? 'active' : ''), + 'title' => t('Wiki'), + 'id' => 'wiki-tab', + 'icon' => 'pencil-square-o' + ); + } + } - $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); - call_hooks('profile_tabs', $arr); - - $tpl = get_markup_template('profile_tabs.tpl'); + $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); + call_hooks('profile_tabs', $arr); - return replace_macros($tpl, array( - '$tabs' => $arr['tabs'], - '$name' => App::$profile['channel_name'], - '$thumb' => App::$profile['thumb'] - )); + $tpl = get_markup_template('profile_tabs.tpl'); + + return replace_macros($tpl, array( + '$tabs' => $arr['tabs'], + '$name' => App::$profile['channel_name'], + '$thumb' => App::$profile['thumb'] + )); } -function get_responses($conv_responses,$response_verbs,$ob,$item) { +function get_responses($conv_responses, $response_verbs, $ob, $item) +{ - $ret = []; - foreach($response_verbs as $v) { - $ret[$v] = []; - $ret[$v]['count'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid']] : ''); - $ret[$v]['list'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid'] . '-l'] : ''); - $ret[$v]['button'] = get_response_button_text($v,$ret[$v]['count']); - $ret[$v]['title'] = $conv_responses[$v]['title']; - if($ret[$v]['count'] > MAX_LIKERS) { - $ret[$v]['modal'] = true; - } - } + $ret = []; + foreach ($response_verbs as $v) { + $ret[$v] = []; + $ret[$v]['count'] = ((x($conv_responses[$v], $item['mid'])) ? $conv_responses[$v][$item['mid']] : ''); + $ret[$v]['list'] = ((x($conv_responses[$v], $item['mid'])) ? $conv_responses[$v][$item['mid'] . '-l'] : ''); + $ret[$v]['button'] = get_response_button_text($v, $ret[$v]['count']); + $ret[$v]['title'] = $conv_responses[$v]['title']; + if ($ret[$v]['count'] > MAX_LIKERS) { + $ret[$v]['modal'] = true; + } + } - $count = 0; - foreach ($ret as $key) { - if ($key['count'] == true) - $count++; - } + $count = 0; + foreach ($ret as $key) { + if ($key['count'] == true) { + $count++; + } + } - $ret['count'] = $count; + $ret['count'] = $count; //logger('ret: ' . print_r($ret,true)); - return $ret; + return $ret; } -function get_response_button_text($v,$count) { - switch($v) { - case 'like': - if(get_config('system','show_like_counts',true)) { - return $count . ' ' . tt('Like','Likes',$count,'noun'); - } - else { - return t('Likes', 'noun'); - } - break; - case 'dislike': - if(get_config('system','show_like_counts',true)) { - return $count . ' ' . tt('Dislike','Dislikes',$count,'noun'); - } - else { - return t('Dislikes', 'noun'); - } - break; - case 'attendyes': - return $count . ' ' . tt('Attending','Attending',$count,'noun'); - break; - case 'attendno': - return $count . ' ' . tt('Not Attending','Not Attending',$count,'noun'); - break; - case 'attendmaybe': - return $count . ' ' . tt('Undecided','Undecided',$count,'noun'); - break; - case 'agree': - return $count . ' ' . tt('Agree','Agrees',$count,'noun'); - break; - case 'disagree': - return $count . ' ' . tt('Disagree','Disagrees',$count,'noun'); - break; - case 'abstain': - return $count . ' ' . tt('Abstain','Abstains',$count,'noun'); - break; - default: - return ''; - break; - } +function get_response_button_text($v, $count) +{ + switch ($v) { + case 'like': + if (get_config('system', 'show_like_counts', true)) { + return $count . ' ' . tt('Like', 'Likes', $count, 'noun'); + } else { + return t('Likes', 'noun'); + } + break; + case 'dislike': + if (get_config('system', 'show_like_counts', true)) { + return $count . ' ' . tt('Dislike', 'Dislikes', $count, 'noun'); + } else { + return t('Dislikes', 'noun'); + } + break; + case 'attendyes': + return $count . ' ' . tt('Attending', 'Attending', $count, 'noun'); + break; + case 'attendno': + return $count . ' ' . tt('Not Attending', 'Not Attending', $count, 'noun'); + break; + case 'attendmaybe': + return $count . ' ' . tt('Undecided', 'Undecided', $count, 'noun'); + break; + case 'agree': + return $count . ' ' . tt('Agree', 'Agrees', $count, 'noun'); + break; + case 'disagree': + return $count . ' ' . tt('Disagree', 'Disagrees', $count, 'noun'); + break; + case 'abstain': + return $count . ' ' . tt('Abstain', 'Abstains', $count, 'noun'); + break; + default: + return ''; + break; + } } diff --git a/include/datetime.php b/include/datetime.php index 934f7ec90..91c9703dd 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -1,4 +1,5 @@ 1) { - $continent = t($ex[0]); - if (count($ex) > 2) - $city = substr($value, strpos($value, '/')+1); - else - $city = $ex[1]; - } else { - $city = $ex[0]; - $continent = t('Miscellaneous'); - } - $city = str_replace('_', ' ', t($city)); + usort($timezone_identifiers, 'timezone_cmp'); + $continent = ''; + $continents = []; + foreach ($timezone_identifiers as $value) { + $ex = explode("/", $value); + if (count($ex) > 1) { + $continent = t($ex[0]); + if (count($ex) > 2) { + $city = substr($value, strpos($value, '/') + 1); + } else { + $city = $ex[1]; + } + } else { + $city = $ex[0]; + $continent = t('Miscellaneous'); + } + $city = str_replace('_', ' ', t($city)); - if (!x($continents, $ex[0])) $continents[$ex[0]] = []; - $continents[$continent][$value] = $city; - } + if (!x($continents, $ex[0])) { + $continents[$ex[0]] = []; + } + $continents[$continent][$value] = $city; + } - return $continents; + return $continents; } /** @@ -76,45 +92,49 @@ function get_timezones( ){ * http://www.php.net/manual/en/datetime.format.php * @return string */ -function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") { +function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") +{ - // Defaults to UTC if nothing is set, but throws an exception if set to empty string. - // Provide some sane defaults regardless. + // Defaults to UTC if nothing is set, but throws an exception if set to empty string. + // Provide some sane defaults regardless. - if($from === '') - $from = 'UTC'; - if($to === '') - $to = 'UTC'; - if( ($s === '') || (! is_string($s)) ) - $s = 'now'; + if ($from === '') { + $from = 'UTC'; + } + if ($to === '') { + $to = 'UTC'; + } + if (($s === '') || (! is_string($s))) { + $s = 'now'; + } - if(is_null_date($s)) { - $d = new DateTime('0001-01-01 00:00:00', new DateTimeZone('UTC')); - return $d->format($fmt); - } + if (is_null_date($s)) { + $d = new DateTime('0001-01-01 00:00:00', new DateTimeZone('UTC')); + return $d->format($fmt); + } - try { - $from_obj = new DateTimeZone($from); - } catch(Exception $e) { - $from_obj = new DateTimeZone('UTC'); - } + try { + $from_obj = new DateTimeZone($from); + } catch (Exception $e) { + $from_obj = new DateTimeZone('UTC'); + } - try { - $d = new DateTime($s, $from_obj); - } catch(Exception $e) { - logger('exception: ' . $e->getMessage()); - $d = new DateTime('now', $from_obj); - } + try { + $d = new DateTime($s, $from_obj); + } catch (Exception $e) { + logger('exception: ' . $e->getMessage()); + $d = new DateTime('now', $from_obj); + } - try { - $to_obj = new DateTimeZone($to); - } catch(Exception $e) { - $to_obj = new DateTimeZone('UTC'); - } + try { + $to_obj = new DateTimeZone($to); + } catch (Exception $e) { + $to_obj = new DateTimeZone('UTC'); + } - $d->setTimeZone($to_obj); + $d->setTimeZone($to_obj); - return($d->format($fmt)); + return($d->format($fmt)); } /** @@ -123,27 +143,30 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d * @param string $dob Date of Birth * @return string Parsed HTML with selector */ -function dob($dob) { +function dob($dob) +{ - $y = substr($dob,0,4); - if((! ctype_digit($y)) || ($y < 1900)) - $ignore_year = true; - else - $ignore_year = false; + $y = substr($dob, 0, 4); + if ((! ctype_digit($y)) || ($y < 1900)) { + $ignore_year = true; + } else { + $ignore_year = false; + } - if ($dob === '0000-00-00' || $dob === '') - $value = ''; - else - $value = (($ignore_year) ? datetime_convert('UTC','UTC',$dob,'m-d') : datetime_convert('UTC','UTC',$dob,'Y-m-d')); + if ($dob === '0000-00-00' || $dob === '') { + $value = ''; + } else { + $value = (($ignore_year) ? datetime_convert('UTC', 'UTC', $dob, 'm-d') : datetime_convert('UTC', 'UTC', $dob, 'Y-m-d')); + } - $age = age($value,App::$user['timezone'],App::$user['timezone']); + $age = age($value, App::$user['timezone'], App::$user['timezone']); - $o = replace_macros(get_markup_template("field_input.tpl"), [ - '$field' => [ 'dob', t('Birthday'), $value, ((intval($age)) ? t('Age: ') . $age : ''), '', 'placeholder="' . t('YYYY-MM-DD or MM-DD') .'"' ] - ]); + $o = replace_macros(get_markup_template("field_input.tpl"), [ + '$field' => [ 'dob', t('Birthday'), $value, ((intval($age)) ? t('Age: ') . $age : ''), '', 'placeholder="' . t('YYYY-MM-DD or MM-DD') . '"' ] + ]); - return $o; + return $o; } /** @@ -175,46 +198,59 @@ function dob($dob) { * @todo Once browser support is better this could probably be replaced with * native HTML5 date picker. */ -function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false, $first_day = 0) { +function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false, $first_day = 0) +{ - $o = ''; - $dateformat = ''; + $o = ''; + $dateformat = ''; - if($pickdate) $dateformat .= 'Y-m-d'; - if($pickdate && $picktime) $dateformat .= ' '; - if($picktime) $dateformat .= 'H:i'; + if ($pickdate) { + $dateformat .= 'Y-m-d'; + } + if ($pickdate && $picktime) { + $dateformat .= ' '; + } + if ($picktime) { + $dateformat .= 'H:i'; + } - $minjs = $min->getTimestamp() ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : ''; - $maxjs = $max->getTimestamp() ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : ''; + $minjs = $min->getTimestamp() ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : ''; + $maxjs = $max->getTimestamp() ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : ''; - $input_text = $default->getTimestamp() ? date($dateformat, $default->getTimestamp()) : ''; - $defaultdatejs = $default->getTimestamp() ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : ''; + $input_text = $default->getTimestamp() ? date($dateformat, $default->getTimestamp()) : ''; + $defaultdatejs = $default->getTimestamp() ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : ''; - $pickers = ''; - if(!$pickdate) $pickers .= ',datepicker: false'; - if(!$picktime) $pickers .= ',timepicker: false, closeOnDateSelect:true'; + $pickers = ''; + if (!$pickdate) { + $pickers .= ',datepicker: false'; + } + if (!$picktime) { + $pickers .= ',timepicker: false, closeOnDateSelect:true'; + } - $extra_js = ''; - if($minfrom != '') - $extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})"; + $extra_js = ''; + if ($minfrom != '') { + $extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})"; + } - if($maxfrom != '') - $extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})"; + if ($maxfrom != '') { + $extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})"; + } - $readable_format = $dateformat; - $readable_format = str_replace('Y','yyyy',$readable_format); - $readable_format = str_replace('m','mm',$readable_format); - $readable_format = str_replace('d','dd',$readable_format); - $readable_format = str_replace('H','HH',$readable_format); - $readable_format = str_replace('i','MM',$readable_format); + $readable_format = $dateformat; + $readable_format = str_replace('Y', 'yyyy', $readable_format); + $readable_format = str_replace('m', 'mm', $readable_format); + $readable_format = str_replace('d', 'dd', $readable_format); + $readable_format = str_replace('H', 'HH', $readable_format); + $readable_format = str_replace('i', 'MM', $readable_format); - $tpl = get_markup_template('field_input.tpl'); - $o .= replace_macros($tpl,array( - '$field' => array($id, $label, $input_text, (($required) ? t('Required') : ''), (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'), - )); - $o .= ""; + $tpl = get_markup_template('field_input.tpl'); + $o .= replace_macros($tpl, array( + '$field' => array($id, $label, $input_text, (($required) ? t('Required') : ''), (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'), + )); + $o .= ""; - return $o; + return $o; } /** @@ -230,78 +266,79 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago * @return string with relative date */ -function relative_date($posted_date, $format = null) { +function relative_date($posted_date, $format = null) +{ - $localtime = datetime_convert('UTC', date_default_timezone_get(), $posted_date); + $localtime = datetime_convert('UTC', date_default_timezone_get(), $posted_date); - $abs = strtotime($localtime); + $abs = strtotime($localtime); - if (is_null($posted_date) || is_null_date($posted_date) || $abs === false) { - return t('never'); - } + if (is_null($posted_date) || is_null_date($posted_date) || $abs === false) { + return t('never'); + } - if ($abs > time()) { - $direction = t('from now'); - $etime = $abs - time(); - } - else { - $direction = t('ago'); - $etime = time() - $abs; - } - - if ($etime < 1) { - return sprintf( t('less than a second %s'), $direction); - } + if ($abs > time()) { + $direction = t('from now'); + $etime = $abs - time(); + } else { + $direction = t('ago'); + $etime = time() - $abs; + } - $a = array( 12 * 30 * 24 * 60 * 60 => 'y', - 30 * 24 * 60 * 60 => 'm', - 7 * 24 * 60 * 60 => 'w', - 24 * 60 * 60 => 'd', - 60 * 60 => 'h', - 60 => 'i', - 1 => 's' - ); + if ($etime < 1) { + return sprintf(t('less than a second %s'), $direction); + } + + $a = array( 12 * 30 * 24 * 60 * 60 => 'y', + 30 * 24 * 60 * 60 => 'm', + 7 * 24 * 60 * 60 => 'w', + 24 * 60 * 60 => 'd', + 60 * 60 => 'h', + 60 => 'i', + 1 => 's' + ); - foreach ($a as $secs => $str) { - $d = $etime / $secs; - if ($d >= 1) { - $r = round($d); - if (! $format) { - $format = t('%1$d %2$s %3$s', 'e.g. 22 hours ago, 1 minute ago'); - } - return sprintf($format, $r, plural_dates($str,$r), $direction); - } - } + foreach ($a as $secs => $str) { + $d = $etime / $secs; + if ($d >= 1) { + $r = round($d); + if (! $format) { + $format = t('%1$d %2$s %3$s', 'e.g. 22 hours ago, 1 minute ago'); + } + return sprintf($format, $r, plural_dates($str, $r), $direction); + } + } } -function plural_dates($k,$n) { +function plural_dates($k, $n) +{ - switch($k) { - case 'y': - return tt('year','years',$n,'relative_date'); - break; - case 'm': - return tt('month','months',$n,'relative_date'); - break; - case 'w': - return tt('week','weeks',$n,'relative_date'); - break; - case 'd': - return tt('day','days',$n,'relative_date'); - break; - case 'h': - return tt('hour','hours',$n,'relative_date'); - break; - case 'i': - return tt('minute','minutes',$n,'relative_date'); - break; - case 's': - return tt('second','seconds',$n,'relative_date'); - break; - default: - return; - } + switch ($k) { + case 'y': + return tt('year', 'years', $n, 'relative_date'); + break; + case 'm': + return tt('month', 'months', $n, 'relative_date'); + break; + case 'w': + return tt('week', 'weeks', $n, 'relative_date'); + break; + case 'd': + return tt('day', 'days', $n, 'relative_date'); + break; + case 'h': + return tt('hour', 'hours', $n, 'relative_date'); + break; + case 'i': + return tt('minute', 'minutes', $n, 'relative_date'); + break; + case 's': + return tt('second', 'seconds', $n, 'relative_date'); + break; + default: + return; + } } /** @@ -324,24 +361,29 @@ function plural_dates($k,$n) { * @param string $viewer_tz (optional) timezone of the person viewing * @return number */ -function age($dob, $owner_tz = '', $viewer_tz = '') { - if (! intval($dob)) - return 0; - if (! $owner_tz) - $owner_tz = date_default_timezone_get(); - if (! $viewer_tz) - $viewer_tz = date_default_timezone_get(); +function age($dob, $owner_tz = '', $viewer_tz = '') +{ + if (! intval($dob)) { + return 0; + } + if (! $owner_tz) { + $owner_tz = date_default_timezone_get(); + } + if (! $viewer_tz) { + $viewer_tz = date_default_timezone_get(); + } - $birthdate = datetime_convert('UTC', $owner_tz, $dob . ' 00:00:00+00:00','Y-m-d'); - list($year,$month,$day) = explode("-", $birthdate); - $year_diff = datetime_convert('UTC', $viewer_tz, 'now', 'Y') - $year; - $curr_month = datetime_convert('UTC', $viewer_tz, 'now', 'm'); - $curr_day = datetime_convert('UTC', $viewer_tz, 'now', 'd'); + $birthdate = datetime_convert('UTC', $owner_tz, $dob . ' 00:00:00+00:00', 'Y-m-d'); + list($year,$month,$day) = explode("-", $birthdate); + $year_diff = datetime_convert('UTC', $viewer_tz, 'now', 'Y') - $year; + $curr_month = datetime_convert('UTC', $viewer_tz, 'now', 'm'); + $curr_day = datetime_convert('UTC', $viewer_tz, 'now', 'd'); - if (($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day))) - $year_diff--; + if (($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day))) { + $year_diff--; + } - return $year_diff; + return $year_diff; } /** @@ -354,19 +396,22 @@ function age($dob, $owner_tz = '', $viewer_tz = '') { * @param int $m month (1=January, 12=December) * @return int number of days in the given month */ -function get_dim($y, $m) { - $dim = array( 0, - 31, 28, 31, 30, 31, 30, - 31, 31, 30, 31, 30, 31 - ); +function get_dim($y, $m) +{ + $dim = array( 0, + 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31 + ); - if ($m != 2) - return $dim[$m]; + if ($m != 2) { + return $dim[$m]; + } - if (((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0)) - return 29; + if (((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0)) { + return 29; + } - return $dim[2]; + return $dim[2]; } /** @@ -378,10 +423,11 @@ function get_dim($y, $m) { * @param int $m Month (1=January, 12=December) * @return string day 0 = Sunday through 6 = Saturday */ -function get_first_dim($y, $m) { - $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m)); +function get_first_dim($y, $m) +{ + $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m)); - return datetime_convert('UTC', 'UTC', $d, 'w'); + return datetime_convert('UTC', 'UTC', $d, 'w'); } /** @@ -400,69 +446,78 @@ function get_first_dim($y, $m) { * * @todo provide (prev,next) links, define class variations for different size calendars */ -function cal($y = 0, $m = 0, $links = false, $class='') { +function cal($y = 0, $m = 0, $links = false, $class = '') +{ - // month table - start at 1 to match human usage. + // month table - start at 1 to match human usage. - $mtab = [ ' ', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; + $mtab = [ ' ', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; - $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); - $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m'); - if (! $y) - $y = $thisyear; - if (! $m) - $m = intval($thismonth); + $thisyear = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); + $thismonth = datetime_convert('UTC', date_default_timezone_get(), 'now', 'm'); + if (! $y) { + $y = $thisyear; + } + if (! $m) { + $m = intval($thismonth); + } - $dn = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; - $f = get_first_dim($y, $m); - $l = get_dim($y, $m); - $d = 1; - $dow = 0; - $started = false; + $dn = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; + $f = get_first_dim($y, $m); + $l = get_dim($y, $m); + $d = 1; + $dow = 0; + $started = false; - if (($y == $thisyear) && ($m == $thismonth)) - $tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j')); + if (($y == $thisyear) && ($m == $thismonth)) { + $tddate = intval(datetime_convert('UTC', date_default_timezone_get(), 'now', 'j')); + } - $str_month = day_translate($mtab[$m]); - $o = ''; - $o .= ""; - for ($a = 0; $a < 7; $a ++) - $o .= ''; + $str_month = day_translate($mtab[$m]); + $o = '
                    $str_month $y
                    ' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . '
                    '; + $o .= ""; + for ($a = 0; $a < 7; $a++) { + $o .= ''; + } - $o .= ''; + $o .= ''; - while ($d <= $l) { - if (($dow == $f) && (! $started)) - $started = true; + while ($d <= $l) { + if (($dow == $f) && (! $started)) { + $started = true; + } - $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : ''); - $o .= "'; - $dow ++; - if (($dow == 7) && ($d <= $l)) { - $dow = 0; - $o .= ''; - } - } - if ($dow) - for ($a = $dow; $a < 7; $a ++) - $o .= ''; + $o .= ''; + $dow++; + if (($dow == 7) && ($d <= $l)) { + $dow = 0; + $o .= ''; + } + } + if ($dow) { + for ($a = $dow; $a < 7; $a++) { + $o .= ''; + } + } - $o .= '
                    $str_month $y
                    ' . mb_substr(day_translate($dn[$a]), 0, 3, 'UTF-8') . '
                    "; - $day = str_replace(' ',' ',sprintf('%2.2d', $d)); - if ($started) { - if (is_array($links) && isset($links[$d])) - $o .= "$day"; - else - $o .= $day; + $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : ''); + $o .= ""; + $day = str_replace(' ', ' ', sprintf('%2.2d', $d)); + if ($started) { + if (is_array($links) && isset($links[$d])) { + $o .= "$day"; + } else { + $o .= $day; + } - $d ++; - } else { - $o .= ' '; - } + $d++; + } else { + $o .= ' '; + } - $o .= '
                     
                     
                    '."\r\n"; + $o .= '' . "\r\n"; - return $o; + return $o; } /** @@ -477,26 +532,29 @@ function cal($y = 0, $m = 0, $links = false, $class='') { * @param string $format * @return string */ -function z_birthday($dob, $tz, $format="Y-m-d H:i:s") { +function z_birthday($dob, $tz, $format = "Y-m-d H:i:s") +{ - if (! strlen($tz)) - $tz = 'UTC'; + if (! strlen($tz)) { + $tz = 'UTC'; + } - $birthday = ''; - $tmp_dob = substr($dob,5); - $tmp_d = substr($dob,8); - if (intval($tmp_dob) && intval($tmp_d)) { - $y = datetime_convert($tz,$tz,'now','Y'); - $bd = $y . '-' . $tmp_dob . ' 00:00'; - $t_dob = strtotime($bd); - $now = strtotime(datetime_convert($tz,$tz,'now')); - if ($t_dob < $now) - $bd = $y + 1 . '-' . $tmp_dob . ' 00:00'; + $birthday = ''; + $tmp_dob = substr($dob, 5); + $tmp_d = substr($dob, 8); + if (intval($tmp_dob) && intval($tmp_d)) { + $y = datetime_convert($tz, $tz, 'now', 'Y'); + $bd = $y . '-' . $tmp_dob . ' 00:00'; + $t_dob = strtotime($bd); + $now = strtotime(datetime_convert($tz, $tz, 'now')); + if ($t_dob < $now) { + $bd = $y + 1 . '-' . $tmp_dob . ' 00:00'; + } - $birthday = datetime_convert($tz,'UTC',$bd,$format); - } + $birthday = datetime_convert($tz, 'UTC', $bd, $format); + } - return $birthday; + return $birthday; } /** @@ -504,41 +562,47 @@ function z_birthday($dob, $tz, $format="Y-m-d H:i:s") { * * Update the year so that we don't create another event until next year. */ -function update_birthdays() { +function update_birthdays() +{ - require_once('include/event.php'); - require_once('include/permissions.php'); + require_once('include/event.php'); + require_once('include/permissions.php'); - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_dob > %s + interval %s and abook_dob < %s + interval %s", - db_utcnow(), db_quoteinterval('7 day'), - db_utcnow(), db_quoteinterval('14 day') - ); - if ($r) { - foreach ($r as $rr) { - if (! perm_is_allowed($rr['abook_channel'], $rr['xchan_hash'], 'send_stream')) - continue; + db_utcnow(), + db_quoteinterval('7 day'), + db_utcnow(), + db_quoteinterval('14 day') + ); + if ($r) { + foreach ($r as $rr) { + if (! perm_is_allowed($rr['abook_channel'], $rr['xchan_hash'], 'send_stream')) { + continue; + } - $ev = [ - 'uid' => $rr['abook_channel'], - 'account' => $rr['abook_account'], - 'event_xchan' => $rr['xchan_hash'], - 'dtstart' => datetime_convert('UTC', 'UTC', $rr['abook_dob']), - 'dtend' => datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day '), - 'adjust' => intval(feature_enabled($rr['abook_channel'],'smart_birthdays')), - 'summary' => sprintf( t('%1$s\'s birthday'), $rr['xchan_name']), - 'description' => sprintf( t('Happy Birthday %1$s'), '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]'), - 'etype' => 'birthday', - ]; + $ev = [ + 'uid' => $rr['abook_channel'], + 'account' => $rr['abook_account'], + 'event_xchan' => $rr['xchan_hash'], + 'dtstart' => datetime_convert('UTC', 'UTC', $rr['abook_dob']), + 'dtend' => datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day '), + 'adjust' => intval(feature_enabled($rr['abook_channel'], 'smart_birthdays')), + 'summary' => sprintf(t('%1$s\'s birthday'), $rr['xchan_name']), + 'description' => sprintf(t('Happy Birthday %1$s'), '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]'), + 'etype' => 'birthday', + ]; - $z = event_store_event($ev); - if ($z) { - $item_id = event_store_item($ev, $z); - q("update abook set abook_dob = '%s' where abook_id = %d", - dbesc(intval($rr['abook_dob']) + 1 . substr($rr['abook_dob'], 4)), - intval($rr['abook_id']) - ); - } - } - } + $z = event_store_event($ev); + if ($z) { + $item_id = event_store_item($ev, $z); + q( + "update abook set abook_dob = '%s' where abook_id = %d", + dbesc(intval($rr['abook_dob']) + 1 . substr($rr['abook_dob'], 4)), + intval($rr['abook_id']) + ); + } + } + } } diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index da5257f25..32506293d 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -16,67 +16,68 @@ use Zotlabs\Lib\System; * abstract dba_driver class. */ -class DBA { +class DBA +{ - public static $dba = null; - public static $dbtype = null; - public static $scheme = 'mysql'; - public static $logging = false; + public static $dba = null; + public static $dbtype = null; + public static $scheme = 'mysql'; + public static $logging = false; - public static $install_script = 'schema_mysql.sql'; - public static $null_date = '0001-01-01 00:00:00'; - public static $utc_now = 'UTC_TIMESTAMP()'; - public static $tquot = "`"; + public static $install_script = 'schema_mysql.sql'; + public static $null_date = '0001-01-01 00:00:00'; + public static $utc_now = 'UTC_TIMESTAMP()'; + public static $tquot = "`"; - /** - * @brief Returns the database driver object. - * - * @param string $server DB server name (or PDO dsn - e.g. mysqli:foobar.com;) - * @param string $port DB port - * @param string $user DB username - * @param string $pass DB password - * @param string $db database name - * @param string $dbtype 0 for mysql, 1 for postgres - * @param bool $install Defaults to false - * @return null|dba_driver A database driver object (dba_pdo) or null if no driver found. - */ - public static function dba_factory($server, $port, $user, $pass, $db, $dbtype, $install = false) { + /** + * @brief Returns the database driver object. + * + * @param string $server DB server name (or PDO dsn - e.g. mysqli:foobar.com;) + * @param string $port DB port + * @param string $user DB username + * @param string $pass DB password + * @param string $db database name + * @param string $dbtype 0 for mysql, 1 for postgres + * @param bool $install Defaults to false + * @return null|dba_driver A database driver object (dba_pdo) or null if no driver found. + */ + public static function dba_factory($server, $port, $user, $pass, $db, $dbtype, $install = false) + { - self::$dba = null; - self::$dbtype = intval($dbtype); + self::$dba = null; + self::$dbtype = intval($dbtype); - if(self::$dbtype == DBTYPE_POSTGRES) { - if(!($port)) - $port = 5432; + if (self::$dbtype == DBTYPE_POSTGRES) { + if (!($port)) { + $port = 5432; + } - self::$install_script = 'schema_postgres.sql'; - self::$utc_now = "now() at time zone 'UTC'"; - self::$tquot = '"'; - self::$scheme = 'pgsql'; - } - else { + self::$install_script = 'schema_postgres.sql'; + self::$utc_now = "now() at time zone 'UTC'"; + self::$tquot = '"'; + self::$scheme = 'pgsql'; + } else { + // attempt to use the pdo driver compiled-in mysqli socket + // if using 'localhost' with no port configured. + // If this is wrong you'll need to set the socket path specifically + // using a server name of 'mysql:unix_socket=/socket/path', setting /socket/path + // as needed for your platform - // attempt to use the pdo driver compiled-in mysqli socket - // if using 'localhost' with no port configured. - // If this is wrong you'll need to set the socket path specifically - // using a server name of 'mysql:unix_socket=/socket/path', setting /socket/path - // as needed for your platform + if ((!($port)) && ($server !== 'localhost')) { + $port = 3306; + } + } - if((!($port)) && ($server !== 'localhost')) - $port = 3306; - } + require_once('include/dba/dba_pdo.php'); + self::$dba = new dba_pdo($server, self::$scheme, $port, $user, $pass, $db, $install); - require_once('include/dba/dba_pdo.php'); - self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$install); - - define('NULL_DATE', self::$null_date); - define('ACTIVE_DBTYPE', self::$dbtype); - define('TQUOT', self::$tquot); - - return self::$dba; - } + define('NULL_DATE', self::$null_date); + define('ACTIVE_DBTYPE', self::$dbtype); + define('TQUOT', self::$tquot); + return self::$dba; + } } /** @@ -109,7 +110,7 @@ abstract class dba_driver * @param string $db database name * @return bool */ - public abstract function connect($server, $scheme, $port, $user, $pass, $db); + abstract public function connect($server, $scheme, $port, $user, $pass, $db); /** * @brief Perform a DB query with the SQL statement $sql. @@ -118,7 +119,7 @@ abstract class dba_driver * * @param string $sql The SQL query to execute */ - public abstract function q($sql); + abstract public function q($sql); /** * @brief Escape a string before being passed to a DB query. @@ -127,21 +128,21 @@ abstract class dba_driver * * @param string $str The string to escape. */ - public abstract function escape($str); + abstract public function escape($str); /** * @brief Close the database connection. * * This abstract function needs to be implemented in the real driver. */ - public abstract function close(); + abstract public function close(); /** * @brief Return text name for db driver * * This abstract function needs to be implemented in the real driver. */ - public abstract function getdriver(); + abstract public function getdriver(); public function __construct($server, $scheme, $port, $user, $pass, $db, $install = false) { @@ -159,8 +160,9 @@ abstract class dba_driver public function get_install_script() { $platform_name = System::get_platform_name(); - if (file_exists('install/' . $platform_name . '/' . DBA::$install_script)) + if (file_exists('install/' . $platform_name . '/' . DBA::$install_script)) { return 'install/' . $platform_name . '/' . DBA::$install_script; + } return 'install/' . DBA::$install_script; } @@ -236,7 +238,6 @@ abstract class dba_driver { return $str; } - } // end abstract dba_driver class @@ -244,14 +245,15 @@ abstract class dba_driver // Procedural functions // -function printable($s, $escape = true) { - $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s); - $s = str_replace("\x00",'.',$s); - if ($escape) { - $s = escape_tags($s); - } +function printable($s, $escape = true) +{ + $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~", ".", $s); + $s = str_replace("\x00", '.', $s); + if ($escape) { + $s = escape_tags($s); + } - return $s; + return $s; } /** @@ -259,11 +261,13 @@ function printable($s, $escape = true) { * * @param int $state 0 to disable debugging */ -function dbg($state) { - global $db; +function dbg($state) +{ + global $db; - if(DBA::$dba) - DBA::$dba->dbg($state); + if (DBA::$dba) { + DBA::$dba->dbg($state); + } } /** @@ -276,53 +280,66 @@ function dbg($state) { * @param string $str A string to pass to a DB query * @return string Return an escaped string of the value to pass to a DB query. */ -function dbesc($str) { +function dbesc($str) +{ - if(is_null_date($str)) - $str = NULL_DATE; + if (is_null_date($str)) { + $str = NULL_DATE; + } - if(DBA::$dba && DBA::$dba->connected) - return(DBA::$dba->escape($str)); - else - return(str_replace("'", "\\'", $str)); + if (DBA::$dba && DBA::$dba->connected) { + return(DBA::$dba->escape($str)); + } else { + return(str_replace("'", "\\'", $str)); + } } -function dbescbin($str) { - return DBA::$dba->escapebin($str); +function dbescbin($str) +{ + return DBA::$dba->escapebin($str); } -function dbunescbin($str) { - return DBA::$dba->unescapebin($str); +function dbunescbin($str) +{ + return DBA::$dba->unescapebin($str); } -function dbescdate($date) { - if(is_null_date($date)) - return DBA::$dba->escape(NULL_DATE); +function dbescdate($date) +{ + if (is_null_date($date)) { + return DBA::$dba->escape(NULL_DATE); + } - return DBA::$dba->escape($date); + return DBA::$dba->escape($date); } -function db_quoteinterval($txt) { - return DBA::$dba->quote_interval($txt); +function db_quoteinterval($txt) +{ + return DBA::$dba->quote_interval($txt); } -function dbesc_identifier($str) { - return DBA::$dba->escape_identifier($str); +function dbesc_identifier($str) +{ + return DBA::$dba->escape_identifier($str); } -function db_utcnow() { - return DBA::$dba->utcnow(); +function db_utcnow() +{ + return DBA::$dba->utcnow(); } -function db_optimizetable($table) { - DBA::$dba->optimize_table($table); +function db_optimizetable($table) +{ + DBA::$dba->optimize_table($table); } -function db_concat($fld, $sep) { - return DBA::$dba->concat($fld, $sep); +function db_concat($fld, $sep) +{ + return DBA::$dba->concat($fld, $sep); } -function db_use_index($str) { - return DBA::$dba->use_index($str); +function db_use_index($str) +{ + return DBA::$dba->use_index($str); } /** @@ -341,31 +358,33 @@ function db_use_index($str) { * @param string $sql The SQL query to execute * @return bool|array */ -function q($sql) { +function q($sql) +{ - $args = func_get_args(); - array_shift($args); + $args = func_get_args(); + array_shift($args); - if(DBA::$dba && DBA::$dba->connected) { - $stmt = vsprintf($sql, $args); - if($stmt === false) { - db_logger('dba: vsprintf error: ' . - print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true),LOGGER_NORMAL,LOG_CRIT); - } - if(DBA::$dba->debug) - db_logger('Sql: ' . $stmt, LOGGER_DEBUG, LOG_INFO); + if (DBA::$dba && DBA::$dba->connected) { + $stmt = vsprintf($sql, $args); + if ($stmt === false) { + db_logger('dba: vsprintf error: ' . + print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true), LOGGER_NORMAL, LOG_CRIT); + } + if (DBA::$dba->debug) { + db_logger('Sql: ' . $stmt, LOGGER_DEBUG, LOG_INFO); + } - return DBA::$dba->q($stmt); - } + return DBA::$dba->q($stmt); + } - /* - * This will happen occasionally trying to store the - * session data after abnormal program termination - */ + /* + * This will happen occasionally trying to store the + * session data after abnormal program termination + */ - db_logger('dba: no database: ' . print_r($args,true),LOGGER_NORMAL,LOG_CRIT); + db_logger('dba: no database: ' . print_r($args, true), LOGGER_NORMAL, LOG_CRIT); - return false; + return false; } /** @@ -375,14 +394,16 @@ function q($sql) { * * @param string $sql The SQL query to execute */ -function dbq($sql) { +function dbq($sql) +{ - if(DBA::$dba && DBA::$dba->connected) - $ret = DBA::$dba->q($sql); - else - $ret = false; + if (DBA::$dba && DBA::$dba->connected) { + $ret = DBA::$dba->q($sql); + } else { + $ret = false; + } - return $ret; + return $ret; } @@ -392,72 +413,78 @@ function dbq($sql) { // SQL injection vectors. All integer array elements should be specifically // cast to int to avoid trouble. -function dbesc_array_cb(&$item, $key) { - if(is_string($item)) { - if(is_null_date($item)) - $item = NULL_DATE; - $item = dbesc($item); - } +function dbesc_array_cb(&$item, $key) +{ + if (is_string($item)) { + if (is_null_date($item)) { + $item = NULL_DATE; + } + $item = dbesc($item); + } } -function dbesc_array(&$arr) { - $bogus_key = false; - if(is_array($arr) && count($arr)) { - $matches = false; - foreach($arr as $k => $v) { - if(preg_match('/([^a-zA-Z0-9\-\_\.])/',$k,$matches)) { - logger('bogus key: ' . $k); - $bogus_key = true; - } - } - array_walk($arr,'dbesc_array_cb'); - if($bogus_key) { - $arr['BOGUS.KEY'] = 1; - return false; - } - } - return true; +function dbesc_array(&$arr) +{ + $bogus_key = false; + if (is_array($arr) && count($arr)) { + $matches = false; + foreach ($arr as $k => $v) { + if (preg_match('/([^a-zA-Z0-9\-\_\.])/', $k, $matches)) { + logger('bogus key: ' . $k); + $bogus_key = true; + } + } + array_walk($arr, 'dbesc_array_cb'); + if ($bogus_key) { + $arr['BOGUS.KEY'] = 1; + return false; + } + } + return true; } -function db_getfunc($f) { - $lookup = array( - 'rand'=>array( - DBTYPE_MYSQL=>'RAND()', - DBTYPE_POSTGRES=>'RANDOM()' - ), - 'utc_timestamp'=>array( - DBTYPE_MYSQL=>'UTC_TIMESTAMP()', - DBTYPE_POSTGRES=>"now() at time zone 'UTC'" - ), - 'regexp'=>array( - DBTYPE_MYSQL=>'REGEXP', - DBTYPE_POSTGRES=>'~' - ), - '^'=>array( - DBTYPE_MYSQL=>'^', - DBTYPE_POSTGRES=>'#' - ) - ); - $f = strtolower($f); - if(isset($lookup[$f]) && isset($lookup[$f][ACTIVE_DBTYPE])) - return $lookup[$f][ACTIVE_DBTYPE]; +function db_getfunc($f) +{ + $lookup = array( + 'rand'=>array( + DBTYPE_MYSQL=>'RAND()', + DBTYPE_POSTGRES=>'RANDOM()' + ), + 'utc_timestamp'=>array( + DBTYPE_MYSQL=>'UTC_TIMESTAMP()', + DBTYPE_POSTGRES=>"now() at time zone 'UTC'" + ), + 'regexp'=>array( + DBTYPE_MYSQL=>'REGEXP', + DBTYPE_POSTGRES=>'~' + ), + '^'=>array( + DBTYPE_MYSQL=>'^', + DBTYPE_POSTGRES=>'#' + ) + ); + $f = strtolower($f); + if (isset($lookup[$f]) && isset($lookup[$f][ACTIVE_DBTYPE])) { + return $lookup[$f][ACTIVE_DBTYPE]; + } - db_logger('Unable to abstract DB function "'. $f . '" for dbtype ' . ACTIVE_DBTYPE, LOGGER_DEBUG, LOG_ERR); - return $f; + db_logger('Unable to abstract DB function "'. $f . '" for dbtype ' . ACTIVE_DBTYPE, LOGGER_DEBUG, LOG_ERR); + return $f; } -function db_load_file($f) { - // db errors should get logged to the logfile - $str = @file_get_contents($f); - $arr = explode(';', $str); - if($arr) { - foreach($arr as $a) { - if(strlen(trim($a))) { - $r = dbq(trim($a)); - } - } - } +function db_load_file($f) +{ + // db errors should get logged to the logfile + $str = @file_get_contents($f); + $arr = explode(';', $str); + if ($arr) { + foreach ($arr as $a) { + if (strlen(trim($a))) { + $r = dbq(trim($a)); + } + } + } } @@ -466,65 +493,71 @@ function db_load_file($f) { // So this function preserves the current database debugging state and then turns it off // temporarily while doing the logger() call -function db_logger($s,$level = LOGGER_NORMAL,$syslog = LOG_INFO) { +function db_logger($s, $level = LOGGER_NORMAL, $syslog = LOG_INFO) +{ - if(DBA::$logging || ! DBA::$dba) - return; + if (DBA::$logging || ! DBA::$dba) { + return; + } - $saved = DBA::$dba->debug; - DBA::$dba->debug = false; - DBA::$logging = true; - logger($s,$level,$syslog); - DBA::$logging = false; - DBA::$dba->debug = $saved; + $saved = DBA::$dba->debug; + DBA::$dba->debug = false; + DBA::$logging = true; + logger($s, $level, $syslog); + DBA::$logging = false; + DBA::$dba->debug = $saved; } -function db_columns($table) { +function db_columns($table) +{ - if($table) { - if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) { - $r = q("SELECT column_name as field FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '%s'", - dbesc($table) - ); - if($r) { - return ids_to_array($r,'field'); - } - } - else { - $r = q("show columns in %s", - dbesc($table) - ); - if($r) { - return ids_to_array($r,'Field'); - } - } - } + if ($table) { + if (ACTIVE_DBTYPE === DBTYPE_POSTGRES) { + $r = q( + "SELECT column_name as field FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '%s'", + dbesc($table) + ); + if ($r) { + return ids_to_array($r, 'field'); + } + } else { + $r = q( + "show columns in %s", + dbesc($table) + ); + if ($r) { + return ids_to_array($r, 'Field'); + } + } + } - return []; + return []; } -function db_indexes($table) { +function db_indexes($table) +{ - if($table) { - if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) { - $r = q("SELECT indexname from pg_indexes where tablename = '%s'", - dbesc($table) - ); - if($r) { - return ids_to_array($r,'indexname'); - } - } - else { - $r = q("show index from %s", - dbesc($table) - ); - if($r) { - return ids_to_array($r,'Key_name'); - } - } - } + if ($table) { + if (ACTIVE_DBTYPE === DBTYPE_POSTGRES) { + $r = q( + "SELECT indexname from pg_indexes where tablename = '%s'", + dbesc($table) + ); + if ($r) { + return ids_to_array($r, 'indexname'); + } + } else { + $r = q( + "show index from %s", + dbesc($table) + ); + if ($r) { + return ids_to_array($r, 'Key_name'); + } + } + } - return []; + return []; } diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index 92955c3fe..9009c03d2 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -39,8 +39,9 @@ class dba_pdo extends dba_driver return false; } - if ($this->driver_dbtype === 'pgsql') + if ($this->driver_dbtype === 'pgsql') { $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';"); + } $this->connected = true; @@ -58,8 +59,9 @@ class dba_pdo extends dba_driver */ public function q($sql) { - if ((!$this->db) || (!$this->connected)) + if ((!$this->db) || (!$this->connected)) { return false; + } if ($this->driver_dbtype === 'pgsql') { if (substr(rtrim($sql), -1, 1) !== ';') { @@ -74,7 +76,6 @@ class dba_pdo extends dba_driver try { $result = $this->db->query($sql, PDO::FETCH_ASSOC); } catch (PDOException $e) { - $this->error = $e->getMessage(); if ($this->error) { db_logger('dba_pdo: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); @@ -117,8 +118,9 @@ class dba_pdo extends dba_driver public function close() { - if ($this->db) + if ($this->db) { $this->db = null; + } $this->connected = false; } @@ -173,7 +175,6 @@ class dba_pdo extends dba_driver $x = hex2bin(substr($x, 2)); } return $x; - } else { return $str; } @@ -184,5 +185,4 @@ class dba_pdo extends dba_driver { return 'pdo'; } - } diff --git a/include/event.php b/include/event.php index cd11c4aca..896d94814 100644 --- a/include/event.php +++ b/include/event.php @@ -1,4 +1,5 @@ ' . "\r\n"; + $o = '
                    ' . "\r\n"; - $o .= '

                     ' . zidify_links(smilies(bbcode($ev['summary']))) . '

                    ' . "\r\n"; + $o .= '

                     ' . zidify_links(smilies(bbcode($ev['summary']))) . '

                    ' . "\r\n"; - $o .= '
                    ' . t('Starts:') . ' ' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), - $ev['dtstart'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', - $ev['dtstart'] , $bd_format))) - . '
                    ' . "\r\n"; + $o .= '
                    ' . t('Starts:') . ' ' + . (($ev['adjust']) ? day_translate(datetime_convert( + 'UTC', + date_default_timezone_get(), + $ev['dtstart'], + $bd_format + )) + : day_translate(datetime_convert( + 'UTC', + 'UTC', + $ev['dtstart'], + $bd_format + ))) + . '
                    ' . "\r\n"; - if(! $ev['nofinish']) - $o .= '
                    ' . t('Finishes:') . ' ' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), - $ev['dtend'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', - $ev['dtend'] , $bd_format ))) - . '
                    ' . "\r\n"; + if (! $ev['nofinish']) { + $o .= '
                    ' . t('Finishes:') . ' ' + . (($ev['adjust']) ? day_translate(datetime_convert( + 'UTC', + date_default_timezone_get(), + $ev['dtend'], + $bd_format + )) + : day_translate(datetime_convert( + 'UTC', + 'UTC', + $ev['dtend'], + $bd_format + ))) + . '
                    ' . "\r\n"; + } - $o .= '
                    ' . zidify_links(smilies(bbcode($ev['description']))) . '
                    ' . "\r\n"; + $o .= '
                    ' . zidify_links(smilies(bbcode($ev['description']))) . '
                    ' . "\r\n"; - if(isset($ev['location']) && strlen($ev['location'])) - $o .= '
                    ' . t('Location:') . ' ' - . zidify_links(smilies(bbcode($ev['location']))) - . '
                    ' . "\r\n"; + if (isset($ev['location']) && strlen($ev['location'])) { + $o .= '
                    ' . t('Location:') . ' ' + . zidify_links(smilies(bbcode($ev['location']))) + . '
                    ' . "\r\n"; + } - $o .= '
                    ' . "\r\n"; + $o .= '' . "\r\n"; - return $o; + return $o; } -function format_event_obj($jobject) { +function format_event_obj($jobject) +{ - $event = []; + $event = []; - $object = json_decode($jobject,true); + $object = json_decode($jobject, true); /******* - This is our encoded format + This is our encoded format - $x = [ - 'type' => 'Event', - 'id' => z_root() . '/event/' . $r[0]['resource_id'], - 'summary' => bbcode($arr['summary']), - // RFC3339 Section 4.3 - 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')), - 'content' => bbcode($arr['description']), - 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], - 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], - 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], - 'actor' => Activity::encode_person($r[0],false), - ]; - if(! $arr['nofinish']) { - $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00')); - } + $x = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $r[0]['resource_id'], + 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($r[0],false), + ]; + if(! $arr['nofinish']) { + $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00')); + } ******/ - if(is_array($object) && (array_key_exists('summary', $object) || array_key_exists('name',$object))) { + if (is_array($object) && (array_key_exists('summary', $object) || array_key_exists('name', $object))) { + $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM + $dtend = ((array_key_exists('endTime', $object)) ? $object['endTime'] : NULL_DATE); + $title = ((isset($object['summary']) && $object['summary']) ? zidify_links(smilies(bbcode($object['summary']))) : $object['name']); - $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM - $dtend = ((array_key_exists('endTime',$object)) ? $object['endTime'] : NULL_DATE); - $title = ((isset($object['summary']) && $object['summary']) ? zidify_links(smilies(bbcode($object['summary']))) : $object['name']); + $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'), array( + '$title' => $title, + '$dtstart_label' => t('Starts:'), + '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['startTime'], ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtstart_dt' => ((strpos($object['startTime'], 'Z')) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['startTime'], $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $object['startTime'], $bd_format))), + '$finish' => ((array_key_exists('endTime', $object)) ? true : false), + '$dtend_label' => t('Finishes:'), + '$dtend_title' => datetime_convert('UTC', 'UTC', $dtend, ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtend_dt' => ((strpos($object['startTime'], 'Z')) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $dtend, $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $dtend, $bd_format))) - $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array( - '$title' => $title, - '$dtstart_label' => t('Starts:'), - '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['startTime'], ((strpos($object['startTime'],'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtstart_dt' => ((strpos($object['startTime'],'Z')) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['startTime'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['startTime'] , $bd_format))), - '$finish' => ((array_key_exists('endTime',$object)) ? true : false), - '$dtend_label' => t('Finishes:'), - '$dtend_title' => datetime_convert('UTC','UTC',$dtend, ((strpos($object['startTime'],'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtend_dt' => ((strpos($object['startTime'],'Z')) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $dtend , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $dtend , $bd_format ))) + )); - )); + $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'), array( + '$description' => $object['content'], + '$location_label' => t('Location:'), + '$location' => ((array_path_exists('location/content', $object)) ? zidify_links(smilies(bbcode($object['location']['content']))) : EMPTY_STR) + )); + } - $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array( - '$description' => $object['content'], - '$location_label' => t('Location:'), - '$location' => ((array_path_exists('location/content',$object)) ? zidify_links(smilies(bbcode($object['location']['content']))) : EMPTY_STR) - )); - - } - - return $event; + return $event; } -function ical_wrapper($ev) { +function ical_wrapper($ev) +{ - if(! ((is_array($ev)) && count($ev))) - return ''; + if (! ((is_array($ev)) && count($ev))) { + return ''; + } - $o .= "BEGIN:VCALENDAR"; - $o .= "\r\nVERSION:2.0"; - $o .= "\r\nMETHOD:PUBLISH"; - $o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . Zotlabs\Lib\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n"; - if(array_key_exists('dtstart', $ev)) - $o .= format_event_ical($ev); - else { - foreach($ev as $e) { - $o .= format_event_ical($e); - } - } - $o .= "\r\nEND:VCALENDAR\r\n"; + $o .= "BEGIN:VCALENDAR"; + $o .= "\r\nVERSION:2.0"; + $o .= "\r\nMETHOD:PUBLISH"; + $o .= "\r\nPRODID:-//" . get_config('system', 'sitename') . "//" . Zotlabs\Lib\System::get_platform_name() . "//" . strtoupper(App::$language) . "\r\n"; + if (array_key_exists('dtstart', $ev)) { + $o .= format_event_ical($ev); + } else { + foreach ($ev as $e) { + $o .= format_event_ical($e); + } + } + $o .= "\r\nEND:VCALENDAR\r\n"; - return $o; + return $o; } -function format_event_ical($ev) { +function format_event_ical($ev) +{ - if($ev['etype'] === 'task') - return format_todo_ical($ev); + if ($ev['etype'] === 'task') { + return format_todo_ical($ev); + } - $o = ''; + $o = ''; - $o .= "\r\nBEGIN:VEVENT"; + $o .= "\r\nBEGIN:VEVENT"; - $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z'); - $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - if($ev['dtstart']) - $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['dtend'] && ! $ev['nofinish']) - $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['summary']) { - $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); - $o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']); - } - if($ev['location']) { - $o .= "\r\nLOCATION:" . format_ical_text($ev['location']); - $o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']); - } - if($ev['description']) { - $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']); - $o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']); - } - if($ev['event_priority']) - $o .= "\r\nPRIORITY:" . intval($ev['event_priority']); - $o .= "\r\nUID:" . $ev['event_hash'] ; - $o .= "\r\nEND:VEVENT\r\n"; + $o .= "\r\nCREATED:" . datetime_convert('UTC', 'UTC', $ev['created'], 'Ymd\\THis\\Z'); + $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC', 'UTC', $ev['edited'], 'Ymd\\THis\\Z'); + $o .= "\r\nDTSTAMP:" . datetime_convert('UTC', 'UTC', $ev['edited'], 'Ymd\\THis\\Z'); + if ($ev['dtstart']) { + $o .= "\r\nDTSTART:" . datetime_convert('UTC', 'UTC', $ev['dtstart'], 'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + } + if ($ev['dtend'] && ! $ev['nofinish']) { + $o .= "\r\nDTEND:" . datetime_convert('UTC', 'UTC', $ev['dtend'], 'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + } + if ($ev['summary']) { + $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); + $o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']); + } + if ($ev['location']) { + $o .= "\r\nLOCATION:" . format_ical_text($ev['location']); + $o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']); + } + if ($ev['description']) { + $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']); + $o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']); + } + if ($ev['event_priority']) { + $o .= "\r\nPRIORITY:" . intval($ev['event_priority']); + } + $o .= "\r\nUID:" . $ev['event_hash'] ; + $o .= "\r\nEND:VEVENT\r\n"; - return $o; + return $o; } -function format_todo_ical($ev) { +function format_todo_ical($ev) +{ - $o = ''; + $o = ''; - $o .= "\r\nBEGIN:VTODO"; - $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z'); - $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - if($ev['dtstart']) - $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['dtend'] && ! $ev['nofinish']) - $o .= "\r\nDUE:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['summary']) { - $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); - $o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']); - } - if($ev['event_status']) { - $o .= "\r\nSTATUS:" . $ev['event_status']; - if($ev['event_status'] === 'COMPLETED') - $o .= "\r\nCOMPLETED:" . datetime_convert('UTC','UTC', $ev['event_status_date'],'Ymd\\THis\\Z'); - } - if(intval($ev['event_percent'])) - $o .= "\r\nPERCENT-COMPLETE:" . $ev['event_percent']; - if(intval($ev['event_sequence'])) - $o .= "\r\nSEQUENCE:" . $ev['event_sequence']; - if($ev['location']) { - $o .= "\r\nLOCATION:" . format_ical_text($ev['location']); - $o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']); - } - if($ev['description']) { - $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']); - $o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']); - } - $o .= "\r\nUID:" . $ev['event_hash'] ; - if($ev['event_priority']) - $o .= "\r\nPRIORITY:" . intval($ev['event_priority']); - $o .= "\r\nEND:VTODO\r\n"; + $o .= "\r\nBEGIN:VTODO"; + $o .= "\r\nCREATED:" . datetime_convert('UTC', 'UTC', $ev['created'], 'Ymd\\THis\\Z'); + $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC', 'UTC', $ev['edited'], 'Ymd\\THis\\Z'); + $o .= "\r\nDTSTAMP:" . datetime_convert('UTC', 'UTC', $ev['edited'], 'Ymd\\THis\\Z'); + if ($ev['dtstart']) { + $o .= "\r\nDTSTART:" . datetime_convert('UTC', 'UTC', $ev['dtstart'], 'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + } + if ($ev['dtend'] && ! $ev['nofinish']) { + $o .= "\r\nDUE:" . datetime_convert('UTC', 'UTC', $ev['dtend'], 'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + } + if ($ev['summary']) { + $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); + $o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']); + } + if ($ev['event_status']) { + $o .= "\r\nSTATUS:" . $ev['event_status']; + if ($ev['event_status'] === 'COMPLETED') { + $o .= "\r\nCOMPLETED:" . datetime_convert('UTC', 'UTC', $ev['event_status_date'], 'Ymd\\THis\\Z'); + } + } + if (intval($ev['event_percent'])) { + $o .= "\r\nPERCENT-COMPLETE:" . $ev['event_percent']; + } + if (intval($ev['event_sequence'])) { + $o .= "\r\nSEQUENCE:" . $ev['event_sequence']; + } + if ($ev['location']) { + $o .= "\r\nLOCATION:" . format_ical_text($ev['location']); + $o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']); + } + if ($ev['description']) { + $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']); + $o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']); + } + $o .= "\r\nUID:" . $ev['event_hash'] ; + if ($ev['event_priority']) { + $o .= "\r\nPRIORITY:" . intval($ev['event_priority']); + } + $o .= "\r\nEND:VTODO\r\n"; - return $o; + return $o; } -function format_ical_text($s) { +function format_ical_text($s) +{ - require_once('include/html2plain.php'); + require_once('include/html2plain.php'); - $s = html2plain(bbcode($s)); - $s = str_replace(["\r\n","\n"],["",""],$s); + $s = html2plain(bbcode($s)); + $s = str_replace(["\r\n","\n"], ["",""], $s); - return(wordwrap(str_replace(['\\',',',';'],['\\\\','\\,','\\;'],$s),72,"\r\n ",true)); + return(wordwrap(str_replace(['\\',',',';'], ['\\\\','\\,','\\;'], $s), 72, "\r\n ", true)); } -function format_ical_sourcetext($s) { - $s = base64_encode($s); +function format_ical_sourcetext($s) +{ + $s = base64_encode($s); - return(wordwrap(str_replace(['\\',',',';'],['\\\\','\\,','\\;'],$s),72,"\r\n ",true)); + return(wordwrap(str_replace(['\\',',',';'], ['\\\\','\\,','\\;'], $s), 72, "\r\n ", true)); } -function format_event_bbcode($ev) { +function format_event_bbcode($ev) +{ - $o = ''; + $o = ''; - if($ev['event_vdata']) { - $o .= '[event]' . $ev['event_vdata'] . '[/event]'; - } + if ($ev['event_vdata']) { + $o .= '[event]' . $ev['event_vdata'] . '[/event]'; + } - if($ev['summary']) - $o .= '[event-summary]' . $ev['summary'] . '[/event-summary]'; + if ($ev['summary']) { + $o .= '[event-summary]' . $ev['summary'] . '[/event-summary]'; + } - if($ev['description']) - $o .= '[event-description]' . $ev['description'] . '[/event-description]'; + if ($ev['description']) { + $o .= '[event-description]' . $ev['description'] . '[/event-description]'; + } - if($ev['dtstart']) - $o .= '[event-start]' . $ev['dtstart'] . '[/event-start]'; + if ($ev['dtstart']) { + $o .= '[event-start]' . $ev['dtstart'] . '[/event-start]'; + } - if(($ev['dtend']) && (! $ev['nofinish'])) - $o .= '[event-finish]' . $ev['dtend'] . '[/event-finish]'; + if (($ev['dtend']) && (! $ev['nofinish'])) { + $o .= '[event-finish]' . $ev['dtend'] . '[/event-finish]'; + } - if($ev['location']) - $o .= '[event-location]' . $ev['location'] . '[/event-location]'; + if ($ev['location']) { + $o .= '[event-location]' . $ev['location'] . '[/event-location]'; + } - if($ev['event_repeat']) - $o .= '[event-repeat]' . $ev['event_repeat'] . '[/event-repeat]'; + if ($ev['event_repeat']) { + $o .= '[event-repeat]' . $ev['event_repeat'] . '[/event-repeat]'; + } - if($ev['event_hash']) - $o .= '[event-id]' . $ev['event_hash'] . '[/event-id]'; + if ($ev['event_hash']) { + $o .= '[event-id]' . $ev['event_hash'] . '[/event-id]'; + } - if($ev['adjust']) - $o .= '[event-adjust]' . $ev['adjust'] . '[/event-adjust]'; + if ($ev['adjust']) { + $o .= '[event-adjust]' . $ev['adjust'] . '[/event-adjust]'; + } - // Hubzilla compatibility - $o .= '[event-timezone]UTC[/event-timezone]'; - - return $o; + // Hubzilla compatibility + $o .= '[event-timezone]UTC[/event-timezone]'; + + return $o; } -function bbtovcal($s) { - $o = ''; - $ev = bbtoevent($s); - if($ev['description']) - $o = format_event_html($ev); +function bbtovcal($s) +{ + $o = ''; + $ev = bbtoevent($s); + if ($ev['description']) { + $o = format_event_html($ev); + } - return $o; + return $o; } -function bbtoevent($s) { +function bbtoevent($s) +{ - $ev = []; + $ev = []; - $match = ''; - if(preg_match("/\[event\](.*?)\[\/event\]/is",$s,$match)) { - // only parse one object per event tag - // @fixme disabled for now - ical_to_event() expects a VCALENDAR wrapper - // and our VEVENT does not current include it. -// $x = ical_to_ev($match[1]); -// if($x) -// $ev = $x[0]; - } + $match = ''; + if (preg_match("/\[event\](.*?)\[\/event\]/is", $s, $match)) { + // only parse one object per event tag + // @fixme disabled for now - ical_to_event() expects a VCALENDAR wrapper + // and our VEVENT does not current include it. +// $x = ical_to_ev($match[1]); +// if($x) +// $ev = $x[0]; + } - $match = ''; - if(preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is",$s,$match)) - $ev['summary'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is",$s,$match)) - $ev['description'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-start\](.*?)\[\/event\-start\]/is",$s,$match)) - $ev['dtstart'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-finish\](.*?)\[\/event\-finish\]/is",$s,$match)) - $ev['dtend'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-location\](.*?)\[\/event\-location\]/is",$s,$match)) - $ev['location'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-repeat\](.*?)\[\/event\-repeat\]/is",$s,$match)) - $ev['event_repeat'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-id\](.*?)\[\/event\-id\]/is",$s,$match)) - $ev['event_hash'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",$s,$match)) - $ev['adjust'] = $match[1]; - if(array_key_exists('dtstart',$ev)) { - if(array_key_exists('dtend',$ev)) { - if($ev['dtend'] === $ev['dtstart']) - $ev['nofinish'] = 1; - elseif($ev['dtend']) - $ev['nofinish'] = 0; - else - $ev['nofinish'] = 1; - } - else - $ev['nofinish'] = 1; - } + $match = ''; + if (preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is", $s, $match)) { + $ev['summary'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is", $s, $match)) { + $ev['description'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-start\](.*?)\[\/event\-start\]/is", $s, $match)) { + $ev['dtstart'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-finish\](.*?)\[\/event\-finish\]/is", $s, $match)) { + $ev['dtend'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-location\](.*?)\[\/event\-location\]/is", $s, $match)) { + $ev['location'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-repeat\](.*?)\[\/event\-repeat\]/is", $s, $match)) { + $ev['event_repeat'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-id\](.*?)\[\/event\-id\]/is", $s, $match)) { + $ev['event_hash'] = $match[1]; + } + $match = ''; + if (preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is", $s, $match)) { + $ev['adjust'] = $match[1]; + } + if (array_key_exists('dtstart', $ev)) { + if (array_key_exists('dtend', $ev)) { + if ($ev['dtend'] === $ev['dtstart']) { + $ev['nofinish'] = 1; + } elseif ($ev['dtend']) { + $ev['nofinish'] = 0; + } else { + $ev['nofinish'] = 1; + } + } else { + $ev['nofinish'] = 1; + } + } - if(preg_match("/\[event\-timezone\](.*?)\[\/event\-timezone\]/is",$s,$match)) { - $tz = $match[1]; - if (array_key_exists('dtstart',$ev)) { - $ev['dtstart'] = datetime_convert($tz,'UTC',$ev['dtstart']); - } - if (array_key_exists('dtend',$ev)) { - $ev['dtend'] = datetime_convert($tz,'UTC',$ev['dtend']); - } - } + if (preg_match("/\[event\-timezone\](.*?)\[\/event\-timezone\]/is", $s, $match)) { + $tz = $match[1]; + if (array_key_exists('dtstart', $ev)) { + $ev['dtstart'] = datetime_convert($tz, 'UTC', $ev['dtstart']); + } + if (array_key_exists('dtend', $ev)) { + $ev['dtend'] = datetime_convert($tz, 'UTC', $ev['dtend']); + } + } -// logger('bbtoevent: ' . print_r($ev,true)); +// logger('bbtoevent: ' . print_r($ev,true)); - return $ev; + return $ev; } /** @@ -365,11 +420,13 @@ function bbtoevent($s) { * @param array $arr * @return array Date sorted array of events */ -function sort_by_date($arr) { - if (is_array($arr)) - usort($arr, 'ev_compare'); +function sort_by_date($arr) +{ + if (is_array($arr)) { + usort($arr, 'ev_compare'); + } - return $arr; + return $arr; } /** @@ -382,93 +439,99 @@ function sort_by_date($arr) { * @param array $b * @return number return values like strcmp() */ -function ev_compare($a, $b) { +function ev_compare($a, $b) +{ - $date_a = (($a['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$a['dtstart']) : $a['dtstart']); - $date_b = (($b['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$b['dtstart']) : $b['dtstart']); + $date_a = (($a['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $a['dtstart']) : $a['dtstart']); + $date_b = (($b['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $b['dtstart']) : $b['dtstart']); - if ($date_a === $date_b) - return strcasecmp($a['description'], $b['description']); + if ($date_a === $date_b) { + return strcasecmp($a['description'], $b['description']); + } - return strcmp($date_a, $date_b); + return strcmp($date_a, $date_b); } -function event_store_event($arr) { +function event_store_event($arr) +{ - $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); - $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); - $arr['etype'] = (($arr['etype']) ? $arr['etype'] : 'event' ); - $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : ''); - $arr['event_priority'] = (($arr['event_priority']) ? $arr['event_priority'] : 0); + $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); + $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); + $arr['etype'] = (($arr['etype']) ? $arr['etype'] : 'event' ); + $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : ''); + $arr['event_priority'] = (($arr['event_priority']) ? $arr['event_priority'] : 0); - if (! $arr['dtend']) { - $arr['dtend'] = NULL_DATE; - $arr['nofinish'] = 1; - } + if (! $arr['dtend']) { + $arr['dtend'] = NULL_DATE; + $arr['nofinish'] = 1; + } - if(array_key_exists('event_status_date',$arr)) - $arr['event_status_date'] = datetime_convert('UTC','UTC', $arr['event_status_date']); - else - $arr['event_status_date'] = NULL_DATE; + if (array_key_exists('event_status_date', $arr)) { + $arr['event_status_date'] = datetime_convert('UTC', 'UTC', $arr['event_status_date']); + } else { + $arr['event_status_date'] = NULL_DATE; + } - $existing_event = null; + $existing_event = null; - if($arr['event_hash']) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", - dbesc($arr['event_hash']), - intval($arr['uid']) - ); - if($r) { - $existing_event = $r[0]; - } - } + if ($arr['event_hash']) { + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($arr['event_hash']), + intval($arr['uid']) + ); + if ($r) { + $existing_event = $r[0]; + } + } - if($arr['id']) { - $r = q("SELECT * FROM event WHERE id = %d AND uid = %d LIMIT 1", - intval($arr['id']), - intval($arr['uid']) - ); - if($r) { - $existing_event = $r[0]; - } - else { - return false; - } - } + if ($arr['id']) { + $r = q( + "SELECT * FROM event WHERE id = %d AND uid = %d LIMIT 1", + intval($arr['id']), + intval($arr['uid']) + ); + if ($r) { + $existing_event = $r[0]; + } else { + return false; + } + } - $hook_info = [ - 'event' => $arr, - 'existing_event' => $existing_event, - 'cancel' => false - ]; - /** - * @hooks event_store_event - * Called when an event record is created or updated. - * * \e array \b event - * * \e array \b existing_event - * * \e boolean \b cancel - default false - */ - call_hooks('event_store_event', $hook_info); - if($hook_info['cancel']) - return false; + $hook_info = [ + 'event' => $arr, + 'existing_event' => $existing_event, + 'cancel' => false + ]; + /** + * @hooks event_store_event + * Called when an event record is created or updated. + * * \e array \b event + * * \e array \b existing_event + * * \e boolean \b cancel - default false + */ + call_hooks('event_store_event', $hook_info); + if ($hook_info['cancel']) { + return false; + } - $arr = $hook_info['event']; - $existing_event = $hook_info['existing_event']; + $arr = $hook_info['event']; + $existing_event = $hook_info['existing_event']; - if($existing_event) { + if ($existing_event) { + if ($existing_event['edited'] >= $arr['edited']) { + // Nothing has changed. + return $existing_event; + } - if($existing_event['edited'] >= $arr['edited']) { - // Nothing has changed. - return $existing_event; - } + $hash = $existing_event['event_hash']; - $hash = $existing_event['event_hash']; + // The event changed. Update it. - // The event changed. Update it. - - $r = q("UPDATE event SET + $r = q( + "UPDATE event SET edited = '%s', dtstart = '%s', dtend = '%s', @@ -490,926 +553,997 @@ function event_store_event($arr) { deny_cid = '%s', deny_gid = '%s' WHERE id = %d AND uid = %d", + dbesc(datetime_convert('UTC', 'UTC', $arr['edited'])), + dbesc(datetime_convert('UTC', 'UTC', $arr['dtstart'])), + dbesc(datetime_convert('UTC', 'UTC', $arr['dtend'])), + dbesc($arr['summary']), + dbesc($arr['description']), + dbesc($arr['location']), + dbesc($arr['etype']), + intval($arr['adjust']), + intval($arr['nofinish']), + dbesc($arr['event_status']), + dbesc(datetime_convert('UTC', 'UTC', $arr['event_status_date'])), + intval($arr['event_percent']), + dbesc($arr['event_repeat']), + intval($arr['event_sequence']), + intval($arr['event_priority']), + dbesc($arr['event_vdata']), + dbesc($arr['allow_cid']), + dbesc($arr['allow_gid']), + dbesc($arr['deny_cid']), + dbesc($arr['deny_gid']), + intval($existing_event['id']), + intval($arr['uid']) + ); + } else { + // New event. Store it. - dbesc(datetime_convert('UTC','UTC',$arr['edited'])), - dbesc(datetime_convert('UTC','UTC',$arr['dtstart'])), - dbesc(datetime_convert('UTC','UTC',$arr['dtend'])), - dbesc($arr['summary']), - dbesc($arr['description']), - dbesc($arr['location']), - dbesc($arr['etype']), - intval($arr['adjust']), - intval($arr['nofinish']), - dbesc($arr['event_status']), - dbesc(datetime_convert('UTC','UTC',$arr['event_status_date'])), - intval($arr['event_percent']), - dbesc($arr['event_repeat']), - intval($arr['event_sequence']), - intval($arr['event_priority']), - dbesc($arr['event_vdata']), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']), - intval($existing_event['id']), - intval($arr['uid']) - ); - } else { + if (array_key_exists('external_id', $arr)) { + $hash = $arr['external_id']; + } elseif (array_key_exists('event_hash', $arr)) { + $hash = $arr['event_hash']; + } else { + try { + $hash = Uuid::uuid4()->toString(); + } catch (UnsatisfiedDependencyException $e) { + $hash = random_string(48); + } + } - // New event. Store it. - - if(array_key_exists('external_id',$arr)) - $hash = $arr['external_id']; - elseif(array_key_exists('event_hash',$arr)) - $hash = $arr['event_hash']; - else { - try { - $hash = Uuid::uuid4()->toString(); - } catch (UnsatisfiedDependencyException $e) { - $hash = random_string(48); - } - } - - $r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,dtstart,dtend,summary,description,location,etype, + $r = q( + "INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,dtstart,dtend,summary,description,location,etype, adjust,nofinish, event_status, event_status_date, event_percent, event_repeat, event_sequence, event_priority, event_vdata, allow_cid,allow_gid,deny_cid,deny_gid) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' ) ", - intval($arr['uid']), - intval($arr['account']), - dbesc($arr['event_xchan']), - dbesc($hash), - dbesc(datetime_convert('UTC','UTC',$arr['created'])), - dbesc(datetime_convert('UTC','UTC',$arr['edited'])), - dbesc(datetime_convert('UTC','UTC',$arr['dtstart'])), - dbesc(datetime_convert('UTC','UTC',$arr['dtend'])), - dbesc($arr['summary']), - dbesc($arr['description']), - dbesc($arr['location']), - dbesc($arr['etype']), - intval($arr['adjust']), - intval($arr['nofinish']), - dbesc($arr['event_status']), - dbesc(datetime_convert('UTC','UTC',$arr['event_status_date'])), - intval($arr['event_percent']), - dbesc($arr['event_repeat']), - intval($arr['event_sequence']), - intval($arr['event_priority']), - dbesc($arr['event_vdata']), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']) - ); - } + intval($arr['uid']), + intval($arr['account']), + dbesc($arr['event_xchan']), + dbesc($hash), + dbesc(datetime_convert('UTC', 'UTC', $arr['created'])), + dbesc(datetime_convert('UTC', 'UTC', $arr['edited'])), + dbesc(datetime_convert('UTC', 'UTC', $arr['dtstart'])), + dbesc(datetime_convert('UTC', 'UTC', $arr['dtend'])), + dbesc($arr['summary']), + dbesc($arr['description']), + dbesc($arr['location']), + dbesc($arr['etype']), + intval($arr['adjust']), + intval($arr['nofinish']), + dbesc($arr['event_status']), + dbesc(datetime_convert('UTC', 'UTC', $arr['event_status_date'])), + intval($arr['event_percent']), + dbesc($arr['event_repeat']), + intval($arr['event_sequence']), + intval($arr['event_priority']), + dbesc($arr['event_vdata']), + dbesc($arr['allow_cid']), + dbesc($arr['allow_gid']), + dbesc($arr['deny_cid']), + dbesc($arr['deny_gid']) + ); + } - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", - dbesc($hash), - intval($arr['uid']) - ); - if($r) - return $r[0]; + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($hash), + intval($arr['uid']) + ); + if ($r) { + return $r[0]; + } - return false; + return false; } -function event_addtocal($item_id, $uid) { +function event_addtocal($item_id, $uid) +{ - $c = q("select * from channel where channel_id = %d limit 1", - intval($uid) - ); + $c = q( + "select * from channel where channel_id = %d limit 1", + intval($uid) + ); - if(! $c) - return false; + if (! $c) { + return false; + } - $channel = $c[0]; + $channel = $c[0]; - $r = q("select * from item where id = %d and uid = %d limit 1", - intval($item_id), - intval($channel['channel_id']) - ); + $r = q( + "select * from item where id = %d and uid = %d limit 1", + intval($item_id), + intval($channel['channel_id']) + ); - if((! $r) || ($r[0]['obj_type'] !== ACTIVITY_OBJ_EVENT)) - return false; + if ((! $r) || ($r[0]['obj_type'] !== ACTIVITY_OBJ_EVENT)) { + return false; + } - $item = $r[0]; + $item = $r[0]; - $ev = bbtoevent($r[0]['body']); + $ev = bbtoevent($r[0]['body']); - if(x($ev,'summary') && x($ev,'dtstart')) { - $ev['event_xchan'] = $item['author_xchan']; - $ev['uid'] = $channel['channel_id']; - $ev['account'] = $channel['channel_account_id']; - $ev['edited'] = $item['edited']; - $ev['mid'] = $item['mid']; - $ev['private'] = $item['item_private']; + if (x($ev, 'summary') && x($ev, 'dtstart')) { + $ev['event_xchan'] = $item['author_xchan']; + $ev['uid'] = $channel['channel_id']; + $ev['account'] = $channel['channel_account_id']; + $ev['edited'] = $item['edited']; + $ev['mid'] = $item['mid']; + $ev['private'] = $item['item_private']; - // is this an edit? + // is this an edit? - if($item['resource_type'] === 'event' && (! $ev['event_hash'])) { - $ev['event_hash'] = $item['resource_id']; - } + if ($item['resource_type'] === 'event' && (! $ev['event_hash'])) { + $ev['event_hash'] = $item['resource_id']; + } - if($ev['private']) - $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; - else { - $acl = new AccessControl($channel); - $x = $acl->get(); - $ev['allow_cid'] = $x['allow_cid']; - $ev['allow_gid'] = $x['allow_gid']; - $ev['deny_cid'] = $x['deny_cid']; - $ev['deny_gid'] = $x['deny_gid']; - } + if ($ev['private']) { + $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + } else { + $acl = new AccessControl($channel); + $x = $acl->get(); + $ev['allow_cid'] = $x['allow_cid']; + $ev['allow_gid'] = $x['allow_gid']; + $ev['deny_cid'] = $x['deny_cid']; + $ev['deny_gid'] = $x['deny_gid']; + } - $event = event_store_event($ev); - if($event) { - $r = q("update item set resource_id = '%s', resource_type = 'event' where id = %d and uid = %d", - dbesc($event['event_hash']), - intval($item['id']), - intval($channel['channel_id']) - ); + $event = event_store_event($ev); + if ($event) { + $r = q( + "update item set resource_id = '%s', resource_type = 'event' where id = %d and uid = %d", + dbesc($event['event_hash']), + intval($item['id']), + intval($channel['channel_id']) + ); - $item['resource_id'] = $event['event_hash']; - $item['resource_type'] = 'event'; + $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) { - Libsync::build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); - } - return true; - } - } + $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) { + Libsync::build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)),'event' => $z)); + } + return true; + } + } - return false; + return false; } -function ical_to_ev($s) { - require_once('vendor/autoload.php'); +function ical_to_ev($s) +{ + require_once('vendor/autoload.php'); - $saved_timezone = date_default_timezone_get(); - date_default_timezone_set('Australia/Sydney'); + $saved_timezone = date_default_timezone_get(); + date_default_timezone_set('Australia/Sydney'); - $ical = VObject\Reader::read($s); + $ical = VObject\Reader::read($s); - $ev = []; + $ev = []; - if($ical) { - if($ical->VEVENT) { - foreach($ical->VEVENT as $event) { - $ev[] = parse_vobject($event,'event'); - } - } - if($ical->VTODO) { - foreach($ical->VTODO as $event) { - $ev[] = parse_vobject($event,'task'); - } - } - } + if ($ical) { + if ($ical->VEVENT) { + foreach ($ical->VEVENT as $event) { + $ev[] = parse_vobject($event, 'event'); + } + } + if ($ical->VTODO) { + foreach ($ical->VTODO as $event) { + $ev[] = parse_vobject($event, 'task'); + } + } + } - date_default_timezone_set($saved_timezone); + date_default_timezone_set($saved_timezone); - return $ev; + return $ev; } -function parse_vobject($ical, $type) { +function parse_vobject($ical, $type) +{ - $ev = []; + $ev = []; - if(! isset($ical->DTSTART)) { - logger('no event start'); - return $ev; - } + if (! isset($ical->DTSTART)) { + logger('no event start'); + return $ev; + } - $ev['etype'] = $type; + $ev['etype'] = $type; - $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); + $dtstart = $ical->DTSTART->getDateTime(); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); - $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtstart->format(DateTime::W3C)); + $ev['dtstart'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtstart->format(DateTime::W3C) + ); - if(isset($ical->DUE)) { - $dtend = $ical->DUE->getDateTime(); - $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtend->format(DateTime::W3C)); - } - elseif(isset($ical->DTEND)) { - $dtend = $ical->DTEND->getDateTime(); - $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtend->format(DateTime::W3C)); - } - else - $ev['nofinish'] = 1; + if (isset($ical->DUE)) { + $dtend = $ical->DUE->getDateTime(); + $ev['dtend'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtend->format(DateTime::W3C) + ); + } elseif (isset($ical->DTEND)) { + $dtend = $ical->DTEND->getDateTime(); + $ev['dtend'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtend->format(DateTime::W3C) + ); + } else { + $ev['nofinish'] = 1; + } - if($ev['dtstart'] === $ev['dtend']) - $ev['nofinish'] = 1; + if ($ev['dtstart'] === $ev['dtend']) { + $ev['nofinish'] = 1; + } - if(isset($ical->CREATED)) { - $created = $ical->CREATED->getDateTime(); - $ev['created'] = datetime_convert('UTC','UTC',$created->format(DateTime::W3C)); - } + if (isset($ical->CREATED)) { + $created = $ical->CREATED->getDateTime(); + $ev['created'] = datetime_convert('UTC', 'UTC', $created->format(DateTime::W3C)); + } - if(isset($ical->{'DTSTAMP'})) { - $edited = $ical->{'DTSTAMP'}->getDateTime(); - $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(DateTime::W3C)); - } - if(isset($ical->{'LAST-MODIFIED'})) { - $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); - $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(DateTime::W3C)); - } + if (isset($ical->{'DTSTAMP'})) { + $edited = $ical->{'DTSTAMP'}->getDateTime(); + $ev['edited'] = datetime_convert('UTC', 'UTC', $edited->format(DateTime::W3C)); + } + if (isset($ical->{'LAST-MODIFIED'})) { + $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); + $ev['edited'] = datetime_convert('UTC', 'UTC', $edited->format(DateTime::W3C)); + } - if(isset($ical->{'X-ZOT-LOCATION'})) - $ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'}); - elseif(isset($ical->LOCATION)) - $ev['location'] = (string) $ical->LOCATION; + if (isset($ical->{'X-ZOT-LOCATION'})) { + $ev['location'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-LOCATION'}); + } elseif (isset($ical->LOCATION)) { + $ev['location'] = (string) $ical->LOCATION; + } - if(isset($ical->{'X-ZOT-DESCRIPTION'})) - $ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'}); - elseif(isset($ical->DESCRIPTION)) - $ev['description'] = (string) $ical->DESCRIPTION; + if (isset($ical->{'X-ZOT-DESCRIPTION'})) { + $ev['description'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-DESCRIPTION'}); + } elseif (isset($ical->DESCRIPTION)) { + $ev['description'] = (string) $ical->DESCRIPTION; + } - if(isset($ical->{'X-ZOT-SUMMARY'})) - $ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'}); - elseif(isset($ical->SUMMARY)) - $ev['summary'] = (string) $ical->SUMMARY; + if (isset($ical->{'X-ZOT-SUMMARY'})) { + $ev['summary'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-SUMMARY'}); + } elseif (isset($ical->SUMMARY)) { + $ev['summary'] = (string) $ical->SUMMARY; + } - if(isset($ical->PRIORITY)) - $ev['event_priority'] = intval((string) $ical->PRIORITY); + if (isset($ical->PRIORITY)) { + $ev['event_priority'] = intval((string) $ical->PRIORITY); + } - if(isset($ical->UID)) { - $evuid = (string) $ical->UID; - $ev['event_hash'] = $evuid; - } + if (isset($ical->UID)) { + $evuid = (string) $ical->UID; + $ev['event_hash'] = $evuid; + } - if(isset($ical->SEQUENCE)) { - $ev['event_sequence'] = (string) $ical->SEQUENCE; - } + if (isset($ical->SEQUENCE)) { + $ev['event_sequence'] = (string) $ical->SEQUENCE; + } - if(isset($ical->STATUS)) { - $ev['event_status'] = (string) $ical->STATUS; - } + if (isset($ical->STATUS)) { + $ev['event_status'] = (string) $ical->STATUS; + } - if(isset($ical->{'COMPLETED'})) { - $completed = $ical->{'COMPLETED'}->getDateTime(); - $ev['event_status_date'] = datetime_convert('UTC','UTC',$completed->format(DateTime::W3C)); - } + if (isset($ical->{'COMPLETED'})) { + $completed = $ical->{'COMPLETED'}->getDateTime(); + $ev['event_status_date'] = datetime_convert('UTC', 'UTC', $completed->format(DateTime::W3C)); + } - if(isset($ical->{'PERCENT-COMPLETE'})) { - $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ; - } + if (isset($ical->{'PERCENT-COMPLETE'})) { + $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ; + } - $ev['event_vdata'] = $ical->serialize(); + $ev['event_vdata'] = $ical->serialize(); - return $ev; + return $ev; } -function parse_ical_file($f,$uid) { - require_once('vendor/autoload.php'); +function parse_ical_file($f, $uid) +{ + require_once('vendor/autoload.php'); - $s = @file_get_contents($f); + $s = @file_get_contents($f); - $ical = VObject\Reader::read($s); + $ical = VObject\Reader::read($s); - if($ical) { - if($ical->VEVENT) { - foreach($ical->VEVENT as $event) { - event_import_ical($event,$uid); - } - } - if($ical->VTODO) { - foreach($ical->VTODO as $event) { - event_import_ical_task($event,$uid); - } - } - } + if ($ical) { + if ($ical->VEVENT) { + foreach ($ical->VEVENT as $event) { + event_import_ical($event, $uid); + } + } + if ($ical->VTODO) { + foreach ($ical->VTODO as $event) { + event_import_ical_task($event, $uid); + } + } + } - if($ical) - return true; + if ($ical) { + return true; + } - return false; + return false; } -function event_import_ical($ical, $uid) { +function event_import_ical($ical, $uid) +{ - $c = q("select * from channel where channel_id = %d limit 1", - intval($uid) - ); + $c = q( + "select * from channel where channel_id = %d limit 1", + intval($uid) + ); - if(! $c) - return false; + if (! $c) { + return false; + } - $channel = $c[0]; - $ev = []; + $channel = $c[0]; + $ev = []; - if(! isset($ical->DTSTART)) { - logger('no event start'); - return false; - } + if (! isset($ical->DTSTART)) { + logger('no event start'); + return false; + } - $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); + $dtstart = $ical->DTSTART->getDateTime(); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); -// logger('dtstart: ' . var_export($dtstart,true)); +// logger('dtstart: ' . var_export($dtstart,true)); - $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtstart->format(DateTime::W3C)); + $ev['dtstart'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtstart->format(DateTime::W3C) + ); - if(isset($ical->DTEND)) { - $dtend = $ical->DTEND->getDateTime(); - $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtend->format(DateTime::W3C)); - } - else { - $ev['nofinish'] = 1; - } + if (isset($ical->DTEND)) { + $dtend = $ical->DTEND->getDateTime(); + $ev['dtend'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtend->format(DateTime::W3C) + ); + } else { + $ev['nofinish'] = 1; + } - if($ev['dtstart'] === $ev['dtend']) - $ev['nofinish'] = 1; + if ($ev['dtstart'] === $ev['dtend']) { + $ev['nofinish'] = 1; + } - if(isset($ical->CREATED)) { - $created = $ical->CREATED->getDateTime(); - $ev['created'] = datetime_convert('UTC','UTC',$created->format(DateTime::W3C)); - } + if (isset($ical->CREATED)) { + $created = $ical->CREATED->getDateTime(); + $ev['created'] = datetime_convert('UTC', 'UTC', $created->format(DateTime::W3C)); + } - if(isset($ical->{'LAST-MODIFIED'})) { - $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); - $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(DateTime::W3C)); - } + if (isset($ical->{'LAST-MODIFIED'})) { + $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); + $ev['edited'] = datetime_convert('UTC', 'UTC', $edited->format(DateTime::W3C)); + } - if(isset($ical->{'X-ZOT-LOCATION'})) - $ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'}); - elseif(isset($ical->LOCATION)) - $ev['location'] = (string) $ical->LOCATION; + if (isset($ical->{'X-ZOT-LOCATION'})) { + $ev['location'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-LOCATION'}); + } elseif (isset($ical->LOCATION)) { + $ev['location'] = (string) $ical->LOCATION; + } - if(isset($ical->{'X-ZOT-DESCRIPTION'})) - $ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'}); - elseif(isset($ical->DESCRIPTION)) - $ev['description'] = (string) $ical->DESCRIPTION; + if (isset($ical->{'X-ZOT-DESCRIPTION'})) { + $ev['description'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-DESCRIPTION'}); + } elseif (isset($ical->DESCRIPTION)) { + $ev['description'] = (string) $ical->DESCRIPTION; + } - if(isset($ical->{'X-ZOT-SUMMARY'})) - $ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'}); - elseif(isset($ical->SUMMARY)) - $ev['summary'] = (string) $ical->SUMMARY; + if (isset($ical->{'X-ZOT-SUMMARY'})) { + $ev['summary'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-SUMMARY'}); + } elseif (isset($ical->SUMMARY)) { + $ev['summary'] = (string) $ical->SUMMARY; + } - if(isset($ical->PRIORITY)) - $ev['event_priority'] = intval((string) $ical->PRIORITY); + if (isset($ical->PRIORITY)) { + $ev['event_priority'] = intval((string) $ical->PRIORITY); + } - if(isset($ical->UID)) { - $evuid = (string) $ical->UID; - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", - dbesc($evuid), - intval($uid) - ); - if($r) - $ev['event_hash'] = $evuid; - else - $ev['external_id'] = $evuid; - } + if (isset($ical->UID)) { + $evuid = (string) $ical->UID; + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($evuid), + intval($uid) + ); + if ($r) { + $ev['event_hash'] = $evuid; + } else { + $ev['external_id'] = $evuid; + } + } - if($ev['summary'] && $ev['dtstart']) { - $ev['event_xchan'] = $channel['channel_hash']; - $ev['uid'] = $channel['channel_id']; - $ev['account'] = $channel['channel_account_id']; - $ev['private'] = 1; - $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + if ($ev['summary'] && $ev['dtstart']) { + $ev['event_xchan'] = $channel['channel_hash']; + $ev['uid'] = $channel['channel_id']; + $ev['account'] = $channel['channel_account_id']; + $ev['private'] = 1; + $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; - logger('storing event: ' . print_r($ev,true), LOGGER_ALL); - $event = event_store_event($ev); - if($event) { - $item_id = event_store_item($ev,$event); - return true; - } - } + logger('storing event: ' . print_r($ev, true), LOGGER_ALL); + $event = event_store_event($ev); + if ($event) { + $item_id = event_store_item($ev, $event); + return true; + } + } - return false; + return false; } -function event_ical_get_sourcetext($s) { - return base64_decode($s); +function event_ical_get_sourcetext($s) +{ + return base64_decode($s); } -function event_import_ical_task($ical, $uid) { +function event_import_ical_task($ical, $uid) +{ - $c = q("select * from channel where channel_id = %d limit 1", - intval($uid) - ); + $c = q( + "select * from channel where channel_id = %d limit 1", + intval($uid) + ); - if(! $c) - return false; + if (! $c) { + return false; + } - $channel = $c[0]; - $ev = []; + $channel = $c[0]; + $ev = []; - if(! isset($ical->DTSTART)) { - logger('no event start'); - return false; - } + if (! isset($ical->DTSTART)) { + logger('no event start'); + return false; + } - $dtstart = $ical->DTSTART->getDateTime(); + $dtstart = $ical->DTSTART->getDateTime(); - $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1); -// logger('dtstart: ' . var_export($dtstart,true)); +// logger('dtstart: ' . var_export($dtstart,true)); - $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtstart->format(DateTime::W3C)); + $ev['dtstart'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtstart->format(DateTime::W3C) + ); - if(isset($ical->DUE)) { - $dtend = $ical->DUE->getDateTime(); - $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', - $dtend->format(DateTime::W3C)); - } - else - $ev['nofinish'] = 1; + if (isset($ical->DUE)) { + $dtend = $ical->DUE->getDateTime(); + $ev['dtend'] = datetime_convert( + (($ev['adjust']) ? 'UTC' : date_default_timezone_get()), + 'UTC', + $dtend->format(DateTime::W3C) + ); + } else { + $ev['nofinish'] = 1; + } - if($ev['dtstart'] === $ev['dtend']) - $ev['nofinish'] = 1; + if ($ev['dtstart'] === $ev['dtend']) { + $ev['nofinish'] = 1; + } - if(isset($ical->CREATED)) { - $created = $ical->CREATED->getDateTime(); - $ev['created'] = datetime_convert('UTC','UTC',$created->format(DateTime::W3C)); - } + if (isset($ical->CREATED)) { + $created = $ical->CREATED->getDateTime(); + $ev['created'] = datetime_convert('UTC', 'UTC', $created->format(DateTime::W3C)); + } - if(isset($ical->{'DTSTAMP'})) { - $edited = $ical->{'DTSTAMP'}->getDateTime(); - $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(DateTime::W3C)); - } + if (isset($ical->{'DTSTAMP'})) { + $edited = $ical->{'DTSTAMP'}->getDateTime(); + $ev['edited'] = datetime_convert('UTC', 'UTC', $edited->format(DateTime::W3C)); + } - if(isset($ical->{'LAST-MODIFIED'})) { - $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); - $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(DateTime::W3C)); - } + if (isset($ical->{'LAST-MODIFIED'})) { + $edited = $ical->{'LAST-MODIFIED'}->getDateTime(); + $ev['edited'] = datetime_convert('UTC', 'UTC', $edited->format(DateTime::W3C)); + } - if(isset($ical->{'X-ZOT-LOCATION'})) - $ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'}); - elseif(isset($ical->LOCATION)) - $ev['location'] = (string) $ical->LOCATION; + if (isset($ical->{'X-ZOT-LOCATION'})) { + $ev['location'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-LOCATION'}); + } elseif (isset($ical->LOCATION)) { + $ev['location'] = (string) $ical->LOCATION; + } - if(isset($ical->{'X-ZOT-DESCRIPTION'})) - $ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'}); - elseif(isset($ical->DESCRIPTION)) - $ev['description'] = (string) $ical->DESCRIPTION; + if (isset($ical->{'X-ZOT-DESCRIPTION'})) { + $ev['description'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-DESCRIPTION'}); + } elseif (isset($ical->DESCRIPTION)) { + $ev['description'] = (string) $ical->DESCRIPTION; + } - if(isset($ical->{'X-ZOT-SUMMARY'})) - $ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'}); - elseif(isset($ical->SUMMARY)) - $ev['summary'] = (string) $ical->SUMMARY; + if (isset($ical->{'X-ZOT-SUMMARY'})) { + $ev['summary'] = event_ical_get_sourcetext((string) $ical->{'X-ZOT-SUMMARY'}); + } elseif (isset($ical->SUMMARY)) { + $ev['summary'] = (string) $ical->SUMMARY; + } - if(isset($ical->PRIORITY)) - $ev['event_priority'] = intval((string) $ical->PRIORITY); + if (isset($ical->PRIORITY)) { + $ev['event_priority'] = intval((string) $ical->PRIORITY); + } - $stored_event = null; + $stored_event = null; - if(isset($ical->UID)) { - $evuid = (string) $ical->UID; - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", - dbesc($evuid), - intval($uid) - ); - if($r) { - $ev['event_hash'] = $evuid; - $stored_event = $r[0]; - } - else { - $ev['external_id'] = $evuid; - } - } + if (isset($ical->UID)) { + $evuid = (string) $ical->UID; + $r = q( + "SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($evuid), + intval($uid) + ); + if ($r) { + $ev['event_hash'] = $evuid; + $stored_event = $r[0]; + } else { + $ev['external_id'] = $evuid; + } + } - if(isset($ical->SEQUENCE)) { - $ev['event_sequence'] = (string) $ical->SEQUENCE; - // see if our stored event is more current than the one we're importing - if((intval($ev['event_sequence']) <= intval($stored_event['event_sequence'])) - && ($ev['edited'] <= $stored_event['edited'])) - return false; - } + if (isset($ical->SEQUENCE)) { + $ev['event_sequence'] = (string) $ical->SEQUENCE; + // see if our stored event is more current than the one we're importing + if ( + (intval($ev['event_sequence']) <= intval($stored_event['event_sequence'])) + && ($ev['edited'] <= $stored_event['edited']) + ) { + return false; + } + } - if(isset($ical->STATUS)) { - $ev['event_status'] = (string) $ical->STATUS; - } + if (isset($ical->STATUS)) { + $ev['event_status'] = (string) $ical->STATUS; + } - if(isset($ical->{'COMPLETED'})) { - $completed = $ical->{'COMPLETED'}->getDateTime(); - $ev['event_status_date'] = datetime_convert('UTC','UTC',$completed->format(DateTime::W3C)); - } + if (isset($ical->{'COMPLETED'})) { + $completed = $ical->{'COMPLETED'}->getDateTime(); + $ev['event_status_date'] = datetime_convert('UTC', 'UTC', $completed->format(DateTime::W3C)); + } - if(isset($ical->{'PERCENT-COMPLETE'})) { - $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ; - } + if (isset($ical->{'PERCENT-COMPLETE'})) { + $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ; + } - $ev['etype'] = 'task'; + $ev['etype'] = 'task'; - if($ev['summary'] && $ev['dtstart']) { - $ev['event_xchan'] = $channel['channel_hash']; - $ev['uid'] = $channel['channel_id']; - $ev['account'] = $channel['channel_account_id']; - $ev['private'] = 1; - $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + if ($ev['summary'] && $ev['dtstart']) { + $ev['event_xchan'] = $channel['channel_hash']; + $ev['uid'] = $channel['channel_id']; + $ev['account'] = $channel['channel_account_id']; + $ev['private'] = 1; + $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; - logger('storing event: ' . print_r($ev,true), LOGGER_ALL); - $event = event_store_event($ev); - if($event) { - $item_id = event_store_item($ev,$event); - return true; - } - } + logger('storing event: ' . print_r($ev, true), LOGGER_ALL); + $event = event_store_event($ev); + if ($event) { + $item_id = event_store_item($ev, $event); + return true; + } + } - return false; + return false; } -function event_store_item($arr, $event) { +function event_store_item($arr, $event) +{ - require_once('include/datetime.php'); - require_once('include/items.php'); + require_once('include/datetime.php'); + require_once('include/items.php'); - $item = null; + $item = null; - if($arr['mid'] && $arr['uid']) { - $i = q("select * from item where mid = '%s' and uid = %d limit 1", - dbesc($arr['mid']), - intval($arr['uid']) - ); - if($i) { - xchan_query($i); - $item = fetch_post_tags($i,true); - } - } + if ($arr['mid'] && $arr['uid']) { + $i = q( + "select * from item where mid = '%s' and uid = %d limit 1", + dbesc($arr['mid']), + intval($arr['uid']) + ); + if ($i) { + xchan_query($i); + $item = fetch_post_tags($i, true); + } + } - $item_arr = []; - $prefix = ''; -// $birthday = false; + $item_arr = []; + $prefix = ''; +// $birthday = false; - if(($event) && array_key_exists('event_hash',$event) && (! array_key_exists('event_hash',$arr))) - $arr['event_hash'] = $event['event_hash']; + if (($event) && array_key_exists('event_hash', $event) && (! array_key_exists('event_hash', $arr))) { + $arr['event_hash'] = $event['event_hash']; + } - if($event['etype'] === 'birthday') { - if(! is_sys_channel($arr['uid'])) - $prefix = t('This event has been added to your calendar.'); -// $birthday = true; + if ($event['etype'] === 'birthday') { + if (! is_sys_channel($arr['uid'])) { + $prefix = t('This event has been added to your calendar.'); + } +// $birthday = true; - // The event is created on your own site by the system, but appears to belong - // to the birthday person. It also isn't propagated - so we need to prevent - // folks from trying to comment on it. If you're looking at this and trying to - // fix it, you'll need to completely change the way birthday events are created - // and send them out from the source. This has its own issues. + // The event is created on your own site by the system, but appears to belong + // to the birthday person. It also isn't propagated - so we need to prevent + // folks from trying to comment on it. If you're looking at this and trying to + // fix it, you'll need to completely change the way birthday events are created + // and send them out from the source. This has its own issues. - $item_arr['comment_policy'] = 'none'; - } + $item_arr['comment_policy'] = 'none'; + } - $r = q("SELECT * FROM item left join xchan on author_xchan = xchan_hash WHERE resource_id = '%s' AND resource_type = 'event' and uid = %d LIMIT 1", - dbesc($event['event_hash']), - intval($arr['uid']) - ); + $r = q( + "SELECT * FROM item left join xchan on author_xchan = xchan_hash WHERE resource_id = '%s' AND resource_type = 'event' and uid = %d LIMIT 1", + dbesc($event['event_hash']), + intval($arr['uid']) + ); - if($r) { - $x = [ - 'type' => 'Event', - 'id' => z_root() . '/event/' . $r[0]['resource_id'], - 'name' => $arr['summary'], -// 'summary' => bbcode($arr['summary']), - // RFC3339 Section 4.3 - 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')), - 'content' => bbcode($arr['description']), - 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], - 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], - 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], - 'actor' => Activity::encode_person($r[0],false), - 'attachment' => Activity::encode_attachment($r[0]), - 'tag' => Activity::encode_taxonomy($r[0]) - ]; + if ($r) { + $x = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $r[0]['resource_id'], + 'name' => $arr['summary'], +// 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($r[0], false), + 'attachment' => Activity::encode_attachment($r[0]), + 'tag' => Activity::encode_taxonomy($r[0]) + ]; - if(! $arr['nofinish']) { - $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00')); - } - if($event['event_repeat']) { - $x['eventRepeat'] = $event['event_repeat']; - } - $object = json_encode($x); + if (! $arr['nofinish']) { + $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00')); + } + if ($event['event_repeat']) { + $x['eventRepeat'] = $event['event_repeat']; + } + $object = json_encode($x); - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); - /** - * @FIXME can only update sig if we have the author's channel on this site - * Until fixed, set it to nothing so it won't give us signature errors. - */ - $sig = ''; + /** + * @FIXME can only update sig if we have the author's channel on this site + * Until fixed, set it to nothing so it won't give us signature errors. + */ + $sig = ''; - q("UPDATE item SET title = '%s', body = '%s', obj = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", - dbesc($arr['summary']), - dbesc($prefix . format_event_bbcode($arr)), - dbesc($object), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']), - dbesc($arr['edited']), - dbesc($sig), - intval($r[0]['item_flags']), - intval($private), - dbesc(ACTIVITY_OBJ_EVENT), - intval($r[0]['id']), - intval($arr['uid']) - ); + q( + "UPDATE item SET title = '%s', body = '%s', obj = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", + dbesc($arr['summary']), + dbesc($prefix . format_event_bbcode($arr)), + dbesc($object), + dbesc($arr['allow_cid']), + dbesc($arr['allow_gid']), + dbesc($arr['deny_cid']), + dbesc($arr['deny_gid']), + dbesc($arr['edited']), + dbesc($sig), + intval($r[0]['item_flags']), + intval($private), + dbesc(ACTIVITY_OBJ_EVENT), + intval($r[0]['id']), + intval($arr['uid']) + ); - q("delete from term where oid = %d and otype = %d", - intval($r[0]['id']), - intval(TERM_OBJ_POST) - ); + q( + "delete from term where oid = %d and otype = %d", + intval($r[0]['id']), + intval(TERM_OBJ_POST) + ); - if(($arr['term']) && (is_array($arr['term']))) { - foreach($arr['term'] as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) + if (($arr['term']) && (is_array($arr['term']))) { + foreach ($arr['term'] as $t) { + q( + "insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", - intval($arr['uid']), - intval($r[0]['id']), - intval(TERM_OBJ_POST), - intval($t['ttype']), - dbesc($t['term']), - dbesc($t['url']) - ); - } - } + intval($arr['uid']), + intval($r[0]['id']), + intval(TERM_OBJ_POST), + intval($t['ttype']), + dbesc($t['term']), + dbesc($t['url']) + ); + } + } - $item_id = $r[0]['id']; - /** - * @hooks event_updated - * Called when an event record is modified. - */ - call_hooks('event_updated', $event['id']); + $item_id = $r[0]['id']; + /** + * @hooks event_updated + * Called when an event record is modified. + */ + call_hooks('event_updated', $event['id']); - return $item_id; - } - else { + return $item_id; + } else { + $z = channelx_by_n($arr['uid']); - $z = channelx_by_n($arr['uid']); + $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $item_wall = 0; + $item_origin = 0; + $item_thread_top = 0; - $item_wall = 0; - $item_origin = 0; - $item_thread_top = 0; + if ($item) { + $item_arr['id'] = $item['id']; + } else { + $wall = (($z['channel_hash'] == $event['event_xchan']) ? true : false); + $item_thread_top = 1; + if ($wall) { + $item_wall = 1; + $item_origin = 1; + } + } - if($item) { - $item_arr['id'] = $item['id']; - } - else { - $wall = (($z['channel_hash'] == $event['event_xchan']) ? true : false); - $item_thread_top = 1; - if($wall) { - $item_wall = 1; - $item_origin = 1; - } - } + if (! $arr['mid']) { + $arr['mid'] = z_root() . '/activity/' . $event['event_hash']; + } - if (! $arr['mid']) { - $arr['mid'] = z_root() . '/activity/' . $event['event_hash']; - } - - $item_arr['aid'] = $z['channel_account_id']; - $item_arr['uid'] = $arr['uid']; - $item_arr['author_xchan'] = $arr['event_xchan']; - $item_arr['mid'] = $arr['mid']; - $item_arr['parent_mid'] = $arr['mid']; - $item_arr['uuid'] = $event['event_hash']; - $item_arr['owner_xchan'] = (($wall) ? $z['channel_hash'] : $arr['event_xchan']); - $item_arr['author_xchan'] = $arr['event_xchan']; - $item_arr['summary'] = $arr['summary']; - $item_arr['allow_cid'] = $arr['allow_cid']; - $item_arr['allow_gid'] = $arr['allow_gid']; - $item_arr['deny_cid'] = $arr['deny_cid']; - $item_arr['deny_gid'] = $arr['deny_gid']; - $item_arr['item_private'] = $private; - $item_arr['verb'] = 'Invite'; - $item_arr['item_wall'] = $item_wall; - $item_arr['item_origin'] = $item_origin; - $item_arr['item_thread_top'] = $item_thread_top; + $item_arr['aid'] = $z['channel_account_id']; + $item_arr['uid'] = $arr['uid']; + $item_arr['author_xchan'] = $arr['event_xchan']; + $item_arr['mid'] = $arr['mid']; + $item_arr['parent_mid'] = $arr['mid']; + $item_arr['uuid'] = $event['event_hash']; + $item_arr['owner_xchan'] = (($wall) ? $z['channel_hash'] : $arr['event_xchan']); + $item_arr['author_xchan'] = $arr['event_xchan']; + $item_arr['summary'] = $arr['summary']; + $item_arr['allow_cid'] = $arr['allow_cid']; + $item_arr['allow_gid'] = $arr['allow_gid']; + $item_arr['deny_cid'] = $arr['deny_cid']; + $item_arr['deny_gid'] = $arr['deny_gid']; + $item_arr['item_private'] = $private; + $item_arr['verb'] = 'Invite'; + $item_arr['item_wall'] = $item_wall; + $item_arr['item_origin'] = $item_origin; + $item_arr['item_thread_top'] = $item_thread_top; - $attach = [ - [ - 'href' => z_root() . '/calendar/ical/' . urlencode($event['event_hash']), - 'length' => 0, - 'type' => 'text/calendar', - 'title' => t('event') . '-' . $event['event_hash'], - 'revision' => '' - ] - ]; + $attach = [ + [ + 'href' => z_root() . '/calendar/ical/' . urlencode($event['event_hash']), + 'length' => 0, + 'type' => 'text/calendar', + 'title' => t('event') . '-' . $event['event_hash'], + 'revision' => '' + ] + ]; - $item_arr['attach'] = $attach; + $item_arr['attach'] = $attach; - if(array_key_exists('term', $arr)) - $item_arr['term'] = $arr['term']; + if (array_key_exists('term', $arr)) { + $item_arr['term'] = $arr['term']; + } - $item_arr['resource_type'] = 'event'; - $item_arr['resource_id'] = $event['event_hash']; - $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT; - $item_arr['body'] = $prefix . format_event_bbcode($arr); + $item_arr['resource_type'] = 'event'; + $item_arr['resource_id'] = $event['event_hash']; + $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT; + $item_arr['body'] = $prefix . format_event_bbcode($arr); - // if it's local send the permalink to the channel page. - // otherwise we'll fallback to /display/$message_id + // if it's local send the permalink to the channel page. + // otherwise we'll fallback to /display/$message_id - if($wall) - $item_arr['plink'] = z_root() . '/channel/' . $z['channel_address'] . '/?f=&mid=' . gen_link_id($item_arr['mid']); - else - $item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']); + if ($wall) { + $item_arr['plink'] = z_root() . '/channel/' . $z['channel_address'] . '/?f=&mid=' . gen_link_id($item_arr['mid']); + } else { + $item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']); + } - $x = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($arr['event_xchan']) - ); - if($x) { - $y = [ - 'type' => 'Event', - 'id' => z_root() . '/event/' . $event['event_hash'], - 'name' => $arr['summary'], -// 'summary' => bbcode($arr['summary']), - // RFC3339 Section 4.3 - 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')), - 'content' => bbcode($arr['description']), - 'location' => [ 'type' => 'Place', 'content' => bbcode($arr['location']) ], - 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], - 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], - 'actor' => Activity::encode_person($z,false), - 'attachment' => Activity::encode_attachment($item_arr), - 'tag' => Activity::encode_taxonomy($item_arr) - ]; + $x = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($arr['event_xchan']) + ); + if ($x) { + $y = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $event['event_hash'], + 'name' => $arr['summary'], +// 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => bbcode($arr['location']) ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/bbcode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($z, false), + 'attachment' => Activity::encode_attachment($item_arr), + 'tag' => Activity::encode_taxonomy($item_arr) + ]; - if(! $arr['nofinish']) { - $y['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00')); - } - if($arr['event_repeat']) { - $y['eventRepeat'] = $arr['event_repeat']; - } + if (! $arr['nofinish']) { + $y['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00')); + } + if ($arr['event_repeat']) { + $y['eventRepeat'] = $arr['event_repeat']; + } - $item_arr['obj'] = json_encode($y); - } + $item_arr['obj'] = json_encode($y); + } - // propagate the event resource_id so that posts containing it are easily searchable in downstream copies - // of the item which have not stored the actual event. Required for Diaspora event federation as Diaspora - // event_participation messages refer to the event resource_id as a parent, while out own event attendance - // activities refer to the item message_id as the parent. + // propagate the event resource_id so that posts containing it are easily searchable in downstream copies + // of the item which have not stored the actual event. Required for Diaspora event federation as Diaspora + // event_participation messages refer to the event resource_id as a parent, while out own event attendance + // activities refer to the item message_id as the parent. - set_iconfig($item_arr, 'system','event_id',$event['event_hash'],true); + set_iconfig($item_arr, 'system', 'event_id', $event['event_hash'], true); - $res = item_store($item_arr); + $res = item_store($item_arr); - $item_id = $res['item_id']; + $item_id = $res['item_id']; - /** - * @hooks event_created - * Called when an event record is created. - */ - call_hooks('event_created', $event['id']); + /** + * @hooks event_created + * Called when an event record is created. + */ + call_hooks('event_created', $event['id']); - return $item_id; - } + return $item_id; + } } -function todo_stat() { - return array( - '' => t('Not specified'), - 'NEEDS-ACTION' => t('Needs Action'), - 'COMPLETED' => t('Completed'), - 'IN-PROCESS' => t('In Process'), - 'CANCELLED' => t('Cancelled') - ); +function todo_stat() +{ + return array( + '' => t('Not specified'), + 'NEEDS-ACTION' => t('Needs Action'), + 'COMPLETED' => t('Completed'), + 'IN-PROCESS' => t('In Process'), + 'CANCELLED' => t('Cancelled') + ); } -function tasks_fetch($arr) { +function tasks_fetch($arr) +{ - if(! local_channel()) - return; + if (! local_channel()) { + return; + } - $ret = []; - $sql_extra = " and event_status != 'COMPLETED' "; - if($arr && $arr['all'] == 1) - $sql_extra = ''; + $ret = []; + $sql_extra = " and event_status != 'COMPLETED' "; + if ($arr && $arr['all'] == 1) { + $sql_extra = ''; + } - $r = q("select * from event where etype = 'task' and uid = %d $sql_extra order by created desc", - intval(local_channel()) - ); + $r = q( + "select * from event where etype = 'task' and uid = %d $sql_extra order by created desc", + intval(local_channel()) + ); - $ret['success'] = (($r) ? true : false); - if($r) { - $ret['tasks'] = $r; - } + $ret['success'] = (($r) ? true : false); + if ($r) { + $ret['tasks'] = $r; + } - return $ret; + return $ret; } -function cdav_principal($uri) { - $r = q("SELECT uri FROM principals WHERE uri = '%s' LIMIT 1", - dbesc($uri) - ); +function cdav_principal($uri) +{ + $r = q( + "SELECT uri FROM principals WHERE uri = '%s' LIMIT 1", + dbesc($uri) + ); - if($r[0]['uri'] === $uri) - return true; - else - return false; + if ($r[0]['uri'] === $uri) { + return true; + } else { + return false; + } } -function cdav_perms($needle, $haystack, $check_rw = false) { +function cdav_perms($needle, $haystack, $check_rw = false) +{ - if ($needle === 'calendar') { - return true; - } - - foreach ($haystack as $item) { - if ($check_rw) { - if (is_array($item['id'])) { - if ($item['id'][0] == $needle && $item['share-access'] != 2) { - return $item['{DAV:}displayname']; - } - } - else { - if ($item['id'] == $needle && $item['share-access'] != 2) { - return $item['{DAV:}displayname']; - } - } - } - else { - if (is_array($item['id'])) { - if ($item['id'][0] == $needle) { - return $item['{DAV:}displayname']; - } - } - else { - if ($item['id'] == $needle) { - return $item['{DAV:}displayname']; - } - } - } - } - return false; + if ($needle === 'calendar') { + return true; + } + + foreach ($haystack as $item) { + if ($check_rw) { + if (is_array($item['id'])) { + if ($item['id'][0] == $needle && $item['share-access'] != 2) { + return $item['{DAV:}displayname']; + } + } else { + if ($item['id'] == $needle && $item['share-access'] != 2) { + return $item['{DAV:}displayname']; + } + } + } else { + if (is_array($item['id'])) { + if ($item['id'][0] == $needle) { + return $item['{DAV:}displayname']; + } + } else { + if ($item['id'] == $needle) { + return $item['{DAV:}displayname']; + } + } + } + } + return false; } -function translate_type($type) { +function translate_type($type) +{ - if(!$type) - return; + if (!$type) { + return; + } - $type = strtoupper($type); + $type = strtoupper($type); - $map = [ - 'CELL' => t('Mobile'), - 'HOME' => t('Home'), - 'HOME,VOICE' => t('Home, Voice'), - 'HOME,FAX' => t('Home, Fax'), - 'WORK' => t('Work'), - 'WORK,VOICE' => t('Work, Voice'), - 'WORK,FAX' => t('Work, Fax'), - 'OTHER' => t('Other') - ]; + $map = [ + 'CELL' => t('Mobile'), + 'HOME' => t('Home'), + 'HOME,VOICE' => t('Home, Voice'), + 'HOME,FAX' => t('Home, Fax'), + 'WORK' => t('Work'), + 'WORK,VOICE' => t('Work, Voice'), + 'WORK,FAX' => t('Work, Fax'), + 'OTHER' => t('Other') + ]; - if (array_key_exists($type, $map)) { - return [$type, $map[$type]]; - } - else { - return [$type, t('Other') . ' (' . $type . ')']; - } + if (array_key_exists($type, $map)) { + return [$type, $map[$type]]; + } else { + return [$type, t('Other') . ' (' . $type . ')']; + } } -function cal_store_lowlevel($arr) { +function cal_store_lowlevel($arr) +{ - $store = [ - 'cal_aid' => ((array_key_exists('cal_aid',$arr)) ? $arr['cal_aid'] : 0), - 'cal_uid' => ((array_key_exists('cal_uid',$arr)) ? $arr['cal_uid'] : 0), - 'cal_hash' => ((array_key_exists('cal_hash',$arr)) ? $arr['cal_hash'] : ''), - 'cal_name' => ((array_key_exists('cal_name',$arr)) ? $arr['cal_name'] : ''), - 'uri' => ((array_key_exists('uri',$arr)) ? $arr['uri'] : ''), - 'logname' => ((array_key_exists('logname',$arr)) ? $arr['logname'] : ''), - 'pass' => ((array_key_exists('pass',$arr)) ? $arr['pass'] : ''), - 'ctag' => ((array_key_exists('ctag',$arr)) ? $arr['ctag'] : ''), - 'synctoken' => ((array_key_exists('synctoken',$arr)) ? $arr['synctoken'] : ''), - 'cal_types' => ((array_key_exists('cal_types',$arr)) ? $arr['cal_types'] : ''), - ]; - - return create_table_from_array('cal', $store); + $store = [ + 'cal_aid' => ((array_key_exists('cal_aid', $arr)) ? $arr['cal_aid'] : 0), + 'cal_uid' => ((array_key_exists('cal_uid', $arr)) ? $arr['cal_uid'] : 0), + 'cal_hash' => ((array_key_exists('cal_hash', $arr)) ? $arr['cal_hash'] : ''), + 'cal_name' => ((array_key_exists('cal_name', $arr)) ? $arr['cal_name'] : ''), + 'uri' => ((array_key_exists('uri', $arr)) ? $arr['uri'] : ''), + 'logname' => ((array_key_exists('logname', $arr)) ? $arr['logname'] : ''), + 'pass' => ((array_key_exists('pass', $arr)) ? $arr['pass'] : ''), + 'ctag' => ((array_key_exists('ctag', $arr)) ? $arr['ctag'] : ''), + 'synctoken' => ((array_key_exists('synctoken', $arr)) ? $arr['synctoken'] : ''), + 'cal_types' => ((array_key_exists('cal_types', $arr)) ? $arr['cal_types'] : ''), + ]; + return create_table_from_array('cal', $store); } - - diff --git a/include/features.php b/include/features.php index 31ab84bf3..6514857d2 100644 --- a/include/features.php +++ b/include/features.php @@ -1,4 +1,6 @@ - $uid, 'feature' => $feature, 'enabled' => $x); - call_hooks('feature_enabled',$arr); - return($arr['enabled']); + $x = get_config('feature_lock', $feature); + if ($x === false) { + $x = get_pconfig($uid, 'feature', $feature); + if ($x === false) { + $x = get_config('feature', $feature); + if ($x === false) { + $x = get_feature_default($feature); + } + } + } + $arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x); + call_hooks('feature_enabled', $arr); + return($arr['enabled']); } -function get_feature_default($feature) { - $f = get_features(false); - foreach($f as $cat) { - foreach($cat as $feat) { - if(is_array($feat) && $feat[0] === $feature) { - return $feat[3]; - } - } - } - return false; +function get_feature_default($feature) +{ + $f = get_features(false); + foreach ($f as $cat) { + foreach ($cat as $feat) { + if (is_array($feat) && $feat[0] === $feature) { + return $feat[3]; + } + } + } + return false; } -function feature_level($feature,$def) { - $x = get_config('feature_level',$feature); - if($x !== false) - return intval($x); - return $def; +function feature_level($feature, $def) +{ + $x = get_config('feature_level', $feature); + if ($x !== false) { + return intval($x); + } + return $def; } -function get_features($filtered = true, $level = (-1)) { +function get_features($filtered = true, $level = (-1)) +{ - $account = App::get_account(); + $account = App::get_account(); - $arr = [ + $arr = [ - // General - 'general' => [ + // General + 'general' => [ - t('General Features'), + t('General Features'), - [ - 'start_menu', - t('New Member Links'), - t('Display new member quick links menu'), - (($account && $account['account_created'] > datetime_convert('','','now - 30 days')) ? true : false), - get_config('feature_lock','start_menu'), - feature_level('start_menu',1), - ], + [ + 'start_menu', + t('New Member Links'), + t('Display new member quick links menu'), + (($account && $account['account_created'] > datetime_convert('', '', 'now - 30 days')) ? true : false), + get_config('feature_lock', 'start_menu'), + feature_level('start_menu', 1), + ], - [ - 'advanced_profiles', - t('Advanced Profiles'), - t('Additional profile sections and selections'), - false, - get_config('feature_lock','advanced_profiles'), - feature_level('advanced_profiles',1), - ], + [ + 'advanced_profiles', + t('Advanced Profiles'), + t('Additional profile sections and selections'), + false, + get_config('feature_lock', 'advanced_profiles'), + feature_level('advanced_profiles', 1), + ], -// [ -// 'profile_export', -// t('Profile Import/Export'), -// t('Save and load profile details across sites/channels'), -// false, -// get_config('feature_lock','profile_export'), -// feature_level('profile_export',3), -// ], +// [ +// 'profile_export', +// t('Profile Import/Export'), +// t('Save and load profile details across sites/channels'), +// false, +// get_config('feature_lock','profile_export'), +// feature_level('profile_export',3), +// ], -// [ -// 'webpages', -// t('Web Pages'), -// t('Provide managed web pages on your channel'), -// false, -// get_config('feature_lock','webpages'), -// feature_level('webpages',3), -// ], +// [ +// 'webpages', +// t('Web Pages'), +// t('Provide managed web pages on your channel'), +// false, +// get_config('feature_lock','webpages'), +// feature_level('webpages',3), +// ], -// [ -// 'wiki', -// t('Wiki'), -// t('Provide a wiki for your channel'), -// false, -// get_config('feature_lock','wiki'), -// feature_level('wiki',2), -// ], +// [ +// 'wiki', +// t('Wiki'), +// t('Provide a wiki for your channel'), +// false, +// get_config('feature_lock','wiki'), +// feature_level('wiki',2), +// ], /* - [ - 'hide_rating', - t('Hide Rating'), - t('Hide the rating buttons on your channel and profile pages. Note: People can still rate you somewhere else.'), - false, - get_config('feature_lock','hide_rating'), - feature_level('hide_rating',3), - ], -*/ - [ - 'private_notes', - t('Private Notes'), - t('Enables a tool to store notes and reminders (note: not encrypted)'), - false, - get_config('feature_lock','private_notes'), - feature_level('private_notes',1), - ], + [ + 'hide_rating', + t('Hide Rating'), + t('Hide the rating buttons on your channel and profile pages. Note: People can still rate you somewhere else.'), + false, + get_config('feature_lock','hide_rating'), + feature_level('hide_rating',3), + ], +*/ + [ + 'private_notes', + t('Private Notes'), + t('Enables a tool to store notes and reminders (note: not encrypted)'), + false, + get_config('feature_lock', 'private_notes'), + feature_level('private_notes', 1), + ], -// [ -// 'cards', -// t('Cards'), -// t('Create personal planning cards'), -// false, -// get_config('feature_lock','cards'), -// feature_level('cards',1), -// ], +// [ +// 'cards', +// t('Cards'), +// t('Create personal planning cards'), +// false, +// get_config('feature_lock','cards'), +// feature_level('cards',1), +// ], - [ - 'articles', - t('Articles'), - t('Create interactive articles'), - false, - get_config('feature_lock','articles'), - feature_level('articles',1), - ], + [ + 'articles', + t('Articles'), + t('Create interactive articles'), + false, + get_config('feature_lock', 'articles'), + feature_level('articles', 1), + ], -// [ -// 'nav_channel_select', -// t('Navigation Channel Select'), -// t('Change channels directly from within the navigation dropdown menu'), -// false, -// get_config('feature_lock','nav_channel_select'), -// feature_level('nav_channel_select',3), -// ], +// [ +// 'nav_channel_select', +// t('Navigation Channel Select'), +// t('Change channels directly from within the navigation dropdown menu'), +// false, +// get_config('feature_lock','nav_channel_select'), +// feature_level('nav_channel_select',3), +// ], - [ - 'photo_location', - t('Photo Location'), - t('If location data is available on uploaded photos, link this to a map.'), - false, - get_config('feature_lock','photo_location'), - feature_level('photo_location',2), - ], + [ + 'photo_location', + t('Photo Location'), + t('If location data is available on uploaded photos, link this to a map.'), + false, + get_config('feature_lock', 'photo_location'), + feature_level('photo_location', 2), + ], -// [ -// 'ajaxchat', -// t('Access Controlled Chatrooms'), -// t('Provide chatrooms and chat services with access control.'), -// true, -// get_config('feature_lock','ajaxchat'), -// feature_level('ajaxchat',1), -// ], +// [ +// 'ajaxchat', +// t('Access Controlled Chatrooms'), +// t('Provide chatrooms and chat services with access control.'), +// true, +// get_config('feature_lock','ajaxchat'), +// feature_level('ajaxchat',1), +// ], -// [ -// 'smart_birthdays', -// t('Smart Birthdays'), -// t('Make birthday events timezone aware in case your friends are scattered across the planet.'), -// true, -// get_config('feature_lock','smart_birthdays'), -// feature_level('smart_birthdays',2), -// ], +// [ +// 'smart_birthdays', +// t('Smart Birthdays'), +// t('Make birthday events timezone aware in case your friends are scattered across the planet.'), +// true, +// get_config('feature_lock','smart_birthdays'), +// feature_level('smart_birthdays',2), +// ], - [ - 'event_tz_select', - t('Event Timezone Selection'), - t('Allow event creation in timezones other than your own.'), - false, - get_config('feature_lock','event_tz_select'), - feature_level('event_tz_select',2), - ], + [ + 'event_tz_select', + t('Event Timezone Selection'), + t('Allow event creation in timezones other than your own.'), + false, + get_config('feature_lock', 'event_tz_select'), + feature_level('event_tz_select', 2), + ], -// [ -// 'premium_channel', -// t('Premium Channel'), -// t('Allows you to set restrictions and terms on those that connect with your channel'), -// false, -// get_config('feature_lock','premium_channel'), -// feature_level('premium_channel',4), -// ], +// [ +// 'premium_channel', +// t('Premium Channel'), +// t('Allows you to set restrictions and terms on those that connect with your channel'), +// false, +// get_config('feature_lock','premium_channel'), +// feature_level('premium_channel',4), +// ], - [ - 'advanced_dirsearch', - t('Advanced Directory Search'), - t('Allows creation of complex directory search queries'), - false, - get_config('feature_lock','advanced_dirsearch'), - feature_level('advanced_dirsearch',4), - ], + [ + 'advanced_dirsearch', + t('Advanced Directory Search'), + t('Allows creation of complex directory search queries'), + false, + get_config('feature_lock', 'advanced_dirsearch'), + feature_level('advanced_dirsearch', 4), + ], - [ - 'advanced_theming', - t('Advanced Theme and Layout Settings'), - t('Allows fine tuning of themes and page layouts'), - false, - get_config('feature_lock','advanced_theming'), - feature_level('advanced_theming',4), - ], - ], + [ + 'advanced_theming', + t('Advanced Theme and Layout Settings'), + t('Allows fine tuning of themes and page layouts'), + false, + get_config('feature_lock', 'advanced_theming'), + feature_level('advanced_theming', 4), + ], + ], - 'access_control' => [ - t('Access Control and Permissions'), + 'access_control' => [ + t('Access Control and Permissions'), - [ - 'groups', - t('Privacy Groups'), - t('Enable management and selection of privacy groups'), - false, - get_config('feature_lock','groups'), - feature_level('groups',0), - ], + [ + 'groups', + t('Privacy Groups'), + t('Enable management and selection of privacy groups'), + false, + get_config('feature_lock', 'groups'), + feature_level('groups', 0), + ], -// [ -// 'multi_profiles', -// t('Multiple Profiles'), -// t('Ability to create multiple profiles'), -// false, -// get_config('feature_lock','multi_profiles'), -// feature_level('multi_profiles',3), -// ], +// [ +// 'multi_profiles', +// t('Multiple Profiles'), +// t('Ability to create multiple profiles'), +// false, +// get_config('feature_lock','multi_profiles'), +// feature_level('multi_profiles',3), +// ], -// [ -// 'permcats', -// t('Permission Categories'), -// t('Create custom connection permission limits'), -// false, -// get_config('feature_lock','permcats'), -// feature_level('permcats',2), -// ], +// [ +// 'permcats', +// t('Permission Categories'), +// t('Create custom connection permission limits'), +// false, +// get_config('feature_lock','permcats'), +// feature_level('permcats',2), +// ], -// [ -// 'oauth_clients', -// t('OAuth1 Clients'), -// t('Manage OAuth1 authenticatication tokens for mobile and remote apps.'), -// false, -// get_config('feature_lock','oauth_clients'), -// feature_level('oauth_clients',1), -// ], +// [ +// 'oauth_clients', +// t('OAuth1 Clients'), +// t('Manage OAuth1 authenticatication tokens for mobile and remote apps.'), +// false, +// get_config('feature_lock','oauth_clients'), +// feature_level('oauth_clients',1), +// ], - [ - 'oauth2_clients', - t('OAuth2 Clients'), - t('Manage OAuth2 authenticatication tokens for mobile and remote apps.'), - false, - get_config('feature_lock','oauth2_clients'), - feature_level('oauth2_clients',1), - ], + [ + 'oauth2_clients', + t('OAuth2 Clients'), + t('Manage OAuth2 authenticatication tokens for mobile and remote apps.'), + false, + get_config('feature_lock', 'oauth2_clients'), + feature_level('oauth2_clients', 1), + ], -// [ -// 'access_tokens', -// t('Access Tokens'), -// t('Create access tokens so that non-members can access private content.'), -// false, -// get_config('feature_lock','access_tokens'), -// feature_level('access_tokens',2), -// ], +// [ +// 'access_tokens', +// t('Access Tokens'), +// t('Create access tokens so that non-members can access private content.'), +// false, +// get_config('feature_lock','access_tokens'), +// feature_level('access_tokens',2), +// ], - ], + ], - // Post composition - 'composition' => [ + // Post composition + 'composition' => [ - t('Post Composition Features'), + t('Post Composition Features'), -// [ -// 'large_photos', -// t('Large Photos'), -// t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'), -// false, -// get_config('feature_lock','large_photos'), -// feature_level('large_photos',1), -// ], +// [ +// 'large_photos', +// t('Large Photos'), +// t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'), +// false, +// get_config('feature_lock','large_photos'), +// feature_level('large_photos',1), +// ], -// [ -// 'channel_sources', -// t('Channel Sources'), -// t('Automatically import channel content from other channels or feeds'), -// false, -// get_config('feature_lock','channel_sources'), -// feature_level('channel_sources',3), -// ], - - [ - 'content_encrypt', - t('Browser Encryption'), - t('Provide optional browser-to-browser encryption of content with a shared secret key'), - true, - get_config('feature_lock','content_encrypt'), - feature_level('content_encrypt',3), - ], - -// [ -// 'consensus_tools', -// t('Enable Voting Tools'), -// t('Provide a class of post which others can vote on'), -// false, -// get_config('feature_lock','consensus_tools'), -// feature_level('consensus_tools',3), -// ], +// [ +// 'channel_sources', +// t('Channel Sources'), +// t('Automatically import channel content from other channels or feeds'), +// false, +// get_config('feature_lock','channel_sources'), +// feature_level('channel_sources',3), +// ], -// [ -// 'disable_comments', -// t('Disable Comments'), -// t('Provide the option to disable comments for a post'), -// false, -// get_config('feature_lock','disable_comments'), -// feature_level('disable_comments',2), -// ], + [ + 'content_encrypt', + t('Browser Encryption'), + t('Provide optional browser-to-browser encryption of content with a shared secret key'), + true, + get_config('feature_lock', 'content_encrypt'), + feature_level('content_encrypt', 3), + ], -// [ -// 'delayed_posting', -// t('Delayed Posting'), -// t('Allow posts to be published at a later date'), -// false, -// get_config('feature_lock','delayed_posting'), -// feature_level('delayed_posting',2), -// ], +// [ +// 'consensus_tools', +// t('Enable Voting Tools'), +// t('Provide a class of post which others can vote on'), +// false, +// get_config('feature_lock','consensus_tools'), +// feature_level('consensus_tools',3), +// ], -// [ -// 'content_expire', -// t('Content Expiration'), -// t('Remove posts/comments and/or private messages at a future time'), -// false, -// get_config('feature_lock','content_expire'), -// feature_level('content_expire',1), -// ], +// [ +// 'disable_comments', +// t('Disable Comments'), +// t('Provide the option to disable comments for a post'), +// false, +// get_config('feature_lock','disable_comments'), +// feature_level('disable_comments',2), +// ], - [ - 'suppress_duplicates', - t('Suppress Duplicate Posts/Comments'), - t('Prevent posts with identical content to be published with less than two minutes in between submissions.'), - true, - get_config('feature_lock','suppress_duplicates'), - feature_level('suppress_duplicates',1), - ], +// [ +// 'delayed_posting', +// t('Delayed Posting'), +// t('Allow posts to be published at a later date'), +// false, +// get_config('feature_lock','delayed_posting'), +// feature_level('delayed_posting',2), +// ], - [ - 'auto_save_draft', - t('Auto-save drafts of posts and comments'), - t('Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions'), - true, - get_config('feature_lock','auto_save_draft'), - feature_level('auto_save_draft',1), - ], +// [ +// 'content_expire', +// t('Content Expiration'), +// t('Remove posts/comments and/or private messages at a future time'), +// false, +// get_config('feature_lock','content_expire'), +// feature_level('content_expire',1), +// ], - ], + [ + 'suppress_duplicates', + t('Suppress Duplicate Posts/Comments'), + t('Prevent posts with identical content to be published with less than two minutes in between submissions.'), + true, + get_config('feature_lock', 'suppress_duplicates'), + feature_level('suppress_duplicates', 1), + ], - // Network Tools - 'net_module' => [ + [ + 'auto_save_draft', + t('Auto-save drafts of posts and comments'), + t('Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions'), + true, + get_config('feature_lock', 'auto_save_draft'), + feature_level('auto_save_draft', 1), + ], - t('Network and Stream Filtering'), + ], - [ - 'archives', - t('Search by Date'), - t('Ability to select posts by date ranges'), - false, - get_config('feature_lock','archives'), - feature_level('archives',1), - ], + // Network Tools + 'net_module' => [ + + t('Network and Stream Filtering'), + + [ + 'archives', + t('Search by Date'), + t('Ability to select posts by date ranges'), + false, + get_config('feature_lock', 'archives'), + feature_level('archives', 1), + ], - [ - 'savedsearch', - t('Saved Searches'), - t('Save search terms for re-use'), - false, - get_config('feature_lock','savedsearch'), - feature_level('savedsearch',2), - ], + [ + 'savedsearch', + t('Saved Searches'), + t('Save search terms for re-use'), + false, + get_config('feature_lock', 'savedsearch'), + feature_level('savedsearch', 2), + ], - [ - 'order_tab', - t('Alternate Stream Order'), - t('Ability to order the stream by last post date, last comment date or unthreaded activities'), - false, - get_config('feature_lock','order_tab'), - feature_level('order_tab',2), - ], + [ + 'order_tab', + t('Alternate Stream Order'), + t('Ability to order the stream by last post date, last comment date or unthreaded activities'), + false, + get_config('feature_lock', 'order_tab'), + feature_level('order_tab', 2), + ], - [ - 'name_tab', - t('Contact Filter'), - t('Ability to display only posts of a selected contact'), - false, - get_config('feature_lock','name_tab'), - feature_level('name_tab',1), - ], + [ + 'name_tab', + t('Contact Filter'), + t('Ability to display only posts of a selected contact'), + false, + get_config('feature_lock', 'name_tab'), + feature_level('name_tab', 1), + ], - [ - 'forums_tab', - t('Forum Filter'), - t('Ability to display only posts of a specific forum'), - false, - get_config('feature_lock','forums_tab'), - feature_level('forums_tab',1), - ], + [ + 'forums_tab', + t('Forum Filter'), + t('Ability to display only posts of a specific forum'), + false, + get_config('feature_lock', 'forums_tab'), + feature_level('forums_tab', 1), + ], - [ - 'personal_tab', - t('Personal Posts Filter'), - t('Ability to display only posts that you\'ve interacted on'), - false, - get_config('feature_lock','personal_tab'), - feature_level('personal_tab',1), - ], + [ + 'personal_tab', + t('Personal Posts Filter'), + t('Ability to display only posts that you\'ve interacted on'), + false, + get_config('feature_lock', 'personal_tab'), + feature_level('personal_tab', 1), + ], - [ - 'affinity', - t('Affinity Tool'), - t('Filter stream activity by depth of relationships'), - false, - get_config('feature_lock','affinity'), - feature_level('affinity',1), - ], + [ + 'affinity', + t('Affinity Tool'), + t('Filter stream activity by depth of relationships'), + false, + get_config('feature_lock', 'affinity'), + feature_level('affinity', 1), + ], - [ - 'suggest', - t('Suggest Channels'), - t('Show friend and connection suggestions'), - false, - get_config('feature_lock','suggest'), - feature_level('suggest',1), - ], + [ + 'suggest', + t('Suggest Channels'), + t('Show friend and connection suggestions'), + false, + get_config('feature_lock', 'suggest'), + feature_level('suggest', 1), + ], - [ - 'connfilter', - t('Connection Filtering'), - t('Filter incoming posts from connections based on keywords/content'), - false, - get_config('feature_lock','connfilter'), - feature_level('connfilter',3), - ], + [ + 'connfilter', + t('Connection Filtering'), + t('Filter incoming posts from connections based on keywords/content'), + false, + get_config('feature_lock', 'connfilter'), + feature_level('connfilter', 3), + ], - ], + ], - // Item tools - 'tools' => [ + // Item tools + 'tools' => [ - t('Post/Comment Tools'), + t('Post/Comment Tools'), - [ - 'commtag', - t('Community Tagging'), - t('Ability to tag existing posts'), - false, - get_config('feature_lock','commtag'), - feature_level('commtag',1), - ], + [ + 'commtag', + t('Community Tagging'), + t('Ability to tag existing posts'), + false, + get_config('feature_lock', 'commtag'), + feature_level('commtag', 1), + ], - [ - 'categories', - t('Post Categories'), - t('Add categories to your posts'), - false, - get_config('feature_lock','categories'), - feature_level('categories',1), - ], + [ + 'categories', + t('Post Categories'), + t('Add categories to your posts'), + false, + get_config('feature_lock', 'categories'), + feature_level('categories', 1), + ], - [ - 'emojis', - t('Emoji Reactions'), - t('Add emoji reaction ability to posts'), - true, - get_config('feature_lock','emojis'), - feature_level('emojis',1), - ], + [ + 'emojis', + t('Emoji Reactions'), + t('Add emoji reaction ability to posts'), + true, + get_config('feature_lock', 'emojis'), + feature_level('emojis', 1), + ], - [ - 'filing', - t('Saved Folders'), - t('Ability to file posts under folders'), - false, - get_config('feature_lock','filing'), - feature_level('filing',2), - ], + [ + 'filing', + t('Saved Folders'), + t('Ability to file posts under folders'), + false, + get_config('feature_lock', 'filing'), + feature_level('filing', 2), + ], - [ - 'dislike', - t('Dislike Posts'), - t('Ability to dislike posts/comments'), - false, - get_config('feature_lock','dislike'), - feature_level('dislike',1), - ], + [ + 'dislike', + t('Dislike Posts'), + t('Ability to dislike posts/comments'), + false, + get_config('feature_lock', 'dislike'), + feature_level('dislike', 1), + ], -// [ -// 'star_posts', -// t('Star Posts'), -// t('Ability to mark special posts with a star indicator'), -// false, -// get_config('feature_lock','star_posts'), -// feature_level('star_posts',1), -// ], +// [ +// 'star_posts', +// t('Star Posts'), +// t('Ability to mark special posts with a star indicator'), +// false, +// get_config('feature_lock','star_posts'), +// feature_level('star_posts',1), +// ], // - [ - 'tagadelic', - t('Tag Cloud'), - t('Provide a personal tag cloud on your channel page'), - false, - get_config('feature_lock','tagadelic'), - feature_level('tagadelic',2), - ], - ], - ]; + [ + 'tagadelic', + t('Tag Cloud'), + t('Provide a personal tag cloud on your channel page'), + false, + get_config('feature_lock', 'tagadelic'), + feature_level('tagadelic', 2), + ], + ], + ]; - $x = [ 'features' => $arr, ]; - call_hooks('get_features',$x); + $x = [ 'features' => $arr, ]; + call_hooks('get_features', $x); - $arr = $x['features']; + $arr = $x['features']; - // removed any locked features and remove the entire category if this makes it empty + // removed any locked features and remove the entire category if this makes it empty - if($filtered) { - $narr = []; - foreach($arr as $k => $x) { - $narr[$k] = [ $arr[$k][0] ]; - $has_items = false; - for($y = 0; $y < count($arr[$k]); $y ++) { - $disabled = false; - if(is_array($arr[$k][$y])) { - if($arr[$k][$y][4] !== false) { - $disabled = true; - } - if(! $disabled) { - $has_items = true; - $narr[$k][$y] = $arr[$k][$y]; - } - } - } - if(! $has_items) { - unset($narr[$k]); - } - } - } - else { - $narr = $arr; - } + if ($filtered) { + $narr = []; + foreach ($arr as $k => $x) { + $narr[$k] = [ $arr[$k][0] ]; + $has_items = false; + for ($y = 0; $y < count($arr[$k]); $y++) { + $disabled = false; + if (is_array($arr[$k][$y])) { + if ($arr[$k][$y][4] !== false) { + $disabled = true; + } + if (! $disabled) { + $has_items = true; + $narr[$k][$y] = $arr[$k][$y]; + } + } + } + if (! $has_items) { + unset($narr[$k]); + } + } + } else { + $narr = $arr; + } - return $narr; + return $narr; } diff --git a/include/feedutils.php b/include/feedutils.php index f0e7bf243..31bdc95bb 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1,4 +1,5 @@ xmlify(Zotlabs\Lib\System::get_project_version()), - '$generator' => xmlify(Zotlabs\Lib\System::get_platform_name()), - '$generator_uri' => 'https://codeberg.org/zot/' . PLATFORM_NAME, - '$feed_id' => xmlify($channel['xchan_url']), - '$feed_title' => xmlify($channel['channel_name']), - '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), - '$author' => $feed_author, - '$owner' => $owner, - '$profile_page' => xmlify($channel['xchan_url']), - )); + $atom .= replace_macros($feed_template, array( + '$version' => xmlify(Zotlabs\Lib\System::get_project_version()), + '$generator' => xmlify(Zotlabs\Lib\System::get_platform_name()), + '$generator_uri' => 'https://codeberg.org/zot/' . PLATFORM_NAME, + '$feed_id' => xmlify($channel['xchan_url']), + '$feed_title' => xmlify($channel['channel_name']), + '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), + '$author' => $feed_author, + '$owner' => $owner, + '$profile_page' => xmlify($channel['xchan_url']), + )); - $x = [ - 'xml' => $atom, - 'channel' => $channel, - 'observer_hash' => $observer_hash, - 'params' => $params - ]; - /** - * @hooks atom_feed_top - * * \e string \b xml - the generated feed and what will get returned from the hook - * * \e array \b channel - * * \e string \b observer_hash - * * \e array \b params - */ - call_hooks('atom_feed_top', $x); + $x = [ + 'xml' => $atom, + 'channel' => $channel, + 'observer_hash' => $observer_hash, + 'params' => $params + ]; + /** + * @hooks atom_feed_top + * * \e string \b xml - the generated feed and what will get returned from the hook + * * \e array \b channel + * * \e string \b observer_hash + * * \e array \b params + */ + call_hooks('atom_feed_top', $x); - $atom = $x['xml']; + $atom = $x['xml']; - /** - * @hooks atom_feed - * A much simpler interface than atom_feed_top. - * * \e string - the feed after atom_feed_top hook - */ - call_hooks('atom_feed', $atom); + /** + * @hooks atom_feed + * A much simpler interface than atom_feed_top. + * * \e string - the feed after atom_feed_top hook + */ + call_hooks('atom_feed', $atom); - $items = items_fetch( - [ - 'wall' => '1', - 'datequery' => $params['end'], - 'datequery2' => $params['begin'], - 'start' => intval($params['start']), - 'records' => intval($params['records']), - 'direction' => dbesc($params['direction']), - 'pages' => $params['pages'], - 'order' => dbesc('post'), - 'top' => $params['top'], - 'cat' => $params['cat'], - 'compat' => $params['compat'] - ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module - ); + $items = items_fetch( + [ + 'wall' => '1', + 'datequery' => $params['end'], + 'datequery2' => $params['begin'], + 'start' => intval($params['start']), + 'records' => intval($params['records']), + 'direction' => dbesc($params['direction']), + 'pages' => $params['pages'], + 'order' => dbesc('post'), + 'top' => $params['top'], + 'cat' => $params['cat'], + 'compat' => $params['compat'] + ], + $channel, + $observer_hash, + CLIENT_MODE_NORMAL, + App::$module + ); - if($items) { - $type = 'html'; - foreach($items as $item) { - if($item['item_private']) - continue; + if ($items) { + $type = 'html'; + foreach ($items as $item) { + if ($item['item_private']) { + continue; + } - $atom .= atom_entry($item, $type, null, $owner, true, '', $params['compat']); - } - } + $atom .= atom_entry($item, $type, null, $owner, true, '', $params['compat']); + } + } - /** - * @hooks atom_feed_end - * \e string - The created XML feed as a string without closing tag - */ - call_hooks('atom_feed_end', $atom); + /** + * @hooks atom_feed_end + * \e string - The created XML feed as a string without closing tag + */ + call_hooks('atom_feed_end', $atom); - $atom .= '' . "\r\n"; + $atom .= '' . "\r\n"; - return $atom; + return $atom; } /** @@ -180,34 +187,36 @@ function get_feed_for($channel, $observer_hash, $params) { * @param string $photo Fully qualified URL to a profile/avator photo * @return string XML tag */ -function atom_author($tag, $nick, $name, $uri, $h, $w, $type, $photo) { - $o = ''; - if(! $tag) - return $o; +function atom_author($tag, $nick, $name, $uri, $h, $w, $type, $photo) +{ + $o = ''; + if (! $tag) { + return $o; + } - $nick = xmlify($nick); - $name = xmlify($name); - $uri = xmlify($uri); - $h = intval($h); - $w = intval($w); - $photo = xmlify($photo); + $nick = xmlify($nick); + $name = xmlify($name); + $uri = xmlify($uri); + $h = intval($h); + $w = intval($w); + $photo = xmlify($photo); - $o .= "<$tag>\r\n"; - $o .= " $name\r\n"; - $o .= " $uri\r\n"; - $o .= ' ' . "\r\n"; - $o .= ' ' . "\r\n"; + $o .= "<$tag>\r\n"; + $o .= " $name\r\n"; + $o .= " $uri\r\n"; + $o .= ' ' . "\r\n"; + $o .= ' ' . "\r\n"; - /** - * @hooks atom_author - * Possibility to add further tags to returned XML string - * * \e string - The created XML tag as a string without closing tag - */ - call_hooks('atom_author', $o); + /** + * @hooks atom_author + * Possibility to add further tags to returned XML string + * * \e string - The created XML tag as a string without closing tag + */ + call_hooks('atom_author', $o); - $o .= "\r\n"; + $o .= "\r\n"; - return $o; + return $o; } @@ -218,56 +227,58 @@ function atom_author($tag, $nick, $name, $uri, $h, $w, $type, $photo) { * @param array $xchan * @return string */ -function atom_render_author($tag, $xchan) { +function atom_render_author($tag, $xchan) +{ - $nick = xmlify(substr($xchan['xchan_addr'], 0, strpos($xchan['xchan_addr'], '@'))); - $id = xmlify($xchan['xchan_url']); - $name = xmlify($xchan['xchan_name']); - $photo = xmlify($xchan['xchan_photo_l']); - $type = xmlify($xchan['xchan_photo_mimetype']); - $w = $h = 300; + $nick = xmlify(substr($xchan['xchan_addr'], 0, strpos($xchan['xchan_addr'], '@'))); + $id = xmlify($xchan['xchan_url']); + $name = xmlify($xchan['xchan_name']); + $photo = xmlify($xchan['xchan_photo_l']); + $type = xmlify($xchan['xchan_photo_mimetype']); + $w = $h = 300; - $o = "<$tag>\r\n"; - $o .= " $name\r\n"; - $o .= " $id\r\n"; - $o .= ' ' . "\r\n"; - $o .= ' ' . "\r\n"; + $o = "<$tag>\r\n"; + $o .= " $name\r\n"; + $o .= " $id\r\n"; + $o .= ' ' . "\r\n"; + $o .= ' ' . "\r\n"; - /** - * @hooks atom_render_author - * Possibility to add further tags to returned XML string. - * * \e string The created XML tag as a string without closing tag - */ - call_hooks('atom_render_author', $o); + /** + * @hooks atom_render_author + * Possibility to add further tags to returned XML string. + * * \e string The created XML tag as a string without closing tag + */ + call_hooks('atom_render_author', $o); - $o .= "\r\n"; + $o .= "\r\n"; - return $o; + return $o; } -function compat_photos_list($s) { +function compat_photos_list($s) +{ - $ret = []; + $ret = []; - $found = preg_match_all('/\[[zi]mg(.*?)\](.*?)\[/ism',$s,$matches,PREG_SET_ORDER); + $found = preg_match_all('/\[[zi]mg(.*?)\](.*?)\[/ism', $s, $matches, PREG_SET_ORDER); - if($found) { - foreach($matches as $match) { - $entry = [ - 'href' => $match[2], - 'type' => guess_image_type($match[2]) - ]; - $sizer = new Img_filesize($match[2]); - $size = $sizer->getSize(); - if(intval($size)) { - $entry['length'] = intval($size); - } + if ($found) { + foreach ($matches as $match) { + $entry = [ + 'href' => $match[2], + 'type' => guess_image_type($match[2]) + ]; + $sizer = new Img_filesize($match[2]); + $size = $sizer->getSize(); + if (intval($size)) { + $entry['length'] = intval($size); + } - $ret[] = $entry; - } - } + $ret[] = $entry; + } + } - return $ret; + return $ret; } @@ -285,128 +296,131 @@ function compat_photos_list($s) { * @param bool $compat default false * @return void|string */ -function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $compat = false) { +function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $compat = false) +{ - if(! $item['parent']) - return; + if (! $item['parent']) { + return; + } - if($item['deleted']) - return '' . "\r\n"; + if ($item['deleted']) { + return '' . "\r\n"; + } - create_export_photo_body($item); + create_export_photo_body($item); - // provide separate summary and content unless compat is true; as summary represents a content-warning on some networks + // provide separate summary and content unless compat is true; as summary represents a content-warning on some networks - $summary = $item['summary']; + $summary = $item['summary']; - $body = $item['body']; + $body = $item['body']; - $compat_photos = null; + $compat_photos = null; - $o = "\r\n\r\n\r\n"; + $o = "\r\n\r\n\r\n"; - if(is_array($author)) { - $o .= atom_render_author('author',$author); - } - else { - $o .= atom_render_author('author',$item['author']); - } + if (is_array($author)) { + $o .= atom_render_author('author', $author); + } else { + $o .= atom_render_author('author', $item['author']); + } - if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { - $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); + if (($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { + $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; - } + $o .= '' . "\r\n"; + } else { + $o .= '' . xmlify($item['title']) . '' . "\r\n"; + if ($summary) { + $o .= '' . xmlify(prepare_text($summary, $item['mimetype'])) . '' . "\r\n"; + } + $o .= '' . xmlify(prepare_text($body, $item['mimetype'])) . '' . "\r\n"; + } + + $o .= '' . xmlify($item['mid']) . '' . "\r\n"; + $o .= '' . xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', ATOM_TIME)) . '' . "\r\n"; + $o .= '' . xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', ATOM_TIME)) . '' . "\r\n"; + + $o .= '' . "\r\n"; - else { - $o .= '' . xmlify($item['title']) . '' . "\r\n"; - if($summary) - $o .= '' . xmlify(prepare_text($summary,$item['mimetype'])) . '' . "\r\n"; - $o .= '' . xmlify(prepare_text($body,$item['mimetype'])) . '' . "\r\n"; - } + if ($item['attach']) { + $enclosures = json_decode($item['attach'], true); + if ($enclosures) { + foreach ($enclosures as $enc) { + $o .= '' . "\r\n"; + } + } + } - $o .= '' . xmlify($item['mid']) . '' . "\r\n"; - $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; - $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; + if ($item['term']) { + foreach ($item['term'] as $term) { + $scheme = ''; + $label = ''; + switch ($term['ttype']) { + case TERM_HASHTAG: + $scheme = NAMESPACE_ZOT . '/term/hashtag'; + $label = '#' . str_replace('"', '', $term['term']); + break; + case TERM_CATEGORY: + $scheme = NAMESPACE_ZOT . '/term/category'; + $label = str_replace('"', '', $term['term']); + break; + default: + break; + } + if (! $scheme) { + continue; + } - $o .= '' . "\r\n"; + $o .= '' . "\r\n"; + } + } + $o .= '' . "\r\n"; - if($item['attach']) { - $enclosures = json_decode($item['attach'], true); - if($enclosures) { - foreach($enclosures as $enc) { - $o .= '' . "\r\n"; - } - } - } + // build array to pass to hook + $x = [ + 'item' => $item, + 'type' => $type, + 'author' => $author, + 'owner' => $owner, + 'comment' => $comment, + 'abook_id' => $cid, + 'entry' => $o + ]; + /** + * @hooks atom_entry + * * \e array \b item + * * \e string \b type + * * \e array \b author + * * \e array \b owner + * * \e string \b comment + * * \e number \b abook_id + * * \e string \b entry - The generated entry and what will get returned + */ + call_hooks('atom_entry', $x); - if($item['term']) { - foreach($item['term'] as $term) { - $scheme = ''; - $label = ''; - switch($term['ttype']) { - case TERM_HASHTAG: - $scheme = NAMESPACE_ZOT . '/term/hashtag'; - $label = '#' . str_replace('"','',$term['term']); - break; - case TERM_CATEGORY: - $scheme = NAMESPACE_ZOT . '/term/category'; - $label = str_replace('"','',$term['term']); - break; - default: - break; - } - if(! $scheme) - continue; - - $o .= '' . "\r\n"; - } - } - - $o .= '' . "\r\n"; - - // build array to pass to hook - $x = [ - 'item' => $item, - 'type' => $type, - 'author' => $author, - 'owner' => $owner, - 'comment' => $comment, - 'abook_id' => $cid, - 'entry' => $o - ]; - /** - * @hooks atom_entry - * * \e array \b item - * * \e string \b type - * * \e array \b author - * * \e array \b owner - * * \e string \b comment - * * \e number \b abook_id - * * \e string \b entry - The generated entry and what will get returned - */ - call_hooks('atom_entry', $x); - - return $x['entry']; + return $x['entry']; } -function get_mentions($item,$tags) { - $o = ''; +function get_mentions($item, $tags) +{ + $o = ''; - if(! count($tags)) - return $o; + if (! count($tags)) { + return $o; + } - foreach($tags as $x) { - if($x['ttype'] == TERM_MENTION) { - $o .= "\t\t" . '' . "\r\n"; - } - } - return $o; + foreach ($tags as $x) { + if ($x['ttype'] == TERM_MENTION) { + $o .= "\t\t" . '' . "\r\n"; + } + } + return $o; } diff --git a/include/help.php b/include/help.php index 84ae9b6fa..ae47e1b60 100644 --- a/include/help.php +++ b/include/help.php @@ -1,6 +1,5 @@ 1) { - for ($x = 1; $x < argc(); $x ++) { - if ($path) { - $path .= '/'; - } - $path .= App::$argv[$x]; - } - } + $path = ''; + if (argc() > 1) { + for ($x = 1; $x < argc(); $x++) { + if ($path) { + $path .= '/'; + } + $path .= App::$argv[$x]; + } + } - $fullpath = get_help_fullpath($path); + $fullpath = get_help_fullpath($path); - $text = load_doc_file($fullpath); + $text = load_doc_file($fullpath); - App::$page['title'] = t('Help'); + App::$page['title'] = t('Help'); - $content = bbcode($text); + $content = bbcode($text); - return translate_projectname($content); + return translate_projectname($content); } -function preg_callback_help_include($matches) { - - if($matches[1]) { - $include = str_replace($matches[0],load_doc_file($matches[1]),$matches[0]); - if(preg_match('/\.bb$/', $matches[1]) || preg_match('/\.txt$/', $matches[1])) { - require_once('include/bbcode.php'); - $include = zidify_links(bbcode($include)); - $include = str_replace(' target="_blank"','',$include); - } - elseif(preg_match('/\.md$/', $matches[1])) { - $include = MarkdownExtra::defaultTransform($include); - } - return $include; - } +function preg_callback_help_include($matches) +{ + if ($matches[1]) { + $include = str_replace($matches[0], load_doc_file($matches[1]), $matches[0]); + if (preg_match('/\.bb$/', $matches[1]) || preg_match('/\.txt$/', $matches[1])) { + require_once('include/bbcode.php'); + $include = zidify_links(bbcode($include)); + $include = str_replace(' target="_blank"', '', $include); + } elseif (preg_match('/\.md$/', $matches[1])) { + $include = MarkdownExtra::defaultTransform($include); + } + return $include; + } } /** @@ -93,42 +94,47 @@ function preg_callback_help_include($matches) { * * @return bool|array */ -function determine_help_language() { +function determine_help_language() +{ - require_once('library/text_languagedetect/Text/LanguageDetect.php'); + require_once('library/text_languagedetect/Text/LanguageDetect.php'); - $lang_detect = new Text_LanguageDetect(); - // Set this mode to recognize language by the short code like "en", "ru", etc. - $lang_detect->setNameMode(2); - // If the language was specified in the URL, override the language preference - // of the browser. Default to English if both of these are absent. - if($lang_detect->languageExists(argv(1))) { - $lang = argv(1); - $from_url = true; - } else { - $lang = App::$language; - if(! isset($lang)) - $lang = 'en'; + $lang_detect = new Text_LanguageDetect(); + // Set this mode to recognize language by the short code like "en", "ru", etc. + $lang_detect->setNameMode(2); + // If the language was specified in the URL, override the language preference + // of the browser. Default to English if both of these are absent. + if ($lang_detect->languageExists(argv(1))) { + $lang = argv(1); + $from_url = true; + } else { + $lang = App::$language; + if (! isset($lang)) { + $lang = 'en'; + } - $from_url = false; - } + $from_url = false; + } - return array('language' => $lang, 'from_url' => $from_url); + return array('language' => $lang, 'from_url' => $from_url); } -function load_doc_file($s) { +function load_doc_file($s) +{ - $c = find_doc_file($s); - if($c) - return $c; - return ''; + $c = find_doc_file($s); + if ($c) { + return $c; + } + return ''; } -function find_doc_file($s) { - if(file_exists($s)) { - return file_get_contents($s); - } - return ''; +function find_doc_file($s) +{ + if (file_exists($s)) { + return file_get_contents($s); + } + return ''; } /** @@ -137,59 +143,64 @@ function find_doc_file($s) { * @param string $s * @return number|mixed|unknown|bool */ -function search_doc_files($s) { +function search_doc_files($s) +{ - App::set_pager_itemspage(60); - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + App::set_pager_itemspage(60); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); - $regexop = db_getfunc('REGEXP'); + $regexop = db_getfunc('REGEXP'); - $r = q("select iconfig.v, item.* from item left join iconfig on item.id = iconfig.iid + $r = q( + "select iconfig.v, item.* from item left join iconfig on item.id = iconfig.iid where iconfig.cat = 'system' and iconfig.k = 'docfile' and body $regexop '%s' and item_type = %d $pager_sql", - dbesc($s), - intval(ITEM_TYPE_DOC) - ); + dbesc($s), + intval(ITEM_TYPE_DOC) + ); - $r = fetch_post_tags($r, true); + $r = fetch_post_tags($r, true); - for($x = 0; $x < count($r); $x ++) { - $position = stripos($r[$x]['body'], $s); - $dislen = 300; - $start = $position-floor($dislen/2); - if ( $start < 0) { - $start = 0; - } - $r[$x]['text'] = substr($r[$x]['body'], $start, $dislen); + for ($x = 0; $x < count($r); $x++) { + $position = stripos($r[$x]['body'], $s); + $dislen = 300; + $start = $position - floor($dislen / 2); + if ($start < 0) { + $start = 0; + } + $r[$x]['text'] = substr($r[$x]['body'], $start, $dislen); - $r[$x]['rank'] = 0; - if($r[$x]['term']) { - foreach($r[$x]['term'] as $t) { - if(stristr($t['term'],$s)) { - $r[$x]['rank'] ++; - } - } - } - if(stristr($r[$x]['v'], $s)) - $r[$x]['rank'] ++; - $r[$x]['rank'] += substr_count(strtolower($r[$x]['text']), strtolower($s)); - // bias the results to the observer's native language - if($r[$x]['lang'] === App::$language) - $r[$x]['rank'] = $r[$x]['rank'] + 10; + $r[$x]['rank'] = 0; + if ($r[$x]['term']) { + foreach ($r[$x]['term'] as $t) { + if (stristr($t['term'], $s)) { + $r[$x]['rank'] ++; + } + } + } + if (stristr($r[$x]['v'], $s)) { + $r[$x]['rank'] ++; + } + $r[$x]['rank'] += substr_count(strtolower($r[$x]['text']), strtolower($s)); + // bias the results to the observer's native language + if ($r[$x]['lang'] === App::$language) { + $r[$x]['rank'] = $r[$x]['rank'] + 10; + } + } + usort($r, 'doc_rank_sort'); - } - usort($r,'doc_rank_sort'); - - return $r; + return $r; } -function doc_rank_sort($s1, $s2) { - if($s1['rank'] == $s2['rank']) - return 0; +function doc_rank_sort($s1, $s2) +{ + if ($s1['rank'] == $s2['rank']) { + return 0; + } - return (($s1['rank'] < $s2['rank']) ? 1 : (-1)); + return (($s1['rank'] < $s2['rank']) ? 1 : (-1)); } /** @@ -198,29 +209,31 @@ function doc_rank_sort($s1, $s2) { * @return string */ -function load_context_help() { +function load_context_help() +{ - $path = App::$cmd; - $args = App::$argv; - $lang = App::$language; + $path = App::$cmd; + $args = App::$argv; + $lang = App::$language; - if(! isset($lang) || !is_dir('doc/context/' . $lang . '/')) { - $lang = 'en'; - } - while($path) { - $context_help = load_doc_file('doc/context/' . $lang . '/' . $path . '/help.html'); - if(!$context_help) { - // Fallback to English if the translation is absent - $context_help = load_doc_file('doc/context/en/' . $path . '/help.html'); - } - if($context_help) - break; + if (! isset($lang) || !is_dir('doc/context/' . $lang . '/')) { + $lang = 'en'; + } + while ($path) { + $context_help = load_doc_file('doc/context/' . $lang . '/' . $path . '/help.html'); + if (!$context_help) { + // Fallback to English if the translation is absent + $context_help = load_doc_file('doc/context/en/' . $path . '/help.html'); + } + if ($context_help) { + break; + } - array_pop($args); - $path = implode('/',$args); - } + array_pop($args); + $path = implode('/', $args); + } - return $context_help; + return $context_help; } /** @@ -229,47 +242,49 @@ function load_context_help() { * @param string $s * @return void|bool|number[]|string[]|unknown[] */ -function store_doc_file($s) { +function store_doc_file($s) +{ - if(is_dir($s)) - return; + if (is_dir($s)) { + return; + } - $item = []; - $sys = get_sys_channel(); + $item = []; + $sys = get_sys_channel(); - $item['aid'] = 0; - $item['uid'] = $sys['channel_id']; + $item['aid'] = 0; + $item['uid'] = $sys['channel_id']; - $mimetype = 'text/bbcode'; + $mimetype = 'text/bbcode'; - require_once('include/html2plain.php'); + require_once('include/html2plain.php'); - $item['body'] = html2plain(prepare_text(file_get_contents($s),$mimetype, [ 'cache' => true ])); - $item['mimetype'] = 'text/plain'; + $item['body'] = html2plain(prepare_text(file_get_contents($s), $mimetype, [ 'cache' => true ])); + $item['mimetype'] = 'text/plain'; - $item['plink'] = z_root() . '/' . str_replace('doc','help',$s); - $item['owner_xchan'] = $item['author_xchan'] = $sys['channel_hash']; - $item['item_type'] = ITEM_TYPE_DOC; + $item['plink'] = z_root() . '/' . str_replace('doc', 'help', $s); + $item['owner_xchan'] = $item['author_xchan'] = $sys['channel_hash']; + $item['item_type'] = ITEM_TYPE_DOC; - $r = q("select item.* from item left join iconfig on item.id = iconfig.iid + $r = q( + "select item.* from item left join iconfig on item.id = iconfig.iid where iconfig.cat = 'system' and iconfig.k = 'docfile' and iconfig.v = '%s' and item_type = %d limit 1", - dbesc($s), - intval(ITEM_TYPE_DOC) - ); + dbesc($s), + intval(ITEM_TYPE_DOC) + ); - IConfig::Set($item,'system','docfile',$s); + IConfig::Set($item, 'system', 'docfile', $s); - if($r) { - $item['id'] = $r[0]['id']; - $item['mid'] = $item['parent_mid'] = $r[0]['mid']; - $x = item_store_update($item); - } - else { - $item['uuid'] = new_uuid(); - $item['mid'] = $item['parent_mid'] = z_root() . '/item/' . $item['uuid']; - $x = item_store($item); - } + if ($r) { + $item['id'] = $r[0]['id']; + $item['mid'] = $item['parent_mid'] = $r[0]['mid']; + $x = item_store_update($item); + } else { + $item['uuid'] = new_uuid(); + $item['mid'] = $item['parent_mid'] = z_root() . '/item/' . $item['uuid']; + $x = item_store($item); + } - return $x; + return $x; } diff --git a/include/html2bbcode.php b/include/html2bbcode.php index 1901d991c..e4533d2d7 100644 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -1,320 +1,332 @@ -query("//".$oldnode); - foreach ($list as $oldNode) { + $list = $xpath->query("//" . $oldnode); + foreach ($list as $oldNode) { + $attr = []; + if ($oldNode->attributes->length) { + foreach ($oldNode->attributes as $attribute) { + $attr[$attribute->name] = $attribute->value; + } + } - $attr = []; - if ($oldNode->attributes->length) - foreach ($oldNode->attributes as $attribute) - $attr[$attribute->name] = $attribute->value; + $replace = true; - $replace = true; + $startbb = $savestart; - $startbb = $savestart; + $i = 0; - $i = 0; + foreach ($attributes as $attribute => $value) { + $startbb = str_replace('\x01' . ++$i, '$1', $startbb); - foreach ($attributes as $attribute => $value) { + if (strpos('*' . $startbb, '$1') > 0) { + if ($replace and (@$attr[$attribute] != '')) { + $startbb = preg_replace($value, $startbb, $attr[$attribute], -1, $count); - $startbb = str_replace('\x01'.++$i, '$1', $startbb); + // If nothing could be changed + if ($count == 0) { + $replace = false; + } + } else { + $replace = false; + } + } else { + if (@$attr[$attribute] != $value) { + $replace = false; + } + } + } - if (strpos('*'.$startbb, '$1') > 0) { + if ($replace) { + $StartCode = $oldNode->ownerDocument->createTextNode($startbb); + $EndCode = $oldNode->ownerDocument->createTextNode($endbb); - if ($replace and (@$attr[$attribute] != '')) { + $oldNode->parentNode->insertBefore($StartCode, $oldNode); - $startbb = preg_replace($value, $startbb, $attr[$attribute], -1, $count); + if ($oldNode->hasChildNodes()) { + foreach ($oldNode->childNodes as $child) { + $newNode = $child->cloneNode(true); + $oldNode->parentNode->insertBefore($newNode, $oldNode); + } + } - // If nothing could be changed - if ($count == 0) - $replace = false; - } else - $replace = false; - } else { - if (@$attr[$attribute] != $value) - $replace = false; - } - } - - if ($replace) { - $StartCode = $oldNode->ownerDocument->createTextNode($startbb); - $EndCode = $oldNode->ownerDocument->createTextNode($endbb); - - $oldNode->parentNode->insertBefore($StartCode, $oldNode); - - if ($oldNode->hasChildNodes()) { - foreach ($oldNode->childNodes as $child) { - $newNode = $child->cloneNode(true); - $oldNode->parentNode->insertBefore($newNode, $oldNode); - } - } - - $oldNode->parentNode->insertBefore($EndCode, $oldNode); - $oldNode->parentNode->removeChild($oldNode); - } - } - return($replace); + $oldNode->parentNode->insertBefore($EndCode, $oldNode); + $oldNode->parentNode->removeChild($oldNode); + } + } + return($replace); } function deletenode(&$doc, $node) { - $xpath = new DomXPath($doc); - $list = $xpath->query("//".$node); - foreach ($list as $child) - $child->parentNode->removeChild($child); + $xpath = new DomXPath($doc); + $list = $xpath->query("//" . $node); + foreach ($list as $child) { + $child->parentNode->removeChild($child); + } } -function svg2bbcode($match) { +function svg2bbcode($match) +{ - $params = $match[1]; - $s = $match[2]; - - $output = '' . $s . ''; + $params = $match[1]; + $s = $match[2]; - $purify = new SvgSanitizer(); - if ($purify->loadXML($s)) { - $purify->sanitize(); - $output = $purify->saveSVG(); - $output = preg_replace("/\<\?xml(.*?)\>/",'',$output); - $output = preg_replace("/\<\!\-\-(.*?)\-\-\>/",'',$output); - $output = str_replace(['<','>'],['[',']'],$output); - return $output; - } - return EMPTY_STR; + $output = '' . $s . ''; + $purify = new SvgSanitizer(); + if ($purify->loadXML($s)) { + $purify->sanitize(); + $output = $purify->saveSVG(); + $output = preg_replace("/\<\?xml(.*?)\>/", '', $output); + $output = preg_replace("/\<\!\-\-(.*?)\-\-\>/", '', $output); + $output = str_replace(['<','>'], ['[',']'], $output); + return $output; + } + return EMPTY_STR; } -function html2bbcode($message) { +function html2bbcode($message) +{ - if (! $message) { - return EMPTY_STR; - } + if (! $message) { + return EMPTY_STR; + } - $message = str_replace("\r", "", $message); + $message = str_replace("\r", "", $message); - $message = str_replace(array( - "
                  • ", - "

                  • "), - array( - "
                  • ", - "
                  • "), - $message); + $message = str_replace( + array( + "
                  • ", + "

                  • "), + array( + "
                  • ", + "
                  • "), + $message + ); - // remove namespaces - $message = preg_replace('=<(\w+):(.+?)>=', '', $message); - $message = preg_replace('==', '', $message); + // remove namespaces + $message = preg_replace('=<(\w+):(.+?)>=', '', $message); + $message = preg_replace('==', '', $message); - $doc = new DOMDocument(); - $doc->preserveWhiteSpace = false; + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; - $tmp_message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); + $tmp_message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); - if (! $tmp_message) { - logger('mb_convert_encoding failed: ' . $message); - return EMPTY_STR; - } + if (! $tmp_message) { + logger('mb_convert_encoding failed: ' . $message); + return EMPTY_STR; + } - @$doc->loadHTML($tmp_message); + @$doc->loadHTML($tmp_message); - deletenode($doc, 'style'); - deletenode($doc, 'head'); - deletenode($doc, 'title'); - deletenode($doc, 'meta'); - deletenode($doc, 'xml'); - deletenode($doc, 'removeme'); + deletenode($doc, 'style'); + deletenode($doc, 'head'); + deletenode($doc, 'title'); + deletenode($doc, 'meta'); + deletenode($doc, 'xml'); + deletenode($doc, 'removeme'); - $xpath = new DomXPath($doc); - $list = $xpath->query("//pre"); - foreach ($list as $node) - $node->nodeValue = str_replace("\n", "\r", $node->nodeValue); + $xpath = new DomXPath($doc); + $list = $xpath->query("//pre"); + foreach ($list as $node) { + $node->nodeValue = str_replace("\n", "\r", $node->nodeValue); + } - $message = $doc->saveHTML(); - $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "
                    ", " ", ""), $message); - $message = preg_replace('= [\s]*=i', " ", $message); - @$doc->loadHTML($message); + $message = $doc->saveHTML(); + $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "
                    ", " ", ""), $message); + $message = preg_replace('= [\s]*=i', " ", $message); + @$doc->loadHTML($message); - node2bbcode($doc, 'html', [], "", ""); - node2bbcode($doc, 'body', [], "", ""); + node2bbcode($doc, 'html', [], "", ""); + node2bbcode($doc, 'body', [], "", ""); - // Outlook-Quote - Variant 1 - node2bbcode($doc, 'p', array('class'=>'MsoNormal', 'style'=>'margin-left:35.4pt'), '[quote]', '[/quote]'); + // Outlook-Quote - Variant 1 + node2bbcode($doc, 'p', array('class' => 'MsoNormal', 'style' => 'margin-left:35.4pt'), '[quote]', '[/quote]'); - // Outlook-Quote - Variant 2 - node2bbcode($doc, 'div', array('style'=>'border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'), '[quote]', '[/quote]'); + // Outlook-Quote - Variant 2 + node2bbcode($doc, 'div', array('style' => 'border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'), '[quote]', '[/quote]'); - // MyBB-Stuff - node2bbcode($doc, 'span', array('style'=>'text-decoration: underline;'), '[u]', '[/u]'); - node2bbcode($doc, 'span', array('style'=>'font-style: italic;'), '[i]', '[/i]'); - node2bbcode($doc, 'span', array('style'=>'font-weight: bold;'), '[b]', '[/b]'); + // MyBB-Stuff + node2bbcode($doc, 'span', array('style' => 'text-decoration: underline;'), '[u]', '[/u]'); + node2bbcode($doc, 'span', array('style' => 'font-style: italic;'), '[i]', '[/i]'); + node2bbcode($doc, 'span', array('style' => 'font-weight: bold;'), '[b]', '[/b]'); - /*node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'size'=>'/(\d+)/', 'color'=>'/(.+)/'), '[font=$1][size=$2][color=$3]', '[/color][/size][/font]'); - node2bbcode($doc, 'font', array('size'=>'/(\d+)/', 'color'=>'/(.+)/'), '[size=$1][color=$2]', '[/color][/size]'); - node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'size'=>'/(.+)/'), '[font=$1][size=$2]', '[/size][/font]'); - node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'color'=>'/(.+)/'), '[font=$1][color=$3]', '[/color][/font]'); - node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/'), '[font=$1]', '[/font]'); - node2bbcode($doc, 'font', array('size'=>'/(\d+)/'), '[size=$1]', '[/size]'); - node2bbcode($doc, 'font', array('color'=>'/(.+)/'), '[color=$1]', '[/color]'); + /*node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'size'=>'/(\d+)/', 'color'=>'/(.+)/'), '[font=$1][size=$2][color=$3]', '[/color][/size][/font]'); + node2bbcode($doc, 'font', array('size'=>'/(\d+)/', 'color'=>'/(.+)/'), '[size=$1][color=$2]', '[/color][/size]'); + node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'size'=>'/(.+)/'), '[font=$1][size=$2]', '[/size][/font]'); + node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/', 'color'=>'/(.+)/'), '[font=$1][color=$3]', '[/color][/font]'); + node2bbcode($doc, 'font', array('face'=>'/([\w ]+)/'), '[font=$1]', '[/font]'); + node2bbcode($doc, 'font', array('size'=>'/(\d+)/'), '[size=$1]', '[/size]'); + node2bbcode($doc, 'font', array('color'=>'/(.+)/'), '[color=$1]', '[/color]'); */ - // Untested - //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(.+?)[,;].*font-family:\s*(.+?)[,;].*color:\s*(.+?)[,;].*/'), '[size=$1][font=$2][color=$3]', '[/color][/font][/size]'); - //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(\d+)[,;].*/'), '[size=$1]', '[/size]'); - //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(.+?)[,;].*/'), '[size=$1]', '[/size]'); + // Untested + //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(.+?)[,;].*font-family:\s*(.+?)[,;].*color:\s*(.+?)[,;].*/'), '[size=$1][font=$2][color=$3]', '[/color][/font][/size]'); + //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(\d+)[,;].*/'), '[size=$1]', '[/size]'); + //node2bbcode($doc, 'span', array('style'=>'/.*font-size:\s*(.+?)[,;].*/'), '[size=$1]', '[/size]'); - node2bbcode($doc, 'span', array('style'=>'/.*color:\s*(.+?)[,;].*/'), '[color="$1"]', '[/color]'); - //node2bbcode($doc, 'span', array('style'=>'/.*font-family:\s*(.+?)[,;].*/'), '[font=$1]', '[/font]'); + node2bbcode($doc, 'span', array('style' => '/.*color:\s*(.+?)[,;].*/'), '[color="$1"]', '[/color]'); + //node2bbcode($doc, 'span', array('style'=>'/.*font-family:\s*(.+?)[,;].*/'), '[font=$1]', '[/font]'); - //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*font-size:\s*(\d+?)pt.*/'), '[font=$1][size=$2]', '[/size][/font]'); - //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*font-size:\s*(\d+?)px.*/'), '[font=$1][size=$2]', '[/size][/font]'); - //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*/'), '[font=$1]', '[/font]'); + //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*font-size:\s*(\d+?)pt.*/'), '[font=$1][size=$2]', '[/size][/font]'); + //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*font-size:\s*(\d+?)px.*/'), '[font=$1][size=$2]', '[/size][/font]'); + //node2bbcode($doc, 'div', array('style'=>'/.*font-family:\s*(.+?)[,;].*/'), '[font=$1]', '[/font]'); - node2bbcode($doc, 'strong', [], '[b]', '[/b]'); - node2bbcode($doc, 'em', [], '[i]', '[/i]'); - node2bbcode($doc, 'b', [], '[b]', '[/b]'); - node2bbcode($doc, 'i', [], '[i]', '[/i]'); - node2bbcode($doc, 'u', [], '[u]', '[/u]'); - node2bbcode($doc, 's', [], '[s]', '[/s]'); + node2bbcode($doc, 'strong', [], '[b]', '[/b]'); + node2bbcode($doc, 'em', [], '[i]', '[/i]'); + node2bbcode($doc, 'b', [], '[b]', '[/b]'); + node2bbcode($doc, 'i', [], '[i]', '[/i]'); + node2bbcode($doc, 'u', [], '[u]', '[/u]'); + node2bbcode($doc, 's', [], '[s]', '[/s]'); - node2bbcode($doc, 'big', [], "[size=large]", "[/size]"); - node2bbcode($doc, 'small', [], "[size=small]", "[/size]"); + node2bbcode($doc, 'big', [], "[size=large]", "[/size]"); + node2bbcode($doc, 'small', [], "[size=small]", "[/size]"); - node2bbcode($doc, 'blockquote', [], '[quote]', '[/quote]'); + node2bbcode($doc, 'blockquote', [], '[quote]', '[/quote]'); - node2bbcode($doc, 'br', [], "\n", ''); + node2bbcode($doc, 'br', [], "\n", ''); - node2bbcode($doc, 'p', array('class'=>'MsoNormal'), "\n", ""); - node2bbcode($doc, 'div', array('class'=>'MsoNormal'), "\r", ""); + node2bbcode($doc, 'p', array('class' => 'MsoNormal'), "\n", ""); + node2bbcode($doc, 'div', array('class' => 'MsoNormal'), "\r", ""); - node2bbcode($doc, 'span', [], "", ""); + node2bbcode($doc, 'span', [], "", ""); - node2bbcode($doc, 'span', [], "", ""); - node2bbcode($doc, 'pre', [], "", ""); - node2bbcode($doc, 'div', [], "\r", "\r"); - node2bbcode($doc, 'p', [], "\n", "\n"); + node2bbcode($doc, 'span', [], "", ""); + node2bbcode($doc, 'pre', [], "", ""); + node2bbcode($doc, 'div', [], "\r", "\r"); + node2bbcode($doc, 'p', [], "\n", "\n"); - node2bbcode($doc, 'ul', [], "[list]", "[/list]"); - node2bbcode($doc, 'ol', [], "[list=1]", "[/list]"); - node2bbcode($doc, 'li', [], "[*]", ""); + node2bbcode($doc, 'ul', [], "[list]", "[/list]"); + node2bbcode($doc, 'ol', [], "[list=1]", "[/list]"); + node2bbcode($doc, 'li', [], "[*]", ""); - node2bbcode($doc, 'hr', [], "[hr]", ""); + node2bbcode($doc, 'hr', [], "[hr]", ""); -// node2bbcode($doc, 'table', [], "", ""); -// node2bbcode($doc, 'tr', [], "\n", ""); -// node2bbcode($doc, 'td', [], "\t", ""); +// node2bbcode($doc, 'table', [], "", ""); +// node2bbcode($doc, 'tr', [], "\n", ""); +// node2bbcode($doc, 'td', [], "\t", ""); - node2bbcode($doc, 'table', [], "[table]", "[/table]"); - node2bbcode($doc, 'th', [], "[th]", "[/th]"); - node2bbcode($doc, 'tr', [], "[tr]", "[/tr]"); - node2bbcode($doc, 'td', [], "[td]", "[/td]"); + node2bbcode($doc, 'table', [], "[table]", "[/table]"); + node2bbcode($doc, 'th', [], "[th]", "[/th]"); + node2bbcode($doc, 'tr', [], "[tr]", "[/tr]"); + node2bbcode($doc, 'td', [], "[td]", "[/td]"); - node2bbcode($doc, 'h1', [], "\n\n[h1]", "[/h1]\n"); - node2bbcode($doc, 'h2', [], "\n\n[h2]", "[/h2]\n"); - node2bbcode($doc, 'h3', [], "\n\n[h3]", "[/h3]\n"); - node2bbcode($doc, 'h4', [], "\n\n[h4]", "[/h4]\n"); - node2bbcode($doc, 'h5', [], "\n\n[h5]", "[/h5]\n"); - node2bbcode($doc, 'h6', [], "\n\n[h6]", "[/h6]\n"); + node2bbcode($doc, 'h1', [], "\n\n[h1]", "[/h1]\n"); + node2bbcode($doc, 'h2', [], "\n\n[h2]", "[/h2]\n"); + node2bbcode($doc, 'h3', [], "\n\n[h3]", "[/h3]\n"); + node2bbcode($doc, 'h4', [], "\n\n[h4]", "[/h4]\n"); + node2bbcode($doc, 'h5', [], "\n\n[h5]", "[/h5]\n"); + node2bbcode($doc, 'h6', [], "\n\n[h6]", "[/h6]\n"); - node2bbcode($doc, 'a', array('href'=>'/(.+)/'), '[url=$1]', '[/url]'); + node2bbcode($doc, 'a', array('href' => '/(.+)/'), '[url=$1]', '[/url]'); - node2bbcode($doc, 'img', array('src'=>'/(.+)/', 'width'=>'/(\d+)/', 'height'=>'/(\d+)/'), '[img=$2x$3]$1', '[/img]'); - node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '[img]$1', '[/img]'); + node2bbcode($doc, 'img', array('src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'), '[img=$2x$3]$1', '[/img]'); + node2bbcode($doc, 'img', array('src' => '/(.+)/'), '[img]$1', '[/img]'); - node2bbcode($doc, 'video', array('src'=>'/(.+)/', 'poster'=>'/(.+)/'), '[video poster="$2"]$1', '[/video]'); - node2bbcode($doc, 'video', array('src'=>'/(.+)/'), '[video]$1', '[/video]'); - node2bbcode($doc, 'audio', array('src'=>'/(.+)/'), '[audio]$1', '[/audio]'); -// node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]'); + node2bbcode($doc, 'video', array('src' => '/(.+)/', 'poster' => '/(.+)/'), '[video poster="$2"]$1', '[/video]'); + node2bbcode($doc, 'video', array('src' => '/(.+)/'), '[video]$1', '[/video]'); + node2bbcode($doc, 'audio', array('src' => '/(.+)/'), '[audio]$1', '[/audio]'); +// node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]'); - node2bbcode($doc, 'code', [], '[code]', '[/code]'); + node2bbcode($doc, 'code', [], '[code]', '[/code]'); - $message = $doc->saveHTML(); + $message = $doc->saveHTML(); - // I'm removing something really disturbing - // Don't know exactly what it is - $message = str_replace(chr(194).chr(160), ' ', $message); + // I'm removing something really disturbing + // Don't know exactly what it is + $message = str_replace(chr(194) . chr(160), ' ', $message); - $message = str_replace(" ", " ", $message); + $message = str_replace(" ", " ", $message); - // removing multiple DIVs - $message = preg_replace('=\r *\r=i', "\n", $message); - $message = str_replace("\r", "\n", $message); + // removing multiple DIVs + $message = preg_replace('=\r *\r=i', "\n", $message); + $message = str_replace("\r", "\n", $message); - call_hooks('html2bbcode', $message); + call_hooks('html2bbcode', $message); - $message = strip_tags($message); + $message = strip_tags($message); - $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8'); + $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8'); - $message = str_replace(array("<"), array("<"), $message); + $message = str_replace(array("<"), array("<"), $message); - // remove quotes if they don't make sense - $message = preg_replace('=\[/quote\][\s]*\[quote\]=i', "\n", $message); + // remove quotes if they don't make sense + $message = preg_replace('=\[/quote\][\s]*\[quote\]=i', "\n", $message); - $message = preg_replace('=\[quote\]\s*=i', "[quote]", $message); - $message = preg_replace('=\s*\[/quote\]=i', "[/quote]", $message); + $message = preg_replace('=\[quote\]\s*=i', "[quote]", $message); + $message = preg_replace('=\s*\[/quote\]=i', "[/quote]", $message); - do { - $oldmessage = $message; - $message = str_replace("\n \n", "\n\n", $message); - } while ($oldmessage != $message); + do { + $oldmessage = $message; + $message = str_replace("\n \n", "\n\n", $message); + } while ($oldmessage != $message); - do { - $oldmessage = $message; - $message = str_replace("\n\n\n", "\n\n", $message); - } while ($oldmessage != $message); + do { + $oldmessage = $message; + $message = str_replace("\n\n\n", "\n\n", $message); + } while ($oldmessage != $message); - do { - $oldmessage = $message; - $message = str_replace(array( - "[/size]\n\n", - "\n[hr]", - "[hr]\n", - "\n[list", - "[/list]\n", - "\n[/", - "[list]\n", - "[list=1]\n", - "\n[*]"), - array( - "[/size]\n", - "[hr]", - "[hr]", - "[list", - "[/list]", - "[/", - "[list]", - "[list=1]", - "[*]"), - $message); - } while ($message != $oldmessage); + do { + $oldmessage = $message; + $message = str_replace( + array( + "[/size]\n\n", + "\n[hr]", + "[hr]\n", + "\n[list", + "[/list]\n", + "\n[/", + "[list]\n", + "[list=1]\n", + "\n[*]"), + array( + "[/size]\n", + "[hr]", + "[hr]", + "[list", + "[/list]", + "[/", + "[list]", + "[list=1]", + "[*]"), + $message + ); + } while ($message != $oldmessage); - $message = str_replace(array('[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'), - array('[b]', '[/b]', '[i]', '[/i]'), $message); + $message = str_replace( + array('[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'), + array('[b]', '[/b]', '[i]', '[/i]'), + $message + ); - // Handling Yahoo style of mails - // $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message); + // Handling Yahoo style of mails + // $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message); - $message = htmlspecialchars($message,ENT_COMPAT,'UTF-8',false); - return(trim($message)); + $message = htmlspecialchars($message, ENT_COMPAT, 'UTF-8', false); + return(trim($message)); } - diff --git a/include/html2plain.php b/include/html2plain.php index 3a77b904e..65697c6f9 100644 --- a/include/html2plain.php +++ b/include/html2plain.php @@ -1,230 +1,246 @@ - 0) and strlen($line) > $wraplen) { - $newline = trim(substr($line, 0, $pos)); - if ($level > 0) - $newline = str_repeat(">", $level).' '.$newline; + if (($pos > 0) and strlen($line) > $wraplen) { + $newline = trim(substr($line, 0, $pos)); + if ($level > 0) { + $newline = str_repeat(">", $level) . ' ' . $newline; + } - $newlines[] = $newline." "; - $line = substr($line, $pos+1); - } + $newlines[] = $newline . " "; + $line = substr($line, $pos + 1); + } + } while ((strlen($line) > $wraplen) and !($oldline == $line)); - } while ((strlen($line) > $wraplen) and !($oldline == $line)); + if ($level > 0) { + $line = str_repeat(">", $level) . ' ' . $line; + } - if ($level > 0) - $line = str_repeat(">", $level).' '.$line; - - $newlines[] = $line; + $newlines[] = $line; - return(implode("\n", $newlines)); + return(implode("\n", $newlines)); } function quotelevel($message, $wraplength = 75) { - $lines = explode("\n", $message); + $lines = explode("\n", $message); - $newlines = []; - $level = 0; - foreach($lines as $line) { + $newlines = []; + $level = 0; + foreach ($lines as $line) { $line = trim($line); - $startquote = false; - while (strpos("*".$line, '[quote]') > 0) { - $level++; - $pos = strpos($line, '[quote]'); - $line = substr($line, 0, $pos).substr($line, $pos+7); - $startquote = true; - } + $startquote = false; + while (strpos("*" . $line, '[quote]') > 0) { + $level++; + $pos = strpos($line, '[quote]'); + $line = substr($line, 0, $pos) . substr($line, $pos + 7); + $startquote = true; + } - $currlevel = $level; + $currlevel = $level; - while (strpos("*".$line, '[/quote]') > 0) { - $level--; - if ($level < 0) - $level = 0; + while (strpos("*" . $line, '[/quote]') > 0) { + $level--; + if ($level < 0) { + $level = 0; + } - $pos = strpos($line, '[/quote]'); - $line = substr($line, 0, $pos).substr($line, $pos+8); - } + $pos = strpos($line, '[/quote]'); + $line = substr($line, 0, $pos) . substr($line, $pos + 8); + } - if (!$startquote or ($line != '')) - $newlines[] = breaklines($line, $currlevel, $wraplength); - } - return(implode("\n", $newlines)); + if (!$startquote or ($line != '')) { + $newlines[] = breaklines($line, $currlevel, $wraplength); + } + } + return(implode("\n", $newlines)); } -function collecturls($message) { - $pattern = '/(.*?)<\/a>/is'; - preg_match_all($pattern, $message, $result, PREG_SET_ORDER); +function collecturls($message) +{ + $pattern = '/(.*?)<\/a>/is'; + preg_match_all($pattern, $message, $result, PREG_SET_ORDER); - $urls = []; - foreach ($result as $treffer) { - // A list of some links that should be ignored - $list = array("/user/", "/tag/", "/group/", "/profile/", "/channel/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/", - "//facebook.com/profile.php?id=", "//plus.google.com/"); - foreach ($list as $listitem) - if (strpos($treffer[1], $listitem) !== false) - $ignore = true; + $urls = []; + foreach ($result as $treffer) { + // A list of some links that should be ignored + $list = array("/user/", "/tag/", "/group/", "/profile/", "/channel/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/", + "//facebook.com/profile.php?id=", "//plus.google.com/"); + foreach ($list as $listitem) { + if (strpos($treffer[1], $listitem) !== false) { + $ignore = true; + } + } - if ((strpos($treffer[1], "//plus.google.com/") !== false) and (strpos($treffer[1], "/posts") !== false)) - $ignore = false; + if ((strpos($treffer[1], "//plus.google.com/") !== false) and (strpos($treffer[1], "/posts") !== false)) { + $ignore = false; + } - if (!$ignore) - $urls[$treffer[1]] = $treffer[1]; - } - return($urls); + if (!$ignore) { + $urls[$treffer[1]] = $treffer[1]; + } + } + return($urls); } function html2plain($html, $wraplength = 75, $compact = false) { - $message = str_replace("\r", "", $html); + $message = str_replace("\r", "", $html); - if (! $message) { - return $message; - } - $doc = new DOMDocument(); - $doc->preserveWhiteSpace = false; + if (! $message) { + return $message; + } + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; - - $tmp_message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); - if ($tmp_message === false) { - logger('mb_convert_encoding failed: ' . $tmp_message); - return EMPTY_STR; - } - @$doc->loadHTML($tmp_message); + $tmp_message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); + if ($tmp_message === false) { + logger('mb_convert_encoding failed: ' . $tmp_message); + return EMPTY_STR; + } - $xpath = new DOMXPath($doc); - $list = $xpath->query("//pre"); - foreach ($list as $node) { - $node->nodeValue = str_replace("\n", "\r", htmlspecialchars($node->nodeValue)); - } + @$doc->loadHTML($tmp_message); - $message = $doc->saveHTML(); - $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "
                    ", " ", ""), $message); - $message = preg_replace('= [\s]*=i', " ", $message); + $xpath = new DOMXPath($doc); + $list = $xpath->query("//pre"); + foreach ($list as $node) { + $node->nodeValue = str_replace("\n", "\r", htmlspecialchars($node->nodeValue)); + } - // Collecting all links - $urls = collecturls($message); + $message = $doc->saveHTML(); + $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "
                    ", " ", ""), $message); + $message = preg_replace('= [\s]*=i', " ", $message); - @$doc->loadHTML($message); + // Collecting all links + $urls = collecturls($message); - node2bbcode($doc, 'html', [], '', ''); - node2bbcode($doc, 'body', [], '', ''); + @$doc->loadHTML($message); - // MyBB-Auszeichnungen - /* - node2bbcode($doc, 'span', array('style'=>'text-decoration: underline;'), '_', '_'); - node2bbcode($doc, 'span', array('style'=>'font-style: italic;'), '/', '/'); - node2bbcode($doc, 'span', array('style'=>'font-weight: bold;'), '*', '*'); + node2bbcode($doc, 'html', [], '', ''); + node2bbcode($doc, 'body', [], '', ''); - node2bbcode($doc, 'strong', [], '*', '*'); - node2bbcode($doc, 'b', [], '*', '*'); - node2bbcode($doc, 'i', [], '/', '/'); - node2bbcode($doc, 'u', [], '_', '_'); - */ + // MyBB-Auszeichnungen + /* + node2bbcode($doc, 'span', array('style'=>'text-decoration: underline;'), '_', '_'); + node2bbcode($doc, 'span', array('style'=>'font-style: italic;'), '/', '/'); + node2bbcode($doc, 'span', array('style'=>'font-weight: bold;'), '*', '*'); - if ($compact) - node2bbcode($doc, 'blockquote', [], "»", "«"); - else - node2bbcode($doc, 'blockquote', [], '[quote]', "[/quote]\n"); + node2bbcode($doc, 'strong', [], '*', '*'); + node2bbcode($doc, 'b', [], '*', '*'); + node2bbcode($doc, 'i', [], '/', '/'); + node2bbcode($doc, 'u', [], '_', '_'); + */ - node2bbcode($doc, 'br', [], "\n", ''); + if ($compact) { + node2bbcode($doc, 'blockquote', [], "»", "«"); + } else { + node2bbcode($doc, 'blockquote', [], '[quote]', "[/quote]\n"); + } - node2bbcode($doc, 'span', [], "", ""); - node2bbcode($doc, 'pre', [], "", ""); - node2bbcode($doc, 'div', [], "\r", "\r"); - node2bbcode($doc, 'p', [], "\n", "\n"); + node2bbcode($doc, 'br', [], "\n", ''); - //node2bbcode($doc, 'ul', [], "\n[list]", "[/list]\n"); - //node2bbcode($doc, 'ol', [], "\n[list=1]", "[/list]\n"); - node2bbcode($doc, 'li', [], "\n* ", "\n"); + node2bbcode($doc, 'span', [], "", ""); + node2bbcode($doc, 'pre', [], "", ""); + node2bbcode($doc, 'div', [], "\r", "\r"); + node2bbcode($doc, 'p', [], "\n", "\n"); - node2bbcode($doc, 'hr', [], "\n".str_repeat("-", 70)."\n", ""); + //node2bbcode($doc, 'ul', [], "\n[list]", "[/list]\n"); + //node2bbcode($doc, 'ol', [], "\n[list=1]", "[/list]\n"); + node2bbcode($doc, 'li', [], "\n* ", "\n"); - node2bbcode($doc, 'tr', [], "\n", ""); - node2bbcode($doc, 'td', [], "\t", ""); + node2bbcode($doc, 'hr', [], "\n" . str_repeat("-", 70) . "\n", ""); - node2bbcode($doc, 'h1', [], "\n\n*", "*\n"); - node2bbcode($doc, 'h2', [], "\n\n*", "*\n"); - node2bbcode($doc, 'h3', [], "\n\n*", "*\n"); - node2bbcode($doc, 'h4', [], "\n\n*", "*\n"); - node2bbcode($doc, 'h5', [], "\n\n*", "*\n"); - node2bbcode($doc, 'h6', [], "\n\n*", "*\n"); + node2bbcode($doc, 'tr', [], "\n", ""); + node2bbcode($doc, 'td', [], "\t", ""); - // Problem: there is no reliable way to detect if it is a link to a tag or profile - //node2bbcode($doc, 'a', array('href'=>'/(.+)/'), ' $1 ', '', true); - node2bbcode($doc, 'a', array('href'=>'/(.+)/', 'rel'=>'oembed'), ' $1 ', '', true); - //node2bbcode($doc, 'img', array('alt'=>'/(.+)/'), '$1', ''); - //node2bbcode($doc, 'img', array('title'=>'/(.+)/'), '$1', ''); - //node2bbcode($doc, 'img', [], '', ''); - if (!$compact) - node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '[img]$1', '[/img]'); - else - node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '', ''); + node2bbcode($doc, 'h1', [], "\n\n*", "*\n"); + node2bbcode($doc, 'h2', [], "\n\n*", "*\n"); + node2bbcode($doc, 'h3', [], "\n\n*", "*\n"); + node2bbcode($doc, 'h4', [], "\n\n*", "*\n"); + node2bbcode($doc, 'h5', [], "\n\n*", "*\n"); + node2bbcode($doc, 'h6', [], "\n\n*", "*\n"); - node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), ' $1 ', '', true); + // Problem: there is no reliable way to detect if it is a link to a tag or profile + //node2bbcode($doc, 'a', array('href'=>'/(.+)/'), ' $1 ', '', true); + node2bbcode($doc, 'a', array('href' => '/(.+)/', 'rel' => 'oembed'), ' $1 ', '', true); + //node2bbcode($doc, 'img', array('alt'=>'/(.+)/'), '$1', ''); + //node2bbcode($doc, 'img', array('title'=>'/(.+)/'), '$1', ''); + //node2bbcode($doc, 'img', [], '', ''); + if (!$compact) { + node2bbcode($doc, 'img', array('src' => '/(.+)/'), '[img]$1', '[/img]'); + } else { + node2bbcode($doc, 'img', array('src' => '/(.+)/'), '', ''); + } - $message = $doc->saveHTML(); + node2bbcode($doc, 'iframe', array('src' => '/(.+)/'), ' $1 ', '', true); - if (!$compact) { - $message = str_replace("[img]", "", $message); - $message = str_replace("[/img]", "", $message); - } + $message = $doc->saveHTML(); - // was ersetze ich da? - // Irgendein stoerrisches UTF-Zeug - $message = str_replace(chr(194).chr(160), ' ', $message); + if (!$compact) { + $message = str_replace("[img]", "", $message); + $message = str_replace("[/img]", "", $message); + } - $message = str_replace(" ", " ", $message); + // was ersetze ich da? + // Irgendein stoerrisches UTF-Zeug + $message = str_replace(chr(194) . chr(160), ' ', $message); - // Aufeinanderfolgende DIVs - $message = preg_replace('=\r *\r=i', "\n", $message); - $message = str_replace("\r", "\n", $message); + $message = str_replace(" ", " ", $message); - $message = strip_tags($message); + // Aufeinanderfolgende DIVs + $message = preg_replace('=\r *\r=i', "\n", $message); + $message = str_replace("\r", "\n", $message); - $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8'); + $message = strip_tags($message); - if (!$compact) { - $counter = 1; - foreach ($urls as $id=>$url) - if ($url && strpos($message, $url) === false) - $message .= "\n".$url." "; - //$message .= "\n[".($counter++)."] ".$url; - } + $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8'); - do { - $oldmessage = $message; - $message = str_replace("\n\n\n", "\n\n", $message); - } while ($oldmessage != $message); + if (!$compact) { + $counter = 1; + foreach ($urls as $id => $url) { + if ($url && strpos($message, $url) === false) { + $message .= "\n" . $url . " "; + } + } + //$message .= "\n[".($counter++)."] ".$url; + } - $message = quotelevel(trim($message), $wraplength); + do { + $oldmessage = $message; + $message = str_replace("\n\n\n", "\n\n", $message); + } while ($oldmessage != $message); - return(trim($message)); + $message = quotelevel(trim($message), $wraplength); + + return(trim($message)); } - diff --git a/include/hubloc.php b/include/hubloc.php index 1fe74a43e..53ad35ccb 100644 --- a/include/hubloc.php +++ b/include/hubloc.php @@ -1,4 +1,5 @@ ((array_key_exists('hubloc_guid',$arr)) ? $arr['hubloc_guid'] : ''), - 'hubloc_guid_sig' => ((array_key_exists('hubloc_guid_sig',$arr)) ? $arr['hubloc_guid_sig'] : ''), - 'hubloc_id_url' => ((array_key_exists('hubloc_id_url',$arr)) ? $arr['hubloc_id_url'] : ''), - 'hubloc_hash' => ((array_key_exists('hubloc_hash',$arr)) ? $arr['hubloc_hash'] : ''), - 'hubloc_addr' => ((array_key_exists('hubloc_addr',$arr)) ? $arr['hubloc_addr'] : ''), - 'hubloc_network' => ((array_key_exists('hubloc_network',$arr)) ? $arr['hubloc_network'] : ''), - 'hubloc_flags' => ((array_key_exists('hubloc_flags',$arr)) ? $arr['hubloc_flags'] : 0), - 'hubloc_status' => ((array_key_exists('hubloc_status',$arr)) ? $arr['hubloc_status'] : 0), - 'hubloc_url' => ((array_key_exists('hubloc_url',$arr)) ? $arr['hubloc_url'] : ''), - 'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig',$arr)) ? $arr['hubloc_url_sig'] : ''), - 'hubloc_site_id' => ((array_key_exists('hubloc_site_id',$arr)) ? $arr['hubloc_site_id'] : ''), - 'hubloc_host' => ((array_key_exists('hubloc_host',$arr)) ? $arr['hubloc_host'] : ''), - 'hubloc_callback' => ((array_key_exists('hubloc_callback',$arr)) ? $arr['hubloc_callback'] : ''), - 'hubloc_connect' => ((array_key_exists('hubloc_connect',$arr)) ? $arr['hubloc_connect'] : ''), - 'hubloc_sitekey' => ((array_key_exists('hubloc_sitekey',$arr)) ? $arr['hubloc_sitekey'] : ''), - 'hubloc_updated' => ((array_key_exists('hubloc_updated',$arr)) ? $arr['hubloc_updated'] : NULL_DATE), - 'hubloc_connected' => ((array_key_exists('hubloc_connected',$arr)) ? $arr['hubloc_connected'] : NULL_DATE), - 'hubloc_primary' => ((array_key_exists('hubloc_primary',$arr)) ? $arr['hubloc_primary'] : 0), - 'hubloc_orphancheck' => ((array_key_exists('hubloc_orphancheck',$arr)) ? $arr['hubloc_orphancheck'] : 0), - 'hubloc_error' => ((array_key_exists('hubloc_error',$arr)) ? $arr['hubloc_error'] : 0), - 'hubloc_deleted' => ((array_key_exists('hubloc_deleted',$arr)) ? $arr['hubloc_deleted'] : 0) - ]; + $store = [ + 'hubloc_guid' => ((array_key_exists('hubloc_guid', $arr)) ? $arr['hubloc_guid'] : ''), + 'hubloc_guid_sig' => ((array_key_exists('hubloc_guid_sig', $arr)) ? $arr['hubloc_guid_sig'] : ''), + 'hubloc_id_url' => ((array_key_exists('hubloc_id_url', $arr)) ? $arr['hubloc_id_url'] : ''), + 'hubloc_hash' => ((array_key_exists('hubloc_hash', $arr)) ? $arr['hubloc_hash'] : ''), + 'hubloc_addr' => ((array_key_exists('hubloc_addr', $arr)) ? $arr['hubloc_addr'] : ''), + 'hubloc_network' => ((array_key_exists('hubloc_network', $arr)) ? $arr['hubloc_network'] : ''), + 'hubloc_flags' => ((array_key_exists('hubloc_flags', $arr)) ? $arr['hubloc_flags'] : 0), + 'hubloc_status' => ((array_key_exists('hubloc_status', $arr)) ? $arr['hubloc_status'] : 0), + 'hubloc_url' => ((array_key_exists('hubloc_url', $arr)) ? $arr['hubloc_url'] : ''), + 'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig', $arr)) ? $arr['hubloc_url_sig'] : ''), + 'hubloc_site_id' => ((array_key_exists('hubloc_site_id', $arr)) ? $arr['hubloc_site_id'] : ''), + 'hubloc_host' => ((array_key_exists('hubloc_host', $arr)) ? $arr['hubloc_host'] : ''), + 'hubloc_callback' => ((array_key_exists('hubloc_callback', $arr)) ? $arr['hubloc_callback'] : ''), + 'hubloc_connect' => ((array_key_exists('hubloc_connect', $arr)) ? $arr['hubloc_connect'] : ''), + 'hubloc_sitekey' => ((array_key_exists('hubloc_sitekey', $arr)) ? $arr['hubloc_sitekey'] : ''), + 'hubloc_updated' => ((array_key_exists('hubloc_updated', $arr)) ? $arr['hubloc_updated'] : NULL_DATE), + 'hubloc_connected' => ((array_key_exists('hubloc_connected', $arr)) ? $arr['hubloc_connected'] : NULL_DATE), + 'hubloc_primary' => ((array_key_exists('hubloc_primary', $arr)) ? $arr['hubloc_primary'] : 0), + 'hubloc_orphancheck' => ((array_key_exists('hubloc_orphancheck', $arr)) ? $arr['hubloc_orphancheck'] : 0), + 'hubloc_error' => ((array_key_exists('hubloc_error', $arr)) ? $arr['hubloc_error'] : 0), + 'hubloc_deleted' => ((array_key_exists('hubloc_deleted', $arr)) ? $arr['hubloc_deleted'] : 0) + ]; - return create_table_from_array('hubloc', $store); + return create_table_from_array('hubloc', $store); } -function site_store_lowlevel($arr) { +function site_store_lowlevel($arr) +{ - $store = [ - 'site_url' => ((array_key_exists('site_url',$arr)) ? $arr['site_url'] : ''), - 'site_access' => ((array_key_exists('site_access',$arr)) ? $arr['site_access'] : 0), - 'site_flags' => ((array_key_exists('site_flags',$arr)) ? $arr['site_flags'] : 0), - 'site_update' => ((array_key_exists('site_update',$arr)) ? $arr['site_update'] : NULL_DATE), - 'site_pull' => ((array_key_exists('site_pull',$arr)) ? $arr['site_pull'] : NULL_DATE), - 'site_sync' => ((array_key_exists('site_sync',$arr)) ? $arr['site_sync'] : NULL_DATE), - 'site_directory' => ((array_key_exists('site_directory',$arr)) ? $arr['site_directory'] : ''), - 'site_register' => ((array_key_exists('site_register',$arr)) ? $arr['site_register'] : 0), - 'site_sellpage' => ((array_key_exists('site_sellpage',$arr)) ? $arr['site_sellpage'] : ''), - 'site_location' => ((array_key_exists('site_location',$arr)) ? $arr['site_location'] : ''), - 'site_realm' => ((array_key_exists('site_realm',$arr)) ? $arr['site_realm'] : ''), - 'site_valid' => ((array_key_exists('site_valid',$arr)) ? $arr['site_valid'] : 0), - 'site_dead' => ((array_key_exists('site_dead',$arr)) ? $arr['site_dead'] : 0), - 'site_type' => ((array_key_exists('site_type',$arr)) ? $arr['site_type'] : 0), - 'site_project' => ((array_key_exists('site_project',$arr)) ? $arr['site_project'] : ''), - 'site_version' => ((array_key_exists('site_version',$arr)) ? $arr['site_version'] : ''), - 'site_crypto' => ((array_key_exists('site_crypto',$arr)) ? $arr['site_crypto'] : '') - ]; + $store = [ + 'site_url' => ((array_key_exists('site_url', $arr)) ? $arr['site_url'] : ''), + 'site_access' => ((array_key_exists('site_access', $arr)) ? $arr['site_access'] : 0), + 'site_flags' => ((array_key_exists('site_flags', $arr)) ? $arr['site_flags'] : 0), + 'site_update' => ((array_key_exists('site_update', $arr)) ? $arr['site_update'] : NULL_DATE), + 'site_pull' => ((array_key_exists('site_pull', $arr)) ? $arr['site_pull'] : NULL_DATE), + 'site_sync' => ((array_key_exists('site_sync', $arr)) ? $arr['site_sync'] : NULL_DATE), + 'site_directory' => ((array_key_exists('site_directory', $arr)) ? $arr['site_directory'] : ''), + 'site_register' => ((array_key_exists('site_register', $arr)) ? $arr['site_register'] : 0), + 'site_sellpage' => ((array_key_exists('site_sellpage', $arr)) ? $arr['site_sellpage'] : ''), + 'site_location' => ((array_key_exists('site_location', $arr)) ? $arr['site_location'] : ''), + 'site_realm' => ((array_key_exists('site_realm', $arr)) ? $arr['site_realm'] : ''), + 'site_valid' => ((array_key_exists('site_valid', $arr)) ? $arr['site_valid'] : 0), + 'site_dead' => ((array_key_exists('site_dead', $arr)) ? $arr['site_dead'] : 0), + 'site_type' => ((array_key_exists('site_type', $arr)) ? $arr['site_type'] : 0), + 'site_project' => ((array_key_exists('site_project', $arr)) ? $arr['site_project'] : ''), + 'site_version' => ((array_key_exists('site_version', $arr)) ? $arr['site_version'] : ''), + 'site_crypto' => ((array_key_exists('site_crypto', $arr)) ? $arr['site_crypto'] : '') + ]; - return create_table_from_array('site', $store); + return create_table_from_array('site', $store); } -function prune_hub_reinstalls() { +function prune_hub_reinstalls() +{ - $r = q("select site_url from site where site_type = %d", - intval(SITE_TYPE_ZOT) - ); - if($r) { - foreach($r as $rr) { - $x = q("select count(*) as t, hubloc_sitekey, max(hubloc_connected) as c from hubloc where hubloc_url = '%s' group by hubloc_sitekey order by c", - dbesc($rr['site_url']) - ); + $r = q( + "select site_url from site where site_type = %d", + intval(SITE_TYPE_ZOT) + ); + if ($r) { + foreach ($r as $rr) { + $x = q( + "select count(*) as t, hubloc_sitekey, max(hubloc_connected) as c from hubloc where hubloc_url = '%s' group by hubloc_sitekey order by c", + dbesc($rr['site_url']) + ); - // see if this url has more than one sitekey, indicating it has been re-installed. + // see if this url has more than one sitekey, indicating it has been re-installed. - if(count($x) > 1) { - $d1 = datetime_convert('UTC', 'UTC', $x[0]['c']); - $d2 = datetime_convert('UTC', 'UTC', 'now - 3 days'); + if (count($x) > 1) { + $d1 = datetime_convert('UTC', 'UTC', $x[0]['c']); + $d2 = datetime_convert('UTC', 'UTC', 'now - 3 days'); - // allow some slop period, say 3 days - just in case this is a glitch or transient occurrence - // Then remove any hublocs pointing to the oldest entry. + // allow some slop period, say 3 days - just in case this is a glitch or transient occurrence + // Then remove any hublocs pointing to the oldest entry. - if(($d1 < $d2) && ($x[0]['hubloc_sitekey'])) { - logger('prune_hub_reinstalls: removing dead hublocs at ' . $rr['site_url']); - $y = q("delete from hubloc where hubloc_sitekey = '%s'", - dbesc($x[0]['hubloc_sitekey']) - ); - } - } - } - } + if (($d1 < $d2) && ($x[0]['hubloc_sitekey'])) { + logger('prune_hub_reinstalls: removing dead hublocs at ' . $rr['site_url']); + $y = q( + "delete from hubloc where hubloc_sitekey = '%s'", + dbesc($x[0]['hubloc_sitekey']) + ); + } + } + } + } } @@ -116,60 +123,70 @@ function prune_hub_reinstalls() { * of an old bug or maybe a regression in some newer code. In any event, they * mess up communications and we have to take action if we find any. */ -function remove_obsolete_hublocs() { +function remove_obsolete_hublocs() +{ - logger('remove_obsolete_hublocs', LOGGER_DEBUG); + logger('remove_obsolete_hublocs', LOGGER_DEBUG); - // First make sure we have any hublocs (at all) with this URL and sitekey. - // We don't want to perform this operation while somebody is in the process - // of renaming their hub or installing certs. + // First make sure we have any hublocs (at all) with this URL and sitekey. + // We don't want to perform this operation while somebody is in the process + // of renaming their hub or installing certs. - $r = q("select hubloc_id from hubloc where hubloc_url = '%s' and hubloc_sitekey = '%s'", - dbesc(z_root()), - dbesc(get_config('system', 'pubkey')) - ); - if((! $r) || (! count($r))) - return; + $r = q( + "select hubloc_id from hubloc where hubloc_url = '%s' and hubloc_sitekey = '%s'", + dbesc(z_root()), + dbesc(get_config('system', 'pubkey')) + ); + if ((! $r) || (! count($r))) { + return; + } - // Good. We have at least one *valid* hubloc. + // Good. We have at least one *valid* hubloc. - // Do we have any invalid ones? + // Do we have any invalid ones? - $r = q("select hubloc_id from hubloc where hubloc_sitekey = '%s' and hubloc_url != '%s'", - dbesc(get_config('system', 'pubkey')), - dbesc(z_root()) - ); - $p = q("select hubloc_id from hubloc where hubloc_sitekey != '%s' and hubloc_url = '%s'", - dbesc(get_config('system', 'pubkey')), - dbesc(z_root()) - ); - if(is_array($r) && is_array($p)) - $r = array_merge($r, $p); + $r = q( + "select hubloc_id from hubloc where hubloc_sitekey = '%s' and hubloc_url != '%s'", + dbesc(get_config('system', 'pubkey')), + dbesc(z_root()) + ); + $p = q( + "select hubloc_id from hubloc where hubloc_sitekey != '%s' and hubloc_url = '%s'", + dbesc(get_config('system', 'pubkey')), + dbesc(z_root()) + ); + if (is_array($r) && is_array($p)) { + $r = array_merge($r, $p); + } - if(! $r) - return; + if (! $r) { + return; + } - // We've got invalid hublocs. Get rid of them. + // We've got invalid hublocs. Get rid of them. - logger('remove_obsolete_hublocs: removing ' . count($r) . ' hublocs.'); + logger('remove_obsolete_hublocs: removing ' . count($r) . ' hublocs.'); - $interval = ((get_config('system', 'delivery_interval') !== false) - ? intval(get_config('system', 'delivery_interval')) : 2 ); + $interval = ((get_config('system', 'delivery_interval') !== false) + ? intval(get_config('system', 'delivery_interval')) : 2 ); - foreach($r as $rr) { - q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d", - intval($rr['hubloc_id']) - ); + foreach ($r as $rr) { + q( + "update hubloc set hubloc_deleted = 1 where hubloc_id = %d", + intval($rr['hubloc_id']) + ); - $x = q("select channel_id from channel where channel_hash = '%s' limit 1", - dbesc($rr['hubloc_hash']) - ); - if($x) { - Run::Summon( [ 'Notifier', 'refresh_all', $x[0]['channel_id'] ] ); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } + $x = q( + "select channel_id from channel where channel_hash = '%s' limit 1", + dbesc($rr['hubloc_hash']) + ); + if ($x) { + Run::Summon([ 'Notifier', 'refresh_all', $x[0]['channel_id'] ]); + if ($interval) { + @time_sleep_until(microtime(true) + (float) $interval); + } + } + } } @@ -182,65 +199,71 @@ function remove_obsolete_hublocs() { * @param array $hubloc * @return bool */ -function hubloc_change_primary($hubloc) { +function hubloc_change_primary($hubloc) +{ - if(! is_array($hubloc)) { - logger('no hubloc'); - return false; - } + if (! is_array($hubloc)) { + logger('no hubloc'); + return false; + } - logger('setting primary: ' . $hubloc['hubloc_url'] . ((intval($hubloc['hubloc_primary'])) ? ' true' : ' false')); + logger('setting primary: ' . $hubloc['hubloc_url'] . ((intval($hubloc['hubloc_primary'])) ? ' true' : ' false')); - // See if this is a local hubloc and if so update the primary for the corresponding channel record. + // See if this is a local hubloc and if so update the primary for the corresponding channel record. - if($hubloc['hubloc_url'] === z_root()) { - $r = q("select channel_id from channel where channel_hash = '%s' limit 1", - dbesc($hubloc['hubloc_hash']) - ); - if($r) { - q("update channel set channel_primary = %d where channel_id = %d", - intval($hubloc['hubloc_primary']), - intval($r[0]['channel_id']) - ); - } - } + if ($hubloc['hubloc_url'] === z_root()) { + $r = q( + "select channel_id from channel where channel_hash = '%s' limit 1", + dbesc($hubloc['hubloc_hash']) + ); + if ($r) { + q( + "update channel set channel_primary = %d where channel_id = %d", + intval($hubloc['hubloc_primary']), + intval($r[0]['channel_id']) + ); + } + } - // we only need to proceed further if this particular hubloc is now primary + // we only need to proceed further if this particular hubloc is now primary - if(! (intval($hubloc['hubloc_primary']))) { - logger('not primary: ' . $hubloc['hubloc_url']); - return false; - } + if (! (intval($hubloc['hubloc_primary']))) { + logger('not primary: ' . $hubloc['hubloc_url']); + return false; + } - // do we even have an xchan for this hubloc and if so is it already set as primary? + // do we even have an xchan for this hubloc and if so is it already set as primary? - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($hubloc['hubloc_hash']) - ); - if(! $r) { - logger('xchan not found'); - return false; - } - if($r[0]['xchan_addr'] === $hubloc['hubloc_addr']) { - logger('xchan already changed'); - return false; - } + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($hubloc['hubloc_hash']) + ); + if (! $r) { + logger('xchan not found'); + return false; + } + if ($r[0]['xchan_addr'] === $hubloc['hubloc_addr']) { + logger('xchan already changed'); + return false; + } - $url = $hubloc['hubloc_url']; - $lwebbie = substr($hubloc['hubloc_addr'], 0, strpos($hubloc['hubloc_addr'], '@')); + $url = $hubloc['hubloc_url']; + $lwebbie = substr($hubloc['hubloc_addr'], 0, strpos($hubloc['hubloc_addr'], '@')); - $r = q("update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_follow = '%s', xchan_connurl = '%s' where xchan_hash = '%s'", - dbesc($hubloc['hubloc_addr']), - dbesc($url . '/channel/' . $lwebbie), - dbesc($url . '/follow?f=&url=%s'), - dbesc($url . '/poco/' . $lwebbie), - dbesc($hubloc['hubloc_hash']) - ); - if(! $r) - logger('xchan_update failed.'); + $r = q( + "update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_follow = '%s', xchan_connurl = '%s' where xchan_hash = '%s'", + dbesc($hubloc['hubloc_addr']), + dbesc($url . '/channel/' . $lwebbie), + dbesc($url . '/follow?f=&url=%s'), + dbesc($url . '/poco/' . $lwebbie), + dbesc($hubloc['hubloc_hash']) + ); + if (! $r) { + logger('xchan_update failed.'); + } - logger('primary hubloc changed.' . print_r($hubloc, true), LOGGER_DEBUG); - return true; + logger('primary hubloc changed.' . print_r($hubloc, true), LOGGER_DEBUG); + return true; } @@ -253,17 +276,20 @@ function hubloc_change_primary($hubloc) { * * @param string $posturl Hubloc callback url which to disable */ -function hubloc_mark_as_down($posturl) { - $r = q("update hubloc set hubloc_status = ( hubloc_status | %d ) where hubloc_callback = '%s'", - intval(HUBLOC_OFFLINE), - dbesc($posturl) - ); - // extract the baseurl and set site.site_dead to match - $m = parse_url($posturl); - $h = $m['scheme'] . '://' . $m['host']; - $r = q("update site set site_dead = 1 where site_url = '%s'", - dbesc($h) - ); +function hubloc_mark_as_down($posturl) +{ + $r = q( + "update hubloc set hubloc_status = ( hubloc_status | %d ) where hubloc_callback = '%s'", + intval(HUBLOC_OFFLINE), + dbesc($posturl) + ); + // extract the baseurl and set site.site_dead to match + $m = parse_url($posturl); + $h = $m['scheme'] . '://' . $m['host']; + $r = q( + "update site set site_dead = 1 where site_url = '%s'", + dbesc($h) + ); } @@ -272,40 +298,44 @@ function hubloc_mark_as_down($posturl) { * * @param string $netid network identity (typically xchan_hash or hubloc_hash) * @return string - */ + */ -function locations_by_netid($netid) { +function locations_by_netid($netid) +{ - $locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_deleted = 0 and site_dead = 0", - dbesc($netid) - ); + $locs = q( + "select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_deleted = 0 and site_dead = 0", + dbesc($netid) + ); - - return array_elm_to_str($locs,'location',', ','trim_and_unpunify'); + return array_elm_to_str($locs, 'location', ', ', 'trim_and_unpunify'); } -function ping_site($url) { +function ping_site($url) +{ - $ret = array('success' => false); + $ret = array('success' => false); - $r = Zotlabs\Lib\Zotfinger::exec($url); + $r = Zotlabs\Lib\Zotfinger::exec($url); - if(! $r['data']) { - $ret['message'] = 'no answer from ' . $url; - return $ret; - } + if (! $r['data']) { + $ret['message'] = 'no answer from ' . $url; + return $ret; + } - $ret['success'] = true; - return $ret; + $ret['success'] = true; + return $ret; } -function get_hubloc_addrs_by_hash($hash) { +function get_hubloc_addrs_by_hash($hash) +{ - return q("select hubloc_addr from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", - dbesc($hash) - ); -} \ No newline at end of file + return q( + "select hubloc_addr from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", + dbesc($hash) + ); +} diff --git a/include/import.php b/include/import.php index 95f695291..cb5b40d13 100644 --- a/include/import.php +++ b/include/import.php @@ -10,7 +10,6 @@ use Zotlabs\Daemon\Run; use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\PermissionLimits; - require_once('include/menu.php'); @@ -22,135 +21,140 @@ require_once('include/menu.php'); * @param int $seize * @return bool|array */ -function import_channel($channel, $account_id, $seize, $newname = '') { +function import_channel($channel, $account_id, $seize, $newname = '') +{ - 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); - } + 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); + } - if (isset($channel['channel_removed']) && intval($channel['channel_removed'])) { - notice( t('Unable to import a removed channel.') . EOL); - return false; - } + if (isset($channel['channel_removed']) && intval($channel['channel_removed'])) { + notice(t('Unable to import a removed channel.') . EOL); + return false; + } - // Ignore the hash provided and re-calculate + // Ignore the hash provided and re-calculate - $channel['channel_hash'] = Libzot::make_xchan_hash($channel['channel_guid'],$channel['channel_pubkey']); + $channel['channel_hash'] = Libzot::make_xchan_hash($channel['channel_guid'], $channel['channel_pubkey']); - if ($newname) { - $channel['channel_address'] = $newname; - } + if ($newname) { + $channel['channel_address'] = $newname; + } - // Check for duplicate channels + // Check for duplicate channels - $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']) - ); - if ($r && $r[0]['channel_guid'] == $channel['channel_guid'] && $r[0]['channel_pubkey'] === $channel['channel_pubkey'] && $r[0]['channel_hash'] === $channel['channel_hash']) { - // do not return a dead or deleted or system channel - if ($r[0]['channel_deleted'] > NULL_DATE - || intval($r[0]['channel_removed']) - || intval($r[0]['channel_moved']) - || intval($r[0]['channel_system'])) { - logger('attempt to import to a channel that was removed. ', print_r($channel,true)); - notice( t('A channel with these settings was discovered and is not usable as it was removed or reserved for system use. Import failed.') . EOL); - return false; - } - return $r[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']) + ); + if ($r && $r[0]['channel_guid'] == $channel['channel_guid'] && $r[0]['channel_pubkey'] === $channel['channel_pubkey'] && $r[0]['channel_hash'] === $channel['channel_hash']) { + // do not return a dead or deleted or system channel + if ( + $r[0]['channel_deleted'] > NULL_DATE + || intval($r[0]['channel_removed']) + || intval($r[0]['channel_moved']) + || intval($r[0]['channel_system']) + ) { + logger('attempt to import to a channel that was removed. ', print_r($channel, true)); + notice(t('A channel with these settings was discovered and is not usable as it was removed or reserved for system use. Import failed.') . EOL); + return false; + } + return $r[0]; + } - if (($r) || (check_webbie(array($channel['channel_address'])) !== $channel['channel_address'])) { - 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; - } - } - } + if (($r) || (check_webbie(array($channel['channel_address'])) !== $channel['channel_address'])) { + 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'] = $account_id; - $channel['channel_primary'] = (($seize) ? 1 : 0); + unset($channel['channel_id']); + $channel['channel_account_id'] = $account_id; + $channel['channel_primary'] = (($seize) ? 1 : 0); - if ($channel['channel_pageflags'] & PAGE_ALLOWCODE) { - if (! is_site_admin()) { - $channel['channel_pageflags'] = $channel['channel_pageflags'] ^ PAGE_ALLOWCODE; - } - } + if ($channel['channel_pageflags'] & PAGE_ALLOWCODE) { + if (! is_site_admin()) { + $channel['channel_pageflags'] = $channel['channel_pageflags'] ^ PAGE_ALLOWCODE; + } + } - // remove all the permissions related settings, we will import/upgrade them after the channel - // is created. + // remove all the permissions related settings, we will import/upgrade them after the channel + // is created. - $disallowed = [ - 'channel_id', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook', - 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall', - 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', - 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', - 'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt', - 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system' - ]; + $disallowed = [ + 'channel_id', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook', + 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall', + 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', + 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', + 'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt', + 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system' + ]; - $clean = []; - foreach ($channel as $k => $v) { - if (in_array($k,$disallowed)) { - continue; - } - $clean[$k] = $v; - } + $clean = []; + foreach ($channel as $k => $v) { + if (in_array($k, $disallowed)) { + continue; + } + $clean[$k] = $v; + } - if ($clean) { - channel_store_lowlevel($clean); - } + if ($clean) { + channel_store_lowlevel($clean); + } - $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", - intval($account_id), - 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 false; - } + $r = q( + "select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", + intval($account_id), + 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 false; + } - // extract the permissions from the original imported array and use our new channel_id to set them - // These could be in the old channel permission stule or the new pconfig. We have a function to - // translate and store them no matter which they throw at us. + // extract the permissions from the original imported array and use our new channel_id to set them + // These could be in the old channel permission stule or the new pconfig. We have a function to + // translate and store them no matter which they throw at us. - $channel['channel_id'] = $r[0]['channel_id']; + $channel['channel_id'] = $r[0]['channel_id']; - // reset - $channel = $r[0]; + // reset + $channel = $r[0]; - set_default_login_identity($account_id,$channel['channel_id'],false); - logger('import step 1'); - $_SESSION['import_step'] = 1; + set_default_login_identity($account_id, $channel['channel_id'], false); + logger('import step 1'); + $_SESSION['import_step'] = 1; - return $channel; + return $channel; } /** @@ -159,168 +163,177 @@ function import_channel($channel, $account_id, $seize, $newname = '') { * @param array $channel * @param array $configs */ -function import_config($channel, $configs) { +function import_config($channel, $configs) +{ - if ($channel && $configs) { - foreach ($configs as $config) { - unset($config['id']); - $config['uid'] = $channel['channel_id']; - if ($config['cat'] === 'system' && $config['k'] === 'import_system_apps') { - continue; - } - set_pconfig($channel['channel_id'],$config['cat'],$config['k'],$config['v']); - } + if ($channel && $configs) { + foreach ($configs as $config) { + unset($config['id']); + $config['uid'] = $channel['channel_id']; + if ($config['cat'] === 'system' && $config['k'] === 'import_system_apps') { + continue; + } + set_pconfig($channel['channel_id'], $config['cat'], $config['k'], $config['v']); + } - load_pconfig($channel['channel_id']); - $permissions_role = get_pconfig($channel['channel_id'],'system','permissions_role'); - if ($permissions_role === 'social_federation') { - // Convert Hubzilla's social_federation role to 'social' with relaxed comment permissions - set_pconfig($channel['channel_id'],'systems','permissions_role','social'); - PermissionLimits::Set($channel['channel_id'],'post_comments', PERMS_AUTHED); - } - else { - // If the requested permissions_role doesn't exist on this system, - // convert it to 'social' - - $role_permissions = PermissionRoles::role_perms($permissions_role); + load_pconfig($channel['channel_id']); + $permissions_role = get_pconfig($channel['channel_id'], 'system', 'permissions_role'); + if ($permissions_role === 'social_federation') { + // Convert Hubzilla's social_federation role to 'social' with relaxed comment permissions + set_pconfig($channel['channel_id'], 'systems', 'permissions_role', 'social'); + PermissionLimits::Set($channel['channel_id'], 'post_comments', PERMS_AUTHED); + } else { + // If the requested permissions_role doesn't exist on this system, + // convert it to 'social' - if (! $role_permissions) { - set_pconfig($channel['channel_id'],'system','permissions_role','social'); - } - } + $role_permissions = PermissionRoles::role_perms($permissions_role); - } + if (! $role_permissions) { + set_pconfig($channel['channel_id'], 'system', 'permissions_role', 'social'); + } + } + } } -function import_atoken($channel, $atokens) { - if ($channel && $atokens) { - foreach ($atokens as $atoken) { - unset($atoken['atoken_id']); - $atoken['atoken_aid'] = $channel['channel_account_id']; - $atoken['atoken_uid'] = $channel['channel_id']; - create_table_from_array('atoken', $atoken); - } - } +function import_atoken($channel, $atokens) +{ + if ($channel && $atokens) { + foreach ($atokens as $atoken) { + unset($atoken['atoken_id']); + $atoken['atoken_aid'] = $channel['channel_account_id']; + $atoken['atoken_uid'] = $channel['channel_id']; + create_table_from_array('atoken', $atoken); + } + } } -function sync_atoken($channel, $atokens) { +function sync_atoken($channel, $atokens) +{ - if ($channel && $atokens) { - foreach ($atokens as $atoken) { - unset($atoken['atoken_id']); - $atoken['atoken_aid'] = $channel['channel_account_id']; - $atoken['atoken_uid'] = $channel['channel_id']; + if ($channel && $atokens) { + foreach ($atokens as $atoken) { + unset($atoken['atoken_id']); + $atoken['atoken_aid'] = $channel['channel_account_id']; + $atoken['atoken_uid'] = $channel['channel_id']; - if ($atoken['deleted']) { - q("delete from atoken where atoken_uid = %d and atoken_guid = '%s' ", - intval($atoken['atoken_uid']), - dbesc($atoken['atoken_guid']) - ); - continue; - } + if ($atoken['deleted']) { + q( + "delete from atoken where atoken_uid = %d and atoken_guid = '%s' ", + intval($atoken['atoken_uid']), + dbesc($atoken['atoken_guid']) + ); + continue; + } - $r = q("select * from atoken where atoken_uid = %d and atoken_guid = '%s' ", - intval($atoken['atoken_uid']), - dbesc($atoken['atoken_guid']) - ); - if (! $r) { - create_table_from_array('atoken', $atoken); - } - else { - $columns = db_columns('atoken'); - foreach ($atoken as $k => $v) { - if (! in_array($k,$columns)) { - continue; - } - - if (in_array($k, ['atoken_guid','atoken_uid','atoken_aid'])) { - continue; - } - - $r = q("UPDATE atoken SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE atoken_guid = '%s' AND atoken_uid = %d", - dbesc($k), - dbesc($v), - dbesc($atoken['atoken_guid']), - intval($channel['channel_id']) - ); - } - } - } - } + $r = q( + "select * from atoken where atoken_uid = %d and atoken_guid = '%s' ", + intval($atoken['atoken_uid']), + dbesc($atoken['atoken_guid']) + ); + if (! $r) { + create_table_from_array('atoken', $atoken); + } else { + $columns = db_columns('atoken'); + foreach ($atoken as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } + + if (in_array($k, ['atoken_guid','atoken_uid','atoken_aid'])) { + continue; + } + + $r = q( + "UPDATE atoken SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE atoken_guid = '%s' AND atoken_uid = %d", + dbesc($k), + dbesc($v), + dbesc($atoken['atoken_guid']), + intval($channel['channel_id']) + ); + } + } + } + } } -function import_xign($channel, $xigns) { +function import_xign($channel, $xigns) +{ - if ($channel && $xigns) { - foreach ($xigns as $xign) { - unset($xign['id']); - $xign['uid'] = $channel['channel_id']; - create_table_from_array('xign', $xign); - } - } + if ($channel && $xigns) { + foreach ($xigns as $xign) { + unset($xign['id']); + $xign['uid'] = $channel['channel_id']; + create_table_from_array('xign', $xign); + } + } } -function sync_xign($channel, $xigns) { +function sync_xign($channel, $xigns) +{ - if ($channel && $xigns) { - foreach ($xigns as $xign) { - unset($xign['id']); - $xign['uid'] = $channel['channel_id']; - if (! $xign['xchan']) { - continue; - } - if ($xign['deleted']) { - q("delete from xign where uid = %d and xchan = '%s' ", - intval($xign['uid']), - dbesc($xign['xchan']) - ); - continue; - } + if ($channel && $xigns) { + foreach ($xigns as $xign) { + unset($xign['id']); + $xign['uid'] = $channel['channel_id']; + if (! $xign['xchan']) { + continue; + } + if ($xign['deleted']) { + q( + "delete from xign where uid = %d and xchan = '%s' ", + intval($xign['uid']), + dbesc($xign['xchan']) + ); + continue; + } - $r = q("select * from xign where uid = %d and xchan = '%s' ", - intval($xign['uid']), - dbesc($xign['xchan']) - ); - if (! $r) { - create_table_from_array('xign', $xign); - } - } - } + $r = q( + "select * from xign where uid = %d and xchan = '%s' ", + intval($xign['uid']), + dbesc($xign['xchan']) + ); + if (! $r) { + create_table_from_array('xign', $xign); + } + } + } } -function import_block($channel, $blocks) { +function import_block($channel, $blocks) +{ - if ($channel && $blocks) { - foreach ($blocks as $block) { - unset($block['block_id']); - $block['block_channel_id'] = $channel['channel_id']; - LibBlock::store($block); - } - } + if ($channel && $blocks) { + foreach ($blocks as $block) { + unset($block['block_id']); + $block['block_channel_id'] = $channel['channel_id']; + LibBlock::store($block); + } + } } -function sync_block($channel, $blocks) { +function sync_block($channel, $blocks) +{ - if ($channel && $blocks) { - foreach ($blocks as $block) { - unset($block['block_id']); - $block['block_channel_id'] = $channel['channel_id']; - if (! $block['block_entity']) { - continue; - } - if ($block['deleted']) { - LibBlock::remove($channel['channel_id'],$block['block_entity']); - continue; - } - LibBlock::store($channel['channel_id'],$block); - } - } + if ($channel && $blocks) { + foreach ($blocks as $block) { + unset($block['block_id']); + $block['block_channel_id'] = $channel['channel_id']; + if (! $block['block_entity']) { + continue; + } + if ($block['deleted']) { + LibBlock::remove($channel['channel_id'], $block['block_entity']); + continue; + } + LibBlock::store($channel['channel_id'], $block); + } + } } @@ -332,34 +345,34 @@ function sync_block($channel, $blocks) { * @param array $channel * @param array $profiles */ -function import_profiles($channel, $profiles) { +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']; + if ($channel && $profiles) { + foreach ($profiles as $profile) { + unset($profile['id']); + $profile['aid'] = get_account_id(); + $profile['uid'] = $channel['channel_id']; - convert_oldfields($profile,'name','fullname'); - convert_oldfields($profile,'with','partner'); - convert_oldfields($profile,'work','employment'); + convert_oldfields($profile, 'name', 'fullname'); + convert_oldfields($profile, 'with', 'partner'); + convert_oldfields($profile, 'work', 'employment'); - /** - * @TODO put all the applicable photos into the export. - */ + /** + * @TODO put all the applicable photos into the export. + */ - if ((strpos($profile['thumb'],'/photo/profile/l/') !== false) || intval($profile['is_default'])) { - $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id']; - $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id']; - } - else { - $profile['photo'] = z_root() . '/photo/' . basename($profile['photo']); - $profile['thumb'] = z_root() . '/photo/' . basename($profile['thumb']); - } + if ((strpos($profile['thumb'], '/photo/profile/l/') !== false) || intval($profile['is_default'])) { + $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id']; + $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id']; + } else { + $profile['photo'] = z_root() . '/photo/' . basename($profile['photo']); + $profile['thumb'] = z_root() . '/photo/' . basename($profile['thumb']); + } - profile_store_lowlevel($profile); - } - } + profile_store_lowlevel($profile); + } + } } /** @@ -370,67 +383,68 @@ function import_profiles($channel, $profiles) { * @param bool $seize * @param bool $moving (optional) default false */ - -function import_hublocs($channel, $hublocs, $seize, $moving = false) { - if ($channel && $hublocs) { - foreach ($hublocs as $hubloc) { +function import_hublocs($channel, $hublocs, $seize, $moving = false) +{ - // Provide backward compatibility for zot11 based projects - - if ($hubloc['hubloc_network'] === 'nomad' && version_compare(ZOT_REVISION, '10.0') <= 0) { - $hubloc['hubloc_network'] = 'zot6'; - } + if ($channel && $hublocs) { + foreach ($hublocs as $hubloc) { + // Provide backward compatibility for zot11 based projects - // verify the hash. We can only do this if we already stored the xchan corresponding to this hubloc - // as we need the public key from there + if ($hubloc['hubloc_network'] === 'nomad' && version_compare(ZOT_REVISION, '10.0') <= 0) { + $hubloc['hubloc_network'] = 'zot6'; + } - if (in_array($hubloc['hubloc_network'],['nomad','zot6'])) { - $x = q("select xchan_pubkey from xchan where xchan_guid = '%s' and xchan_hash = '%s'", - dbesc($hubloc['hubloc_guid']), - dbesc($hubloc['hubloc_hash']) - ); + // verify the hash. We can only do this if we already stored the xchan corresponding to this hubloc + // as we need the public key from there - if (! $x) { - logger('hubloc could not be verified. ' . print_r($hubloc,true)); - continue; - } - $hash = Libzot::make_xchan_hash($hubloc['hubloc_guid'],$x[0]['xchan_pubkey']); - if ($hash !== $hubloc['hubloc_hash']) { - logger('forged hubloc: ' . print_r($hubloc,true)); - continue; - } - } + if (in_array($hubloc['hubloc_network'], ['nomad','zot6'])) { + $x = q( + "select xchan_pubkey from xchan where xchan_guid = '%s' and xchan_hash = '%s'", + dbesc($hubloc['hubloc_guid']), + dbesc($hubloc['hubloc_hash']) + ); - if ($moving && $hubloc['hubloc_hash'] === $channel['channel_hash'] && $hubloc['hubloc_url'] !== z_root()) { - $hubloc['hubloc_deleted'] = 1; - } + if (! $x) { + logger('hubloc could not be verified. ' . print_r($hubloc, true)); + continue; + } + $hash = Libzot::make_xchan_hash($hubloc['hubloc_guid'], $x[0]['xchan_pubkey']); + if ($hash !== $hubloc['hubloc_hash']) { + logger('forged hubloc: ' . print_r($hubloc, true)); + continue; + } + } - $arr = [ - 'id' => $hubloc['hubloc_guid'], - 'id_sig' => $hubloc['hubloc_guid_sig'], - 'location' => $hubloc['hubloc_url'], - 'location_sig' => $hubloc['hubloc_url_sig'], - 'site_id' => $hubloc['hubloc_site_id'] - ]; + if ($moving && $hubloc['hubloc_hash'] === $channel['channel_hash'] && $hubloc['hubloc_url'] !== z_root()) { + $hubloc['hubloc_deleted'] = 1; + } - if (($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize)) { - $hubloc['hubloc_primary'] = 0; - } + $arr = [ + 'id' => $hubloc['hubloc_guid'], + 'id_sig' => $hubloc['hubloc_guid_sig'], + 'location' => $hubloc['hubloc_url'], + 'location_sig' => $hubloc['hubloc_url_sig'], + 'site_id' => $hubloc['hubloc_site_id'] + ]; - if (($x = Libzot::gethub($arr,false)) === false) { - unset($hubloc['hubloc_id']); - hubloc_store_lowlevel($hubloc); - } - else { - q("UPDATE hubloc set hubloc_primary = %d, hubloc_deleted = %d where hubloc_id = %d", - intval($hubloc['hubloc_primary']), - intval($hubloc['hubloc_deleted']), - intval($x['hubloc_id']) - ); - } - } - } + if (($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize)) { + $hubloc['hubloc_primary'] = 0; + } + + if (($x = Libzot::gethub($arr, false)) === false) { + unset($hubloc['hubloc_id']); + hubloc_store_lowlevel($hubloc); + } else { + q( + "UPDATE hubloc set hubloc_primary = %d, hubloc_deleted = %d where hubloc_id = %d", + intval($hubloc['hubloc_primary']), + intval($hubloc['hubloc_deleted']), + intval($x['hubloc_id']) + ); + } + } + } } /** @@ -439,31 +453,31 @@ function import_hublocs($channel, $hublocs, $seize, $moving = false) { * @param array $channel * @param array $objs */ -function import_objs($channel, $objs) { +function import_objs($channel, $objs) +{ - if ($channel && $objs) { - foreach ($objs as $obj) { + if ($channel && $objs) { + foreach ($objs as $obj) { + $baseurl = $obj['obj_baseurl']; + unset($obj['obj_id']); + unset($obj['obj_baseurl']); - $baseurl = $obj['obj_baseurl']; - unset($obj['obj_id']); - unset($obj['obj_baseurl']); + $obj['obj_channel'] = $channel['channel_id']; - $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 ($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_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true); + if ($x) { + $obj['obj_imgurl'] = $x[0]; + } + } - if ($obj['obj_imgurl']) { - $x = import_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true); - if ($x) { - $obj['obj_imgurl'] = $x[0]; - } - } - - create_table_from_array('obj', $obj); - } - } + create_table_from_array('obj', $obj); + } + } } /** @@ -472,76 +486,78 @@ function import_objs($channel, $objs) { * @param array $channel * @param array $objs */ -function sync_objs($channel, $objs) { +function sync_objs($channel, $objs) +{ - if ($channel && $objs) { - $columns = db_columns('obj'); + if ($channel && $objs) { + $columns = db_columns('obj'); - foreach ($objs as $obj) { + 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", + dbesc($obj['obj_obj']), + intval($channel['channel_id']) + ); + continue; + } - 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", - dbesc($obj['obj_obj']), - intval($channel['channel_id']) - ); - continue; - } + $baseurl = $obj['obj_baseurl']; + unset($obj['obj_id']); + unset($obj['obj_baseurl']); - $baseurl = $obj['obj_baseurl']; - unset($obj['obj_id']); - unset($obj['obj_baseurl']); + $obj['obj_channel'] = $channel['channel_id']; - $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 ($baseurl && (strpos($obj['obj_url'], $baseurl . '/thing/') !== false)) { - $obj['obj_url'] = str_replace($baseurl, z_root(), $obj['obj_url']); - } + $exists = false; - $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; + } - $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; + } - $exists = true; - } + if ($obj['obj_imgurl']) { + // import_xchan_photo() has a switch to store thing images + $x = import_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true); + if ($x) { + $obj['obj_imgurl'] = $x[0]; + } + } - if ($obj['obj_imgurl']) { - // import_xchan_photo() has a switch to store thing images - $x = import_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true); - if ($x) { - $obj['obj_imgurl'] = $x[0]; - } - } + $hash = $obj['obj_obj']; - $hash = $obj['obj_obj']; + if ($exists) { + unset($obj['obj_obj']); - if ($exists) { - unset($obj['obj_obj']); + foreach ($obj as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - foreach ($obj as $k => $v) { - if (! in_array($k,$columns)) { - continue; - } - - $r = q("UPDATE obj SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE obj_obj = '%s' AND obj_channel = %d", - dbesc($k), - dbesc($v), - dbesc($hash), - intval($channel['channel_id']) - ); - } - } - else { - create_table_from_array('obj', $obj); - } - } - } + $r = q( + "UPDATE obj SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE obj_obj = '%s' AND obj_channel = %d", + dbesc($k), + dbesc($v), + dbesc($hash), + intval($channel['channel_id']) + ); + } + } else { + create_table_from_array('obj', $obj); + } + } + } } /** @@ -550,52 +566,53 @@ function sync_objs($channel, $objs) { * @param array $channel * @param array $apps */ -function import_apps($channel, $apps) { +function import_apps($channel, $apps) +{ - if ($channel && $apps) { - foreach ($apps as $app) { + if ($channel && $apps) { + foreach ($apps as $app) { + if (array_key_exists('app_system', $app) && intval($app['app_system'])) { + continue; + } - if (array_key_exists('app_system',$app) && intval($app['app_system'])) { - continue; - } + $term = ((array_key_exists('term', $app) && is_array($app['term'])) ? $app['term'] : null); - $term = ((array_key_exists('term',$app) && is_array($app['term'])) ? $app['term'] : null); + unset($app['id']); + unset($app['app_channel']); + unset($app['term']); - unset($app['id']); - unset($app['app_channel']); - unset($app['term']); + $app['app_channel'] = $channel['channel_id']; - $app['app_channel'] = $channel['channel_id']; + if ($app['app_photo']) { + // overload import_xchan_photo() + $x = import_remote_xchan_photo($app['app_photo'], $channel['channel_hash'], true); + if ($x) { + $app['app_photo'] = $x[0]; + } + } - if ($app['app_photo']) { - // overload import_xchan_photo() - $x = import_remote_xchan_photo($app['app_photo'], $channel['channel_hash'], true); - if ($x) { - $app['app_photo'] = $x[0]; - } - } + $hash = $app['app_id']; - $hash = $app['app_id']; + create_table_from_array('app', $app); - create_table_from_array('app', $app); + if ($term) { + $x = q( + "select * from app where app_id = '%s' and app_channel = %d limit 1", + dbesc($hash), + intval($channel['channel_id']) + ); + if ($x) { + foreach ($term as $t) { + if (array_key_exists('type', $t)) { + $t['ttype'] = $t['type']; + } - if ($term) { - $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($hash), - intval($channel['channel_id']) - ); - if ($x) { - foreach ($term as $t) { - if (array_key_exists('type',$t)) { - $t['ttype'] = $t['type']; - } - - store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); - } - } - } - } - } + store_item_tag($channel['channel_id'], $x[0]['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url'])); + } + } + } + } + } } /** @@ -604,180 +621,183 @@ function import_apps($channel, $apps) { * @param array $channel * @param array $apps */ -function sync_apps($channel, $apps) { +function sync_apps($channel, $apps) +{ - if ($channel && $apps) { + if ($channel && $apps) { + $columns = db_columns('app'); - $columns = db_columns('app'); + foreach ($apps as $app) { + $exists = false; + $term = ((array_key_exists('term', $app)) ? $app['term'] : null); - foreach ($apps as $app) { + if (array_key_exists('app_system', $app) && intval($app['app_system'])) { + continue; + } - $exists = false; - $term = ((array_key_exists('term',$app)) ? $app['term'] : null); + $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) { + $exists = $x[0]; + } - if (array_key_exists('app_system',$app) && intval($app['app_system'])) { - continue; - } + 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", + dbesc($app['app_id']), + intval($channel['channel_id']) + ); + if ($exists) { + q( + "delete from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($exists['id']) + ); + } + continue; + } - $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) { - $exists = $x[0]; - } + unset($app['id']); + unset($app['app_channel']); + unset($app['term']); - 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", - dbesc($app['app_id']), - intval($channel['channel_id']) - ); - if ($exists) { - q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($exists['id']) - ); - } - continue; - } + if ($exists) { + q( + "delete from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($exists['id']) + ); + } - unset($app['id']); - unset($app['app_channel']); - unset($app['term']); + 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(); + } - if ($exists) { - q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($exists['id']) - ); - } + $app['app_channel'] = $channel['channel_id']; - 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(); - } + if ($app['app_photo']) { + // use import_xchan_photo() + $x = import_remote_xchan_photo($app['app_photo'], $channel['channel_hash'], true); + if ($x) { + $app['app_photo'] = $x[0]; + } + } - $app['app_channel'] = $channel['channel_id']; + if ($exists && $term) { + foreach ($term as $t) { + if (array_key_exists('type', $t)) { + $t['ttype'] = $t['type']; + } + store_item_tag($channel['channel_id'], $exists['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url'])); + } + } - if ($app['app_photo']) { - // use import_xchan_photo() - $x = import_remote_xchan_photo($app['app_photo'],$channel['channel_hash'],true); - if ($x) { - $app['app_photo'] = $x[0]; - } - } + if ($exists) { + if ($exists['app_edited'] >= $app['app_edited']) { + continue; + } + } + $hash = $app['app_id']; - if ($exists && $term) { - foreach ($term as $t) { - if (array_key_exists('type',$t)) { - $t['ttype'] = $t['type']; - } - store_item_tag($channel['channel_id'],$exists['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); - } - } + if ($exists) { + unset($app['app_id']); + foreach ($app as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - if ($exists) { - if ($exists['app_edited'] >= $app['app_edited']) { - continue; - } - } - $hash = $app['app_id']; + $r = q( + "UPDATE app SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE app_id = '%s' AND app_channel = %d", + dbesc($k), + dbesc($v), + dbesc($hash), + intval($channel['channel_id']) + ); + } + } else { + create_table_from_array('app', $app); - if ($exists) { - unset($app['app_id']); - foreach ($app as $k => $v) { - - if (! in_array($k,$columns)) { - continue; - } - - $r = q("UPDATE app SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE app_id = '%s' AND app_channel = %d", - dbesc($k), - dbesc($v), - dbesc($hash), - intval($channel['channel_id']) - ); - } - } - else { - create_table_from_array('app',$app); - - if ($term) { - $x = q("select * from app where app_id = '%s' and app_channel = %d", - dbesc($hash), - intval($channel['channel_id']) - ); - if ($x) { - foreach ($term as $t) { - if (array_key_exists('type',$t)) { - $t['ttype'] = $t['type']; - } - store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); - } - } - } - } - } - } + if ($term) { + $x = q( + "select * from app where app_id = '%s' and app_channel = %d", + dbesc($hash), + intval($channel['channel_id']) + ); + if ($x) { + foreach ($term as $t) { + if (array_key_exists('type', $t)) { + $t['ttype'] = $t['type']; + } + store_item_tag($channel['channel_id'], $x[0]['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url'])); + } + } + } + } + } + } } /** * @brief Import system apps. - * System apps from the original server may not exist on this system + * System apps from the original server may not exist on this system * (e.g. apps associated with addons that are not installed here). * Check the system apps that were provided in the import file to see if they * exist here and if so, install them locally. Preserve categories that * might have been added by this channel on the other server. - * Do not use any paths from the original as they will point to a different server. + * Do not use any paths from the original as they will point to a different server. * @param array $channel * @param array $apps */ -function import_sysapps($channel, $apps) { +function import_sysapps($channel, $apps) +{ - if ($channel && $apps) { + if ($channel && $apps) { + $sysapps = Apps::get_system_apps(false); - $sysapps = Apps::get_system_apps(false); + foreach ($apps as $app) { + if (array_key_exists('app_system', $app) && (! intval($app['app_system']))) { + continue; + } - foreach ($apps as $app) { + if (array_key_exists('app_deleted', $app) && (intval($app['app_deleted']))) { + continue; + } - if (array_key_exists('app_system',$app) && (! intval($app['app_system']))) { - continue; - } + $term = ((array_key_exists('term', $app) && is_array($app['term'])) ? $app['term'] : null); - if (array_key_exists('app_deleted',$app) && (intval($app['app_deleted']))) { - continue; - } + foreach ($sysapps as $sysapp) { + if ($app['app_id'] === hash('whirlpool', $sysapp['app_name'])) { + // install this app on this server + $newapp = $sysapp; + $newapp['uid'] = $channel['channel_id']; + $newapp['guid'] = hash('whirlpool', $newapp['name']); - $term = ((array_key_exists('term',$app) && is_array($app['term'])) ? $app['term'] : null); + $installed = q( + "select id from app where app_id = '%s' and app_channel = %d limit 1", + dbesc($newapp['guid']), + intval($channel['channel_id']) + ); + if ($installed) { + break; + } - foreach ($sysapps as $sysapp) { - if ($app['app_id'] === hash('whirlpool',$sysapp['app_name'])) { - // install this app on this server - $newapp = $sysapp; - $newapp['uid'] = $channel['channel_id']; - $newapp['guid'] = hash('whirlpool',$newapp['name']); - - $installed = q("select id from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($newapp['guid']), - intval($channel['channel_id']) - ); - if ($installed) { - break; - } - - $newapp['system'] = 1; - if ($term) { - $newapp['categories'] = array_elm_to_str($term,'term'); - } - Apps::app_install($channel['channel_id'],$newapp); - } - } - } - } + $newapp['system'] = 1; + if ($term) { + $newapp['categories'] = array_elm_to_str($term, 'term'); + } + Apps::app_install($channel['channel_id'], $newapp); + } + } + } + } } /** @@ -786,47 +806,46 @@ function import_sysapps($channel, $apps) { * @param array $channel * @param array $apps */ -function sync_sysapps($channel, $apps) { +function sync_sysapps($channel, $apps) +{ - $sysapps = Apps::get_system_apps(false); + $sysapps = Apps::get_system_apps(false); - if ($channel && $apps) { + if ($channel && $apps) { + $columns = db_columns('app'); - $columns = db_columns('app'); + foreach ($apps as $app) { + $exists = false; + $term = ((array_key_exists('term', $app)) ? $app['term'] : null); - foreach ($apps as $app) { + if (array_key_exists('app_system', $app) && (! intval($app['app_system']))) { + continue; + } - $exists = false; - $term = ((array_key_exists('term',$app)) ? $app['term'] : null); + foreach ($sysapps as $sysapp) { + if ($app['app_id'] === hash('whirlpool', $sysapp['app_name'])) { + if (array_key_exists('app_deleted', $app) && $app['app_deleted'] && $app['app_id']) { + q( + "update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", + dbesc($app['app_id']), + intval($channel['channel_id']) + ); + } else { + // install this app on this server + $newapp = $sysapp; + $newapp['uid'] = $channel['channel_id']; + $newapp['guid'] = hash('whirlpool', $newapp['name']); - if (array_key_exists('app_system',$app) && (! intval($app['app_system']))) { - continue; - } - - foreach ($sysapps as $sysapp) { - if ($app['app_id'] === hash('whirlpool',$sysapp['app_name'])) { - if (array_key_exists('app_deleted',$app) && $app['app_deleted'] && $app['app_id']) { - q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", - dbesc($app['app_id']), - intval($channel['channel_id']) - ); - } - else { - // install this app on this server - $newapp = $sysapp; - $newapp['uid'] = $channel['channel_id']; - $newapp['guid'] = hash('whirlpool',$newapp['name']); - - $newapp['system'] = 1; - if ($term) { - $newapp['categories'] = array_elm_to_str($term,'term'); - } - Apps::app_install($channel['channel_id'],$newapp); - } - } - } - } - } + $newapp['system'] = 1; + if ($term) { + $newapp['categories'] = array_elm_to_str($term, 'term'); + } + Apps::app_install($channel['channel_id'], $newapp); + } + } + } + } + } } @@ -839,25 +858,25 @@ function sync_sysapps($channel, $apps) { * @param array $channel * @param array $chatrooms */ -function import_chatrooms($channel, $chatrooms) { +function import_chatrooms($channel, $chatrooms) +{ - if ($channel && $chatrooms) { - foreach ($chatrooms as $chatroom) { + if ($channel && $chatrooms) { + foreach ($chatrooms as $chatroom) { + if (! $chatroom['cr_name']) { + continue; + } - if (! $chatroom['cr_name']) { - continue; - } + unset($chatroom['cr_id']); + unset($chatroom['cr_aid']); + unset($chatroom['cr_uid']); - 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']; - $chatroom['cr_aid'] = $channel['channel_account_id']; - $chatroom['cr_uid'] = $channel['channel_id']; - - create_table_from_array('chatroom', $chatroom); - } - } + create_table_from_array('chatroom', $chatroom); + } + } } /** @@ -866,74 +885,74 @@ function import_chatrooms($channel, $chatrooms) { * @param array $channel * @param array $chatrooms */ -function sync_chatrooms($channel, $chatrooms) { +function sync_chatrooms($channel, $chatrooms) +{ - if ($channel && $chatrooms) { + if ($channel && $chatrooms) { + $columns = db_columns('chatroom'); - $columns = db_columns('chatroom'); + foreach ($chatrooms as $chatroom) { + if (! $chatroom['cr_name']) { + continue; + } - foreach ($chatrooms as $chatroom) { + if (array_key_exists('cr_deleted', $chatroom) && $chatroom['cr_deleted']) { + q( + "delete from chatroom where cr_name = '%s' and cr_uid = %d", + dbesc($chatroom['cr_name']), + intval($channel['channel_id']) + ); + continue; + } - if (! $chatroom['cr_name']) { - continue; - } + unset($chatroom['cr_id']); + unset($chatroom['cr_aid']); + unset($chatroom['cr_uid']); - if (array_key_exists('cr_deleted',$chatroom) && $chatroom['cr_deleted']) { - q("delete from chatroom where cr_name = '%s' and cr_uid = %d", - dbesc($chatroom['cr_name']), - intval($channel['channel_id']) - ); - continue; - } + 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(); + } - 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']; - 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(); - } + $exists = false; - $chatroom['cr_aid'] = $channel['channel_account_id']; - $chatroom['cr_uid'] = $channel['channel_id']; + $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']; - $exists = false; + if ($exists) { + foreach ($chatroom as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - $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) { - - if (! in_array($k,$columns)) { - continue; - } - - $r = q("UPDATE chatroom SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE cr_name = '%s' AND cr_uid = %d", - dbesc($k), - dbesc($v), - dbesc($name), - intval($channel['channel_id']) - ); - } - } - else { - create_table_from_array('chatroom', $chatroom); - } - } - } + $r = q( + "UPDATE chatroom SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE cr_name = '%s' AND cr_uid = %d", + dbesc($k), + dbesc($v), + dbesc($name), + intval($channel['channel_id']) + ); + } + } else { + create_table_from_array('chatroom', $chatroom); + } + } + } } @@ -945,64 +964,66 @@ function sync_chatrooms($channel, $chatrooms) { * @param bool $sync default false * @param array $relocate default null */ -function import_items($channel, $items, $sync = false, $relocate = null) { +function import_items($channel, $items, $sync = false, $relocate = null) +{ - if ($channel && $items) { + if ($channel && $items) { + $allow_code = channel_codeallowed($channel['channel_id']); - $allow_code = channel_codeallowed($channel['channel_id']); + $deliver = false; // Don't deliver any messages or notifications when importing - $deliver = false; // Don't deliver any messages or notifications when importing + foreach ($items as $i) { + $item_result = false; + $item = get_item_elements($i, $allow_code); - foreach ($items as $i) { - $item_result = false; - $item = get_item_elements($i,$allow_code); + if (! $item) { + continue; + } - if (! $item) - continue; + if ($relocate && $item['mid'] === $item['parent_mid']) { + item_url_replace($channel, $item, $relocate['url'], z_root(), $relocate['channel_address']); + } - if ($relocate && $item['mid'] === $item['parent_mid']) { - item_url_replace($channel,$item,$relocate['url'],z_root(),$relocate['channel_address']); - } + $r = q( + "select id, edited from item where mid = '%s' and uid = %d limit 1", + dbesc($item['mid']), + intval($channel['channel_id']) + ); + if ($r) { + // flags may have changed and we are probably relocating the post, + // so force an update even if we have the same timestamp - $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_result = item_store_update($item, $allow_code, $deliver, false); + } + } else { + $item['aid'] = $channel['channel_account_id']; + $item['uid'] = $channel['channel_id']; + $item_result = item_store($item, $allow_code, $deliver, false); + } - // flags may have changed and we are probably relocating the post, - // so force an update even if we have the same timestamp + // preserve conversations you've been involved in from being expired - if ($item['edited'] >= $r[0]['edited']) { - $item['id'] = $r[0]['id']; - $item['uid'] = $channel['channel_id']; - $item_result = item_store_update($item,$allow_code,$deliver,false); - } - } - else { - $item['aid'] = $channel['channel_account_id']; - $item['uid'] = $channel['channel_id']; - $item_result = item_store($item,$allow_code,$deliver,false); - } + $stored = $item_result['item']; + if ( + (is_array($stored)) && ($stored['id'] != $stored['parent']) + && ($stored['author_xchan'] === $channel['channel_hash']) + ) { + retain_item($stored['item']['parent']); + } - // preserve conversations you've been involved in from being expired + fix_attached_permissions($channel['channel_id'], $item['body'], $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']); - $stored = $item_result['item']; - if ((is_array($stored)) && ($stored['id'] != $stored['parent']) - && ($stored['author_xchan'] === $channel['channel_hash'])) { - retain_item($stored['item']['parent']); - } - - fix_attached_permissions($channel['channel_id'],$item['body'],$item['allow_cid'],$item['allow_gid'],$item['deny_cid'],$item['deny_gid']); - - if ($sync && $item['item_wall']) { - // deliver singletons if we have any - if ($item_result && $item_result['success']) { - Run::Summon( [ 'Notifier','single_activity',$item_result['item_id'] ]); - } - } - } - } + if ($sync && $item['item_wall']) { + // deliver singletons if we have any + if ($item_result && $item_result['success']) { + Run::Summon([ 'Notifier','single_activity',$item_result['item_id'] ]); + } + } + } + } } /** @@ -1014,8 +1035,9 @@ function import_items($channel, $items, $sync = false, $relocate = null) { * @param array $items * @param array $relocate default null */ -function sync_items($channel, $items, $relocate = null) { - import_items($channel, $items, true, $relocate); +function sync_items($channel, $items, $relocate = null) +{ + import_items($channel, $items, true, $relocate); } @@ -1025,21 +1047,22 @@ function sync_items($channel, $items, $relocate = null) { * @param array $channel * @param array $events */ -function import_events($channel, $events) { +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']; - convert_oldfields($event,'start','dtstart'); - convert_oldfields($event,'finish','dtend'); - convert_oldfields($event,'type','etype'); - convert_oldfields($event,'ignore','dismissed'); + if ($channel && $events) { + foreach ($events as $event) { + unset($event['id']); + $event['aid'] = $channel['channel_account_id']; + $event['uid'] = $channel['channel_id']; + convert_oldfields($event, 'start', 'dtstart'); + convert_oldfields($event, 'finish', 'dtend'); + convert_oldfields($event, 'type', 'etype'); + convert_oldfields($event, 'ignore', 'dismissed'); - create_table_from_array('event', $event); - } - } + create_table_from_array('event', $event); + } + } } /** @@ -1048,75 +1071,76 @@ function import_events($channel, $events) { * @param array $channel * @param array $events */ -function sync_events($channel, $events) { +function sync_events($channel, $events) +{ - if ($channel && $events) { + if ($channel && $events) { + $columns = db_columns('event'); - $columns = db_columns('event'); + foreach ($events as $event) { + if ((! $event['event_hash']) || (! $event['dtstart'])) { + continue; + } - foreach ($events as $event) { + if ($event['event_deleted']) { + $r = q( + "delete from event where event_hash = '%s' and uid = %d", + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + $r = q( + "select id from item where resource_type = 'event' and resource_id = '%s' and uid = %d", + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + if ($r) { + drop_item($r[0]['id'], false, (($event['event_xchan'] === $channel['channel_hash']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + } + continue; + } - if ((! $event['event_hash']) || (! $event['dtstart'])) { - continue; - } + unset($event['id']); + $event['aid'] = $channel['channel_account_id']; + $event['uid'] = $channel['channel_id']; - if ($event['event_deleted']) { - $r = q("delete from event where event_hash = '%s' and uid = %d", - dbesc($event['event_hash']), - intval($channel['channel_id']) - ); - $r = q("select id from item where resource_type = 'event' and resource_id = '%s' and uid = %d", - dbesc($event['event_hash']), - intval($channel['channel_id']) - ); - if ($r) { - drop_item($r[0]['id'],false,(($event['event_xchan'] === $channel['channel_hash']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); - } - continue; - } + convert_oldfields($event, 'start', 'dtstart'); + convert_oldfields($event, 'finish', 'dtend'); + convert_oldfields($event, 'type', 'etype'); + convert_oldfields($event, 'ignore', 'dismissed'); - unset($event['id']); - $event['aid'] = $channel['channel_account_id']; - $event['uid'] = $channel['channel_id']; + $exists = false; - convert_oldfields($event,'start','dtstart'); - convert_oldfields($event,'finish','dtend'); - convert_oldfields($event,'type','etype'); - convert_oldfields($event,'ignore','dismissed'); + $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; + } - $exists = false; + if ($exists) { + foreach ($event as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - $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) { - - if (! in_array($k,$columns)) { - continue; - } - - $r = q("UPDATE event SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE event_hash = '%s' AND uid = %d", - dbesc($k), - dbesc($v), - dbesc($event['event_hash']), - intval($channel['channel_id']) - ); - } - } - else { - create_table_from_array('event', $event); - } - } - } + $r = q( + "UPDATE event SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE event_hash = '%s' AND uid = %d", + dbesc($k), + dbesc($v), + dbesc($event['event_hash']), + intval($channel['channel_id']) + ); + } + } else { + create_table_from_array('event', $event); + } + } + } } /** @@ -1125,62 +1149,63 @@ function sync_events($channel, $events) { * @param array $channel * @param array $menus */ -function import_menus($channel, $menus) { +function import_menus($channel, $menus) +{ - if ($channel && $menus) { - foreach ($menus as $menu) { - $m = []; - $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('UTC','UTC',$menu['created']); - } - if ($menu['edited']) { - $m['menu_edited'] = datetime_convert('UTC','UTC', $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; - } - } + if ($channel && $menus) { + foreach ($menus as $menu) { + $m = []; + $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('UTC', 'UTC', $menu['created']); + } + if ($menu['edited']) { + $m['menu_edited'] = datetime_convert('UTC', 'UTC', $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); + $menu_id = menu_create($m); - if ($menu_id) { - if (is_array($menu['items'])) { - foreach ($menu['items'] as $it) { - $mitem = []; + if ($menu_id) { + if (is_array($menu['items'])) { + foreach ($menu['items'] as $it) { + $mitem = []; - $mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']); - $mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']); - $mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']); - $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']); + $mitem['mitem_link'] = str_replace('[channelurl]', z_root() . '/channel/' . $channel['channel_address'], $it['link']); + $mitem['mitem_link'] = str_replace('[pageurl]', z_root() . '/page/' . $channel['channel_address'], $it['link']); + $mitem['mitem_link'] = str_replace('[cloudurl]', z_root() . '/cloud/' . $channel['channel_address'], $it['link']); + $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); - } - } - } - } - } + $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); + } + } + } + } + } } /** @@ -1189,94 +1214,95 @@ function import_menus($channel, $menus) { * @param array $channel * @param array $menus */ -function sync_menus($channel, $menus) { +function sync_menus($channel, $menus) +{ - if ($channel && $menus) { + if ($channel && $menus) { + foreach ($menus as $menu) { + $m = []; + $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('UTC', 'UTC', $menu['created']); + } + if ($menu['edited']) { + $m['menu_edited'] = datetime_convert('UTC', 'UTC', $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; - foreach ($menus as $menu) { - $m = []; - $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('UTC','UTC',$menu['created']); - } - if ($menu['edited']) { - $m['menu_edited'] = datetime_convert('UTC','UTC',$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; - } - } + $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) + ); + } - $editing = false; + if (is_array($menu['items'])) { + foreach ($menu['items'] as $it) { + $mitem = []; - $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) - ); - } + $mitem['mitem_link'] = str_replace('[channelurl]', z_root() . '/channel/' . $channel['channel_address'], $it['link']); + $mitem['mitem_link'] = str_replace('[pageurl]', z_root() . '/page/' . $channel['channel_address'], $it['link']); + $mitem['mitem_link'] = str_replace('[cloudurl]', z_root() . '/cloud/' . $channel['channel_address'], $it['link']); + $mitem['mitem_link'] = str_replace('[baseurl]', z_root(), $it['link']); - if (is_array($menu['items'])) { - foreach ($menu['items'] as $it) { - $mitem = []; - - $mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']); - $mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']); - $mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']); - $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); - } - } - } - } - } + $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); + } + } + } + } + } } /** @@ -1285,65 +1311,71 @@ function sync_menus($channel, $menus) { * @param array $channel * @param array $likes */ -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; - } +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; - } - create_table_from_array('likes', $like); - } - } + 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; + } + create_table_from_array('likes', $like); + } + } } -function import_conv($channel,$convs) { - if ($channel && $convs) { - foreach ($convs as $conv) { - if ($conv['deleted']) { - q("delete from conv where guid = '%s' and uid = %d", - dbesc($conv['guid']), - intval($channel['channel_id']) - ); - continue; - } +function import_conv($channel, $convs) +{ + if ($channel && $convs) { + foreach ($convs as $conv) { + if ($conv['deleted']) { + q( + "delete from conv where guid = '%s' and uid = %d", + dbesc($conv['guid']), + intval($channel['channel_id']) + ); + continue; + } - unset($conv['id']); + unset($conv['id']); - $conv['uid'] = $channel['channel_id']; - $conv['subject'] = str_rot47(base64url_encode($conv['subject'])); + $conv['uid'] = $channel['channel_id']; + $conv['subject'] = str_rot47(base64url_encode($conv['subject'])); - $r = q("select id from conv where guid = '%s' and uid = %d limit 1", - dbesc($conv['guid']), - intval($channel['channel_id']) - ); - if ($r) { - continue; - } - create_table_from_array('conv',$conv); - } - } + $r = q( + "select id from conv where guid = '%s' and uid = %d limit 1", + dbesc($conv['guid']), + intval($channel['channel_id']) + ); + if ($r) { + continue; + } + create_table_from_array('conv', $conv); + } + } } /** @@ -1353,37 +1385,40 @@ function import_conv($channel,$convs) { * @param array $mails * @param bool $sync (optional) default false */ -function import_mail($channel, $mails, $sync = false) { - if ($channel && $mails) { - foreach ($mails as $mail) { - if (array_key_exists('flags',$mail) && in_array('deleted',$mail['flags'])) { - q("delete from mail where mid = '%s' and uid = %d", - dbesc($mail['message_id']), - intval($channel['channel_id']) - ); - continue; - } - if (array_key_exists('flags',$mail) && in_array('recalled',$mail['flags'])) { - q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d", - dbesc($mail['message_id']), - intval($channel['channel_id']) - ); - continue; - } +function import_mail($channel, $mails, $sync = false) +{ + if ($channel && $mails) { + foreach ($mails as $mail) { + if (array_key_exists('flags', $mail) && in_array('deleted', $mail['flags'])) { + q( + "delete from mail where mid = '%s' and uid = %d", + dbesc($mail['message_id']), + intval($channel['channel_id']) + ); + continue; + } + if (array_key_exists('flags', $mail) && in_array('recalled', $mail['flags'])) { + q( + "update mail set mail_recalled = 1 where mid = '%s' and uid = %d", + dbesc($mail['message_id']), + intval($channel['channel_id']) + ); + continue; + } - $m = get_mail_elements($mail); - if (! $m) { - continue; - } - $m['account_id'] = $channel['channel_account_id']; - $m['channel_id'] = $channel['channel_id']; - $mail_id = mail_store($m); - if ($sync && $mail_id) { - // Not applicable to Zap which does not support mail - // Run::Summon( [ 'Notifier','single_mail',$mail_id ] ); - } - } - } + $m = get_mail_elements($mail); + if (! $m) { + continue; + } + $m['account_id'] = $channel['channel_account_id']; + $m['channel_id'] = $channel['channel_id']; + $mail_id = mail_store($m); + if ($sync && $mail_id) { + // Not applicable to Zap which does not support mail + // Run::Summon( [ 'Notifier','single_mail',$mail_id ] ); + } + } + } } /** @@ -1393,8 +1428,9 @@ function import_mail($channel, $mails, $sync = false) { * @param array $channel * @param array $mails */ -function sync_mail($channel, $mails) { - import_mail($channel, $mails, true); +function sync_mail($channel, $mails) +{ + import_mail($channel, $mails, true); } /** @@ -1403,355 +1439,352 @@ function sync_mail($channel, $mails) { * @param array $channel * @param array $files */ -function sync_files($channel, $files) { +function sync_files($channel, $files) +{ - require_once('include/attach.php'); + require_once('include/attach.php'); - if ($channel && $files) { + if ($channel && $files) { + $limit = engr_units_to_bytes(service_class_fetch($channel['channel_id'], 'attach_upload_limit')); - $limit = engr_units_to_bytes(service_class_fetch($channel['channel_id'], 'attach_upload_limit')); + foreach ($files as $f) { + if (! $f) { + continue; + } + $fetch_url = $f['fetch_url']; + $oldbase = dirname($fetch_url); + $original_channel = $f['original_channel']; - foreach ($files as $f) { - if (! $f) { - continue; - } - $fetch_url = $f['fetch_url']; - $oldbase = dirname($fetch_url); - $original_channel = $f['original_channel']; + if (! ($fetch_url && $original_channel)) { + continue; + } - if (! ($fetch_url && $original_channel)) { - continue; - } + $has_undeleted_attachments = false; - $has_undeleted_attachments = false; - - if ($f['attach']) { - foreach ($f['attach'] as $att) { - $attachment_stored = false; - convert_oldfields($att,'data','content'); + if ($f['attach']) { + foreach ($f['attach'] as $att) { + $attachment_stored = false; + convert_oldfields($att, 'data', 'content'); - if (intval($att['deleted'])) { - logger('deleting attachment'); - attach_delete($channel['channel_id'],$att['hash']); - continue; - } + if (intval($att['deleted'])) { + logger('deleting attachment'); + attach_delete($channel['channel_id'], $att['hash']); + continue; + } - $has_undeleted_attachments = true; - $attach_exists = false; - $x = attach_by_hash($att['hash'],$channel['channel_hash']); - logger('sync_files duplicate check: attach_exists=' . $attach_exists, LOGGER_DEBUG); - logger('sync_files duplicate check: att=' . print_r($att,true), LOGGER_DEBUG); - logger('sync_files duplicate check: attach_by_hash() returned ' . print_r($x,true), LOGGER_DEBUG); + $has_undeleted_attachments = true; + $attach_exists = false; + $x = attach_by_hash($att['hash'], $channel['channel_hash']); + logger('sync_files duplicate check: attach_exists=' . $attach_exists, LOGGER_DEBUG); + logger('sync_files duplicate check: att=' . print_r($att, true), LOGGER_DEBUG); + logger('sync_files duplicate check: attach_by_hash() returned ' . print_r($x, true), LOGGER_DEBUG); - if ($x['success']) { - $orig_attach = $x['data']; - $attach_exists = true; - $attach_id = $orig_attach['id']; - } + if ($x['success']) { + $orig_attach = $x['data']; + $attach_exists = true; + $attach_id = $orig_attach['id']; + } - $newfname = 'store/' . $channel['channel_address'] . '/' . get_attach_binname($att['content']); + $newfname = 'store/' . $channel['channel_address'] . '/' . get_attach_binname($att['content']); - unset($att['id']); - $att['aid'] = $channel['channel_account_id']; - $att['uid'] = $channel['channel_id']; + unset($att['id']); + $att['aid'] = $channel['channel_account_id']; + $att['uid'] = $channel['channel_id']; - // check for duplicate folder names with the same parent. - // If we have a duplicate that doesn't match this hash value - // change the name so that the contents won't be "covered over" - // by the existing directory. Use the same logic we use for - // duplicate files. + // check for duplicate folder names with the same parent. + // If we have a duplicate that doesn't match this hash value + // change the name so that the contents won't be "covered over" + // by the existing directory. Use the same logic we use for + // duplicate files. - if (strpos($att['filename'],'.') !== false) { - $basename = substr($att['filename'],0,strrpos($att['filename'],'.')); - $ext = substr($att['filename'],strrpos($att['filename'],'.')); - } - else { - $basename = $att['filename']; - $ext = ''; - } + if (strpos($att['filename'], '.') !== false) { + $basename = substr($att['filename'], 0, strrpos($att['filename'], '.')); + $ext = substr($att['filename'], strrpos($att['filename'], '.')); + } else { + $basename = $att['filename']; + $ext = ''; + } - $r = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' and hash != '%s' and uid = %d ", - dbesc($basename . $ext), - dbesc($basename . '(%)' . $ext), - dbesc($att['folder']), - dbesc($att['hash']), - intval($channel['channel_id']) - ); + $r = q( + "select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' and hash != '%s' and uid = %d ", + dbesc($basename . $ext), + dbesc($basename . '(%)' . $ext), + dbesc($att['folder']), + dbesc($att['hash']), + intval($channel['channel_id']) + ); - if ($r) { - $x = 1; + if ($r) { + $x = 1; - do { - $found = false; - foreach ($r as $rr) { - if ($rr['filename'] === $basename . '(' . $x . ')' . $ext) { - $found = true; - break; - } - } - if ($found) { - $x++; - } - } - while ($found); - $att['filename'] = $basename . '(' . $x . ')' . $ext; - } - else { - $att['filename'] = $basename . $ext; - } - // end duplicate detection + do { + $found = false; + foreach ($r as $rr) { + if ($rr['filename'] === $basename . '(' . $x . ')' . $ext) { + $found = true; + break; + } + } + if ($found) { + $x++; + } + } while ($found); + $att['filename'] = $basename . '(' . $x . ')' . $ext; + } else { + $att['filename'] = $basename . $ext; + } + // end duplicate detection - /// @FIXME update attachment structures if they are modified rather than created + /// @FIXME update attachment structures if they are modified rather than created - $att['content'] = $newfname; + $att['content'] = $newfname; - // Note: we use $att['hash'] below after it has been escaped to - // fetch the file contents. - // If the hash ever contains any escapable chars this could cause - // problems. Currently it does not. + // Note: we use $att['hash'] below after it has been escaped to + // fetch the file contents. + // If the hash ever contains any escapable chars this could cause + // problems. Currently it does not. - if (!isset($att['os_path'])) { - $att['os_path'] = ''; - } + if (!isset($att['os_path'])) { + $att['os_path'] = ''; + } - if ($attach_exists) { - logger('sync_files attach exists: ' . print_r($att,true), LOGGER_DEBUG); + if ($attach_exists) { + logger('sync_files attach exists: ' . print_r($att, true), LOGGER_DEBUG); - // process/sync a remote rename/move operation + // process/sync a remote rename/move operation - if ($orig_attach && $orig_attach['content'] && $orig_attach['content'] !== $newfname) { - logger('rename: ' . $orig_attach['content'] . ' -> ' . $newfname); - rename($orig_attach['content'],$newfname); - } + if ($orig_attach && $orig_attach['content'] && $orig_attach['content'] !== $newfname) { + logger('rename: ' . $orig_attach['content'] . ' -> ' . $newfname); + rename($orig_attach['content'], $newfname); + } - if (! dbesc_array($att)) { - continue; - } + if (! dbesc_array($att)) { + continue; + } - $columns = db_columns('attach'); + $columns = db_columns('attach'); - $str = ''; - foreach ($att as $k => $v) { - if (! in_array($k,$columns)) { - continue; - } - - if ($str) { - $str .= ","; - } - $str .= " " . TQUOT . $k . TQUOT . " = '" . $v . "' "; - } - $r = dbq("update attach set " . $str . " where id = " . intval($attach_id) ); - } - else { - logger('sync_files attach does not exists: ' . print_r($att,true), LOGGER_DEBUG); + $str = ''; + foreach ($att as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - if ($limit !== false) { - $r = q("select sum(filesize) as total from attach where aid = %d ", - intval($channel['channel_account_id']) - ); - if (($r) && (($r[0]['total'] + $att['filesize']) > $limit)) { - logger('service class limit exceeded'); - continue; - } - } + if ($str) { + $str .= ","; + } + $str .= " " . TQUOT . $k . TQUOT . " = '" . $v . "' "; + } + $r = dbq("update attach set " . $str . " where id = " . intval($attach_id)); + } else { + logger('sync_files attach does not exists: ' . print_r($att, true), LOGGER_DEBUG); - create_table_from_array('attach',$att); - } + if ($limit !== false) { + $r = q( + "select sum(filesize) as total from attach where aid = %d ", + intval($channel['channel_account_id']) + ); + if (($r) && (($r[0]['total'] + $att['filesize']) > $limit)) { + logger('service class limit exceeded'); + continue; + } + } + + create_table_from_array('attach', $att); + } - // is this a directory? + // is this a directory? - if ($att['filetype'] === 'multipart/mixed' && $att['is_dir']) { - os_mkdir($newfname, STORAGE_DEFAULT_PERMISSIONS,true); - $attachment_stored = true; - continue; - } - else { + if ($att['filetype'] === 'multipart/mixed' && $att['is_dir']) { + os_mkdir($newfname, STORAGE_DEFAULT_PERMISSIONS, true); + $attachment_stored = true; + continue; + } else { + // it's a file + // for the sync version of this algorithm (as opposed to 'offline import') + // we will fetch the actual file from the source server so it can be + // streamed directly to disk and avoid consuming PHP memory if it's a huge + // audio/video file or something. - // it's a file - // for the sync version of this algorithm (as opposed to 'offline import') - // we will fetch the actual file from the source server so it can be - // streamed directly to disk and avoid consuming PHP memory if it's a huge - // audio/video file or something. + $time = datetime_convert(); - $time = datetime_convert(); + $parr = [ + 'hash' => $channel['channel_hash'], + 'time' => $time, + 'resource' => $att['hash'], + 'revision' => 0, + 'signature' => Libzot::sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey']) + ]; - $parr = [ - 'hash' => $channel['channel_hash'], - 'time' => $time, - 'resource' => $att['hash'], - 'revision' => 0, - 'signature' => Libzot::sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey']) - ]; + $store_path = $newfname; - $store_path = $newfname; + $fp = fopen($newfname, 'w'); - $fp = fopen($newfname,'w'); + if (! $fp) { + logger('failed to open storage file.', LOGGER_NORMAL, LOG_ERR); + continue; + } - if (! $fp) { - logger('failed to open storage file.',LOGGER_NORMAL,LOG_ERR); - continue; - } + $redirects = 0; - $redirects = 0; + $m = parse_url($fetch_url); - $m = parse_url($fetch_url); + $headers = [ + 'Accept' => 'application/x-zot+json', + 'Sigtoken' => random_string(), + 'Host' => $m['host'], + '(request-target)' => 'post ' . $m['path'] . '/' . $att['hash'] + ]; - $headers = [ - 'Accept' => 'application/x-zot+json', - 'Sigtoken' => random_string(), - 'Host' => $m['host'], - '(request-target)' => 'post ' . $m['path'] . '/' . $att['hash'] - ]; + $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512'); - $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); + $x = z_post_url($fetch_url . '/' . $att['hash'], $parr, $redirects, [ 'filep' => $fp, 'headers' => $headers]); - $x = z_post_url($fetch_url . '/' . $att['hash'],$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]); + fclose($fp); - fclose($fp); + if ($x['success']) { + $attachment_stored = true; + } + continue; + } + } + } + if (($has_undeleted_attachments) && (! $attachment_stored)) { + /// @TODO should we queue this and retry or delete everything or what? + logger('attachment store failed', LOGGER_NORMAL, LOG_ERR); + } + if ($f['photo']) { + foreach ($f['photo'] as $p) { + unset($p['id']); + $p['aid'] = $channel['channel_account_id']; + $p['uid'] = $channel['channel_id']; - if ($x['success']) { - $attachment_stored = true; - } - continue; - } - } - } - if (($has_undeleted_attachments) && (! $attachment_stored)) { - /// @TODO should we queue this and retry or delete everything or what? - logger('attachment store failed',LOGGER_NORMAL,LOG_ERR); - } - if ($f['photo']) { - foreach ($f['photo'] as $p) { - unset($p['id']); - $p['aid'] = $channel['channel_account_id']; - $p['uid'] = $channel['channel_id']; + convert_oldfields($p, 'data', 'content'); + convert_oldfields($p, 'scale', 'imgscale'); + convert_oldfields($p, 'size', 'filesize'); + convert_oldfields($p, 'type', 'mimetype'); - convert_oldfields($p,'data','content'); - convert_oldfields($p,'scale','imgscale'); - convert_oldfields($p,'size','filesize'); - convert_oldfields($p,'type','mimetype'); + // if this is a profile photo, undo the profile photo bit + // for any other photo which previously held it. - // if this is a profile photo, undo the profile photo bit - // for any other photo which previously held it. - - if ($p['photo_usage'] == PHOTO_PROFILE) { - $e = q("update photo set photo_usage = %d where photo_usage = %d + if ($p['photo_usage'] == PHOTO_PROFILE) { + $e = q( + "update photo set photo_usage = %d where photo_usage = %d and resource_id != '%s' and uid = %d ", - intval(PHOTO_NORMAL), - intval(PHOTO_PROFILE), - dbesc($p['resource_id']), - intval($channel['channel_id']) - ); - } + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + dbesc($p['resource_id']), + intval($channel['channel_id']) + ); + } - // same for cover photos + // same for cover photos - if ($p['photo_usage'] == PHOTO_COVER) { - $e = q("update photo set photo_usage = %d where photo_usage = %d + if ($p['photo_usage'] == PHOTO_COVER) { + $e = q( + "update photo set photo_usage = %d where photo_usage = %d and resource_id != '%s' and uid = %d ", - intval(PHOTO_NORMAL), - intval(PHOTO_COVER), - dbesc($p['resource_id']), - intval($channel['channel_id']) - ); - } + intval(PHOTO_NORMAL), + intval(PHOTO_COVER), + dbesc($p['resource_id']), + intval($channel['channel_id']) + ); + } - if (intval($p['os_storage'])) { - $p['content'] = $store_path . ((intval($p['imgscale'])) ? '-' . $p['imgscale'] : EMPTY_STR); - } - else { - $p['content'] = (($p['content']) ? base64_decode($p['content']) : ''); - } + if (intval($p['os_storage'])) { + $p['content'] = $store_path . ((intval($p['imgscale'])) ? '-' . $p['imgscale'] : EMPTY_STR); + } else { + $p['content'] = (($p['content']) ? base64_decode($p['content']) : ''); + } - if (intval($p['imgscale']) && ((intval($p['os_storage'])) || (! $p['content']))) { + if (intval($p['imgscale']) && ((intval($p['os_storage'])) || (! $p['content']))) { + $time = datetime_convert(); - $time = datetime_convert(); - - $parr = [ - 'hash' => $channel['channel_hash'], - 'time' => $time, - 'resource' => $att['hash'], - 'revision' => 0, - 'signature' => Libzot::sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey']), - 'resolution' => $p['imgscale'] - ]; + $parr = [ + 'hash' => $channel['channel_hash'], + 'time' => $time, + 'resource' => $att['hash'], + 'revision' => 0, + 'signature' => Libzot::sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey']), + 'resolution' => $p['imgscale'] + ]; - $stored_image = $newfname . '-' . intval($p['imgscale']); + $stored_image = $newfname . '-' . intval($p['imgscale']); - logger('fetching_photo: ' . $stored_image); + logger('fetching_photo: ' . $stored_image); - $fp = fopen($stored_image,'w'); - if (! $fp) { - logger('failed to open storage file.',LOGGER_NORMAL,LOG_ERR); - continue; - } - $redirects = 0; + $fp = fopen($stored_image, 'w'); + if (! $fp) { + logger('failed to open storage file.', LOGGER_NORMAL, LOG_ERR); + continue; + } + $redirects = 0; - $m = parse_url($fetch_url); + $m = parse_url($fetch_url); - $headers = [ - 'Accept' => 'application/x-zot+json', - 'Sigtoken' => random_string(), - 'Host' => $m['host'], - '(request-target)' => 'post ' . $m['path'] . '/' . $att['hash'] - ]; + $headers = [ + 'Accept' => 'application/x-zot+json', + 'Sigtoken' => random_string(), + 'Host' => $m['host'], + '(request-target)' => 'post ' . $m['path'] . '/' . $att['hash'] + ]; - $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); + $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512'); - $x = z_post_url($fetch_url . '/' . $att['hash'],$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]); + $x = z_post_url($fetch_url . '/' . $att['hash'], $parr, $redirects, [ 'filep' => $fp, 'headers' => $headers]); - fclose($fp); + fclose($fp); - if (! intval($p['os_storage'])) { - $p['content'] = file_get_contents($stored_image); - unlink($stored_image); - } - } + if (! intval($p['os_storage'])) { + $p['content'] = file_get_contents($stored_image); + unlink($stored_image); + } + } - if (!isset($p['display_path'])) { - $p['display_path'] = ''; - } + if (!isset($p['display_path'])) { + $p['display_path'] = ''; + } - $exists = q("select * from photo where resource_id = '%s' and imgscale = %d and uid = %d limit 1", - dbesc($p['resource_id']), - intval($p['imgscale']), - intval($channel['channel_id']) - ); + $exists = q( + "select * from photo where resource_id = '%s' and imgscale = %d and uid = %d limit 1", + dbesc($p['resource_id']), + intval($p['imgscale']), + intval($channel['channel_id']) + ); - if ($exists) { + if ($exists) { + $str = ''; + foreach ($p as $k => $v) { + $matches = false; + if (preg_match('/([^a-zA-Z0-9\-\_\.])/', $k, $matches)) { + continue; + } - $str = ''; - foreach ($p as $k => $v) { - $matches = false; - if (preg_match('/([^a-zA-Z0-9\-\_\.])/',$k,$matches)) { - continue; - } + if ($str) { + $str .= ","; + } + $str .= " " . TQUOT . $k . TQUOT . " = '" . (($k === 'content') ? dbescbin($v) : dbesc($v)) . "' "; + } + $r = dbq("update photo set " . $str . " where id = " . intval($exists[0]['id'])); + } else { + create_table_from_array('photo', $p, [ 'content' ]); + } + } + } - if ($str) { - $str .= ","; - } - $str .= " " . TQUOT . $k . TQUOT . " = '" . (($k === 'content') ? dbescbin($v) : dbesc($v)) . "' "; - } - $r = dbq("update photo set " . $str . " where id = " . intval($exists[0]['id']) ); - } - else { - create_table_from_array('photo',$p, [ 'content' ] ); - } - } - } + Run::Summon([ 'Thumbnail' , $att['hash'] ]); - Run::Summon([ 'Thumbnail' , $att['hash'] ]); - - if ($f['item']) { - sync_items($channel,$f['item'], - ['channel_address' => $original_channel,'url' => $oldbase] - ); - } - } - } + if ($f['item']) { + sync_items( + $channel, + $f['item'], + ['channel_address' => $original_channel,'url' => $oldbase] + ); + } + } + } } /** @@ -1763,364 +1796,369 @@ function sync_files($channel, $files) { * @param string $old The old key in the array * @param string $new The new key in the array */ -function convert_oldfields(&$arr, $old, $new) { - if (array_key_exists($old, $arr)) { - $arr[$new] = $arr[$old]; - unset($arr[$old]); - } +function convert_oldfields(&$arr, $old, $new) +{ + if (array_key_exists($old, $arr)) { + $arr[$new] = $arr[$old]; + unset($arr[$old]); + } } -function scan_webpage_elements($path, $type, $cloud = false) { - $channel = App::get_channel(); - $dirtoscan = $path; - switch ($type) { - case 'page': - $dirtoscan .= '/pages/'; - $json_filename = 'page.json'; - break; - case 'layout': - $dirtoscan .= '/layouts/'; - $json_filename = 'layout.json'; - break; - case 'block': - $dirtoscan .= '/blocks/'; - $json_filename = 'block.json'; - break; - default : - return []; - } - if($cloud) { - $dirtoscan = get_dirpath_by_cloudpath($channel, $dirtoscan); - } - $elements = []; - if (is_dir($dirtoscan)) { - $dirlist = scandir($dirtoscan); - if ($dirlist) { - foreach ($dirlist as $element) { - if ($element === '.' || $element === '..') { - continue; - } - $folder = $dirtoscan . '/' . $element; - if (is_dir($folder)) { - if ($cloud) { - $jsonfilepath = $folder . '/' . get_filename_by_cloudname($json_filename, $channel, $folder); - } - else { - $jsonfilepath = $folder . '/' . $json_filename; - } - if (is_file($jsonfilepath)) { - $metadata = json_decode(file_get_contents($jsonfilepath), true); - if ($cloud) { - $contentfilename = get_filename_by_cloudname($metadata['contentfile'], $channel, $folder); - $metadata['path'] = $folder . '/' . $contentfilename; - } - else { - $contentfilename = $metadata['contentfile']; - $metadata['path'] = $folder . '/' . $contentfilename; - } - if ($metadata['contentfile'] === '') { - logger('Invalid ' . $type . ' content file'); - return false; - } - $content = file_get_contents($folder . '/' . $contentfilename); - if (!$content) { - if (is_readable($folder . '/' . $contentfilename)) { - $content = ''; - } - else { - logger('Failed to get file content for ' . $metadata['contentfile']); - return false; - } - } - $elements[] = $metadata; - } - } - } - } - } +function scan_webpage_elements($path, $type, $cloud = false) +{ + $channel = App::get_channel(); + $dirtoscan = $path; + switch ($type) { + case 'page': + $dirtoscan .= '/pages/'; + $json_filename = 'page.json'; + break; + case 'layout': + $dirtoscan .= '/layouts/'; + $json_filename = 'layout.json'; + break; + case 'block': + $dirtoscan .= '/blocks/'; + $json_filename = 'block.json'; + break; + default: + return []; + } + if ($cloud) { + $dirtoscan = get_dirpath_by_cloudpath($channel, $dirtoscan); + } + $elements = []; + if (is_dir($dirtoscan)) { + $dirlist = scandir($dirtoscan); + if ($dirlist) { + foreach ($dirlist as $element) { + if ($element === '.' || $element === '..') { + continue; + } + $folder = $dirtoscan . '/' . $element; + if (is_dir($folder)) { + if ($cloud) { + $jsonfilepath = $folder . '/' . get_filename_by_cloudname($json_filename, $channel, $folder); + } else { + $jsonfilepath = $folder . '/' . $json_filename; + } + if (is_file($jsonfilepath)) { + $metadata = json_decode(file_get_contents($jsonfilepath), true); + if ($cloud) { + $contentfilename = get_filename_by_cloudname($metadata['contentfile'], $channel, $folder); + $metadata['path'] = $folder . '/' . $contentfilename; + } else { + $contentfilename = $metadata['contentfile']; + $metadata['path'] = $folder . '/' . $contentfilename; + } + if ($metadata['contentfile'] === '') { + logger('Invalid ' . $type . ' content file'); + return false; + } + $content = file_get_contents($folder . '/' . $contentfilename); + if (!$content) { + if (is_readable($folder . '/' . $contentfilename)) { + $content = ''; + } else { + logger('Failed to get file content for ' . $metadata['contentfile']); + return false; + } + } + $elements[] = $metadata; + } + } + } + } + } - return $elements; + return $elements; } -function import_webpage_element($element, $channel, $type) { +function import_webpage_element($element, $channel, $type) +{ - $arr = []; // construct information for the webpage element item table record + $arr = []; // construct information for the webpage element item table record - switch ($type) { - // - // PAGES - // - case 'page': - $arr['item_type'] = ITEM_TYPE_WEBPAGE; - $namespace = 'WEBPAGE'; - $name = $element['pagelink']; - if ($name) { - require_once('library/urlify/URLify.php'); - $name = strtolower(URLify::transliterate($name)); - } - $arr['title'] = $element['title']; - $arr['term'] = $element['term']; - $arr['layout_mid'] = ''; // by default there is no layout associated with the page - // If a layout was specified, find it in the database and get its info. If - // it does not exist, leave layout_mid empty - if ($element['layout'] !== '') { - $liid = q("select iid from iconfig where k = 'PDL' and v = '%s' and cat = 'system'", - dbesc($element['layout']) - ); - if ($liid) { - $linfo = q("select mid from item where id = %d", - intval($liid[0]['iid']) - ); - $arr['layout_mid'] = $linfo[0]['mid']; - } - } - break; - // - // LAYOUTS - // - case 'layout': - $arr['item_type'] = ITEM_TYPE_PDL; - $namespace = 'PDL'; - $name = $element['name']; - $arr['title'] = $element['description']; - $arr['term'] = $element['term']; - break; - // - // BLOCKS - // - case 'block': - $arr['item_type'] = ITEM_TYPE_BLOCK; - $namespace = 'BUILDBLOCK'; - $name = $element['name']; - $arr['title'] = $element['title']; + switch ($type) { + // + // PAGES + // + case 'page': + $arr['item_type'] = ITEM_TYPE_WEBPAGE; + $namespace = 'WEBPAGE'; + $name = $element['pagelink']; + if ($name) { + require_once('library/urlify/URLify.php'); + $name = strtolower(URLify::transliterate($name)); + } + $arr['title'] = $element['title']; + $arr['term'] = $element['term']; + $arr['layout_mid'] = ''; // by default there is no layout associated with the page + // If a layout was specified, find it in the database and get its info. If + // it does not exist, leave layout_mid empty + if ($element['layout'] !== '') { + $liid = q( + "select iid from iconfig where k = 'PDL' and v = '%s' and cat = 'system'", + dbesc($element['layout']) + ); + if ($liid) { + $linfo = q( + "select mid from item where id = %d", + intval($liid[0]['iid']) + ); + $arr['layout_mid'] = $linfo[0]['mid']; + } + } + break; + // + // LAYOUTS + // + case 'layout': + $arr['item_type'] = ITEM_TYPE_PDL; + $namespace = 'PDL'; + $name = $element['name']; + $arr['title'] = $element['description']; + $arr['term'] = $element['term']; + break; + // + // BLOCKS + // + case 'block': + $arr['item_type'] = ITEM_TYPE_BLOCK; + $namespace = 'BUILDBLOCK'; + $name = $element['name']; + $arr['title'] = $element['title']; - break; - default : - return null; // return null if invalid element type - } + break; + default: + return null; // return null if invalid element type + } - $arr['uid'] = local_channel(); - $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = local_channel(); + $arr['aid'] = $channel['channel_account_id']; - // Check if an item already exists based on the name - $iid = q("select iid from iconfig where k = '" . $namespace . "' and v = '%s' and cat = 'system'", - dbesc($name) - ); - if ($iid) { // If the item does exist, get the item metadata - $iteminfo = q("select mid,created,edited from item where id = %d", - intval($iid[0]['iid']) - ); - $arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid']; - $arr['created'] = $iteminfo[0]['created']; - } - else { // otherwise, generate the creation times and unique id - $arr['created'] = datetime_convert('UTC', 'UTC'); - $arr['uuid'] = new_uuid(); - $arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid']; - } - // Update the edited time whether or not the element already exists - $arr['edited'] = datetime_convert('UTC', 'UTC'); - // Import the actual element content - $arr['body'] = file_get_contents($element['path']); - // The element owner is the channel importing the elements - $arr['owner_xchan'] = get_observer_hash(); - // The author is either the owner or whomever was specified - $arr['author_xchan'] = (($element['author_xchan']) ? $element['author_xchan'] : get_observer_hash()); - // Import mimetype if it is a valid mimetype for the element - $mimetypes = [ - 'text/bbcode', - 'text/html', - 'text/markdown', - 'text/plain', - 'application/x-pdl', - 'application/x-php' - ]; - // Blocks and pages can have any of the valid mimetypes, but layouts must be text/bbcode - if ((in_array($element['mimetype'], $mimetypes)) && in_array($type, [ 'page', 'block' ]) ) { - $arr['mimetype'] = $element['mimetype']; - } - else { - $arr['mimetype'] = 'text/bbcode'; - } + // Check if an item already exists based on the name + $iid = q( + "select iid from iconfig where k = '" . $namespace . "' and v = '%s' and cat = 'system'", + dbesc($name) + ); + if ($iid) { // If the item does exist, get the item metadata + $iteminfo = q( + "select mid,created,edited from item where id = %d", + intval($iid[0]['iid']) + ); + $arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid']; + $arr['created'] = $iteminfo[0]['created']; + } else { // otherwise, generate the creation times and unique id + $arr['created'] = datetime_convert('UTC', 'UTC'); + $arr['uuid'] = new_uuid(); + $arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid']; + } + // Update the edited time whether or not the element already exists + $arr['edited'] = datetime_convert('UTC', 'UTC'); + // Import the actual element content + $arr['body'] = file_get_contents($element['path']); + // The element owner is the channel importing the elements + $arr['owner_xchan'] = get_observer_hash(); + // The author is either the owner or whomever was specified + $arr['author_xchan'] = (($element['author_xchan']) ? $element['author_xchan'] : get_observer_hash()); + // Import mimetype if it is a valid mimetype for the element + $mimetypes = [ + 'text/bbcode', + 'text/html', + 'text/markdown', + 'text/plain', + 'application/x-pdl', + 'application/x-php' + ]; + // Blocks and pages can have any of the valid mimetypes, but layouts must be text/bbcode + if ((in_array($element['mimetype'], $mimetypes)) && in_array($type, [ 'page', 'block' ])) { + $arr['mimetype'] = $element['mimetype']; + } else { + $arr['mimetype'] = 'text/bbcode'; + } - // Verify ability to use html or php!!! + // Verify ability to use html or php!!! - $execflag = channel_codeallowed(local_channel()); + $execflag = channel_codeallowed(local_channel()); - $i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", - dbesc($arr['mid']), - intval(local_channel()) - ); + $i = q( + "select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", + dbesc($arr['mid']), + intval(local_channel()) + ); - IConfig::Set($arr,'system',$namespace,(($name) ? $name : substr($arr['mid'],0,16)),true); + IConfig::Set($arr, 'system', $namespace, (($name) ? $name : substr($arr['mid'], 0, 16)), true); - if ($i) { - $arr['id'] = $i[0]['id']; - // don't update if it has the same timestamp as the original - if ($arr['edited'] > $i[0]['edited']) { - $x = item_store_update($arr,$execflag); - } - } - else { - if (($i) && (intval($i[0]['item_deleted']))) { - // was partially deleted already, finish it off - q("delete from item where mid = '%s' and uid = %d", - dbesc($arr['mid']), - intval(local_channel()) - ); - } - else { - $x = item_store($arr,$execflag); - } - } + if ($i) { + $arr['id'] = $i[0]['id']; + // don't update if it has the same timestamp as the original + if ($arr['edited'] > $i[0]['edited']) { + $x = item_store_update($arr, $execflag); + } + } else { + if (($i) && (intval($i[0]['item_deleted']))) { + // was partially deleted already, finish it off + q( + "delete from item where mid = '%s' and uid = %d", + dbesc($arr['mid']), + intval(local_channel()) + ); + } else { + $x = item_store($arr, $execflag); + } + } - if ($x && $x['success']) { - $element['import_success'] = 1; - } - else { - $element['import_success'] = 0; - } + if ($x && $x['success']) { + $element['import_success'] = 1; + } else { + $element['import_success'] = 0; + } - return $element; + return $element; } -function get_webpage_elements($channel, $type = 'all') { - $elements = []; - if (!$channel['channel_id']) { - return null; - } - switch ($type) { - case 'all': - // If all, execute all the pages, layouts, blocks case statements - case 'pages': - $elements['pages'] = null; - $owner = $channel['channel_id']; +function get_webpage_elements($channel, $type = 'all') +{ + $elements = []; + if (!$channel['channel_id']) { + return null; + } + switch ($type) { + case 'all': + // If all, execute all the pages, layouts, blocks case statements + case 'pages': + $elements['pages'] = null; + $owner = $channel['channel_id']; - $sql_extra = item_permissions_sql($owner); + $sql_extra = item_permissions_sql($owner); - $r = q("select * from iconfig left join item on iconfig.iid = item.id + $r = q( + "select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc", - intval($owner), - intval(ITEM_TYPE_WEBPAGE) - ); + intval($owner), + intval(ITEM_TYPE_WEBPAGE) + ); - $pages = null; + $pages = null; - if ($r) { - $elements['pages'] = []; - $pages = []; - foreach ($r as $rr) { - unobscure($rr); + if ($r) { + $elements['pages'] = []; + $pages = []; + foreach ($r as $rr) { + unobscure($rr); - //$lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock'); + //$lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock'); - $element_arr = [ - 'type' => 'webpage', - 'title' => $rr['title'], - 'body' => $rr['body'], - 'created' => $rr['created'], - 'edited' => $rr['edited'], - 'mimetype' => $rr['mimetype'], - 'pagetitle' => $rr['v'], - 'mid' => $rr['mid'], - 'layout_mid' => $rr['layout_mid'] - ]; - $pages[$rr['iid']][] = [ - 'url' => $rr['iid'], - 'pagetitle' => $rr['v'], - 'title' => $rr['title'], - 'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']), - 'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']), - 'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]', - //'lockstate' => $lockstate - ]; - $elements['pages'][] = $element_arr; - } - } - if ($type !== 'all') { - break; - } + $element_arr = [ + 'type' => 'webpage', + 'title' => $rr['title'], + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'pagetitle' => $rr['v'], + 'mid' => $rr['mid'], + 'layout_mid' => $rr['layout_mid'] + ]; + $pages[$rr['iid']][] = [ + 'url' => $rr['iid'], + 'pagetitle' => $rr['v'], + 'title' => $rr['title'], + 'created' => datetime_convert('UTC', date_default_timezone_get(), $rr['created']), + 'edited' => datetime_convert('UTC', date_default_timezone_get(), $rr['edited']), + 'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]', + //'lockstate' => $lockstate + ]; + $elements['pages'][] = $element_arr; + } + } + if ($type !== 'all') { + break; + } - case 'layouts': - $elements['layouts'] = null; - $owner = $channel['channel_id']; + case 'layouts': + $elements['layouts'] = null; + $owner = $channel['channel_id']; - $sql_extra = item_permissions_sql($owner); + $sql_extra = item_permissions_sql($owner); - $r = q("select * from iconfig left join item on iconfig.iid = item.id + $r = q( + "select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d $sql_extra order by item.created desc", - intval($owner), - intval(ITEM_TYPE_PDL) - ); + intval($owner), + intval(ITEM_TYPE_PDL) + ); - if ($r) { - $elements['layouts'] = []; + if ($r) { + $elements['layouts'] = []; - foreach ($r as $rr) { - unobscure($rr); + foreach ($r as $rr) { + unobscure($rr); - $elements['layouts'][] = array( - 'type' => 'layout', - 'description' => $rr['title'], // description of the layout - 'body' => $rr['body'], - 'created' => $rr['created'], - 'edited' => $rr['edited'], - 'mimetype' => $rr['mimetype'], - 'name' => $rr['v'], // name of reference for the layout - 'mid' => $rr['mid'], - ); - } - } + $elements['layouts'][] = array( + 'type' => 'layout', + 'description' => $rr['title'], // description of the layout + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'name' => $rr['v'], // name of reference for the layout + 'mid' => $rr['mid'], + ); + } + } - if ($type !== 'all') { - break; - } + if ($type !== 'all') { + break; + } - case 'blocks': - $elements['blocks'] = null; - $owner = $channel['channel_id']; + case 'blocks': + $elements['blocks'] = null; + $owner = $channel['channel_id']; - $sql_extra = item_permissions_sql($owner); + $sql_extra = item_permissions_sql($owner); - $r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig + $r = q( + "select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig left join item on iconfig.iid = item.id where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' and item_type = %d order by item.created desc", - intval($owner), - intval(ITEM_TYPE_BLOCK) - ); + intval($owner), + intval(ITEM_TYPE_BLOCK) + ); - if ($r) { - $elements['blocks'] = []; + if ($r) { + $elements['blocks'] = []; - foreach ($r as $rr) { - unobscure($rr); + foreach ($r as $rr) { + unobscure($rr); - $elements['blocks'][] = [ - 'type' => 'block', - 'title' => $rr['title'], - 'body' => $rr['body'], - 'created' => $rr['created'], - 'edited' => $rr['edited'], - 'mimetype' => $rr['mimetype'], - 'name' => $rr['v'], - 'mid' => $rr['mid'] - ]; - } - } + $elements['blocks'][] = [ + 'type' => 'block', + 'title' => $rr['title'], + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'name' => $rr['v'], + 'mid' => $rr['mid'] + ]; + } + } - if ($type !== 'all') { - break; - } + if ($type !== 'all') { + break; + } - default: - break; - } + default: + break; + } - return $elements; + return $elements; } /** @@ -2131,44 +2169,44 @@ function get_webpage_elements($channel, $type = 'all') { * @param bool $overwrite * @return bool Success status */ -function create_zip_file($files = [], $destination = '', $overwrite = false) { - // if the zip file already exists and overwrite is false, return false - if (file_exists($destination) && ! $overwrite) { - return false; - } - //vars - $valid_files = []; - // if files were passed in... - if (is_array($files)) { - // cycle through each file - foreach ($files as $file) { - // make sure the file exists - if (file_exists($file)) { - $valid_files[] = $file; - } - } - } +function create_zip_file($files = [], $destination = '', $overwrite = false) +{ + // if the zip file already exists and overwrite is false, return false + if (file_exists($destination) && ! $overwrite) { + return false; + } + //vars + $valid_files = []; + // if files were passed in... + if (is_array($files)) { + // cycle through each file + foreach ($files as $file) { + // make sure the file exists + if (file_exists($file)) { + $valid_files[] = $file; + } + } + } - // if we have good files... - if (count($valid_files)) { - //create the archive - $zip = new ZipArchive(); - if($zip->open($destination, $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE) !== true) { - return false; - } - // add the files - foreach ($valid_files as $file) { - $zip->addFile($file, $file); - } - //debug - //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status; - //close the zip -- done! - $zip->close(); + // if we have good files... + if (count($valid_files)) { + //create the archive + $zip = new ZipArchive(); + if ($zip->open($destination, $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE) !== true) { + return false; + } + // add the files + foreach ($valid_files as $file) { + $zip->addFile($file, $file); + } + //debug + //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status; + //close the zip -- done! + $zip->close(); - // check to make sure the file exists - return file_exists($destination); - } - else { - return false; - } + // check to make sure the file exists + return file_exists($destination); + } else { + return false; + } } diff --git a/include/items.php b/include/items.php index 62bee009d..5f539eb7e 100644 --- a/include/items.php +++ b/include/items.php @@ -1,17 +1,16 @@ $item, - 'closed' => 'unset' - ]; + $x = [ + 'item' => $item, + 'closed' => 'unset' + ]; - /** - * @hooks comments_are_now_closed - * Called to determine whether commenting should be closed - * * \e array \b item - * * \e boolean \b closed - return value - */ + /** + * @hooks comments_are_now_closed + * Called to determine whether commenting should be closed + * * \e array \b item + * * \e boolean \b closed - return value + */ - call_hooks('comments_are_now_closed', $x); + call_hooks('comments_are_now_closed', $x); - if ($x['closed'] !== 'unset') { - return $x['closed']; - } + if ($x['closed'] !== 'unset') { + return $x['closed']; + } - if ($item['comments_closed'] > NULL_DATE && datetime_convert() > $item['comments_closed']) { - return true; - } + if ($item['comments_closed'] > NULL_DATE && datetime_convert() > $item['comments_closed']) { + return true; + } - return false; + return false; } -function item_normal() { - return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 +function item_normal() +{ + return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 and item.obj_type != '" . ACTIVITY_OBJ_FILE . "' "; } -function item_normal_draft() { - return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 +function item_normal_draft() +{ + return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 and item.obj_type != '" . ACTIVITY_OBJ_FILE . "' "; } -function item_normal_search() { - return " and item.item_hidden = 0 and item.item_type in (0,3,6,7) and item.item_deleted = 0 +function item_normal_search() +{ + return " and item.item_hidden = 0 and item.item_type in (0,3,6,7) and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 and item.obj_type != '" . ACTIVITY_OBJ_FILE . "' "; } -function item_normal_update() { - return " and item.item_hidden = 0 and item.item_type = 0 +function item_normal_update() +{ + return " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 and item.obj_type != '" . ACTIVITY_OBJ_FILE . "' "; } -function item_normal_moderate() { - return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 +function item_normal_moderate() +{ + return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 and item.item_blocked in (0, 4) and item.obj_type != '" . ACTIVITY_OBJ_FILE . "' "; } @@ -265,15 +271,18 @@ function item_normal_moderate() { * * @param array $item */ -function is_item_normal($item) { +function is_item_normal($item) +{ - if (intval($item['item_hidden']) || intval($item['item_type']) || intval($item['item_deleted']) - || intval($item['item_unpublished']) || intval($item['item_delayed']) || intval($item['item_pending_remove']) - || intval($item['item_blocked']) || ($item['obj_type'] == ACTIVITY_OBJ_FILE)) { - return false; - } + if ( + intval($item['item_hidden']) || intval($item['item_type']) || intval($item['item_deleted']) + || intval($item['item_unpublished']) || intval($item['item_delayed']) || intval($item['item_pending_remove']) + || intval($item['item_blocked']) || ($item['obj_type'] == ACTIVITY_OBJ_FILE) + ) { + return false; + } - return true; + return true; } /** @@ -291,111 +300,112 @@ function is_item_normal($item) { * @param array $item * @return bool */ -function can_comment_on_post($observer_xchan, $item) { +function can_comment_on_post($observer_xchan, $item) +{ -// logger('Comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG); +// logger('Comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG); - $x = [ - 'observer_hash' => $observer_xchan, - 'item' => $item, - 'allowed' => 'unset' - ]; + $x = [ + 'observer_hash' => $observer_xchan, + 'item' => $item, + 'allowed' => 'unset' + ]; - /** - * @hooks can_comment_on_post - * Called when deciding whether or not to present a comment box for a post. - * * \e string \b observer_hash - * * \e array \b item - * * \e boolean \b allowed - return value - */ + /** + * @hooks can_comment_on_post + * Called when deciding whether or not to present a comment box for a post. + * * \e string \b observer_hash + * * \e array \b item + * * \e boolean \b allowed - return value + */ - call_hooks('can_comment_on_post', $x); + call_hooks('can_comment_on_post', $x); - if ($x['allowed'] !== 'unset') { - return $x['allowed']; - } + if ($x['allowed'] !== 'unset') { + return $x['allowed']; + } - if (! $observer_xchan) { - return false; - } + if (! $observer_xchan) { + return false; + } - if ($item['comment_policy'] === 'none') { - return false; - } + if ($item['comment_policy'] === 'none') { + return false; + } - if (intval($item['item_nocomment'])) { - return false; - } + if (intval($item['item_nocomment'])) { + return false; + } - if (comments_are_now_closed($item)) { - return false; - } + if (comments_are_now_closed($item)) { + return false; + } - if ($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { - return true; - } + if ($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { + return true; + } - switch ($item['comment_policy']) { - case 'self': - if ($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { - return true; - } - break; - case 'public': - case 'authenticated': - // Anonymous folks won't ever reach this point (as $observer_xchan will be empty). - // This means the viewer has an xchan and we can identify them. - return true; - break; - case 'any connections': - case 'specific': - case 'contacts': - case '': + switch ($item['comment_policy']) { + case 'self': + if ($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { + return true; + } + break; + case 'public': + case 'authenticated': + // Anonymous folks won't ever reach this point (as $observer_xchan will be empty). + // This means the viewer has an xchan and we can identify them. + return true; + break; + case 'any connections': + case 'specific': + case 'contacts': + case '': + // local posts only - check if the post owner granted me + // comment permission + if (local_channel() && array_key_exists('owner', $item) && their_perms_contains(local_channel(), $item['owner']['abook_xchan'], 'post_comments')) { + return true; + } - // local posts only - check if the post owner granted me - // comment permission - if (local_channel() && array_key_exists('owner',$item) && their_perms_contains(local_channel(),$item['owner']['abook_xchan'],'post_comments')) { - return true; - } + if (intval($item['item_wall']) && perm_is_allowed($item['uid'], $observer_xchan, 'post_comments')) { + return true; + } + break; + default: + break; + } + if (strstr($item['comment_policy'], 'network:') && strstr($item['comment_policy'], 'red')) { + return true; + } - if (intval($item['item_wall']) && perm_is_allowed($item['uid'],$observer_xchan,'post_comments')) { - return true; - } - break; - default: - break; - } - if (strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) { - return true; - } - - if (strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'activitypub')) { - return true; - } + if (strstr($item['comment_policy'], 'network:') && strstr($item['comment_policy'], 'activitypub')) { + return true; + } - if (strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname())) { - return true; - } + if (strstr($item['comment_policy'], 'site:') && strstr($item['comment_policy'], App::get_hostname())) { + return true; + } - return false; + return false; } -function absolutely_no_comments($item) { +function absolutely_no_comments($item) +{ - if ($item['comment_policy'] === 'none') { - return true; - } + if ($item['comment_policy'] === 'none') { + return true; + } - if (intval($item['item_nocomment'])) { - return true; - } + if (intval($item['item_nocomment'])) { + return true; + } - if(comments_are_now_closed($item)) { - return true; - } + if (comments_are_now_closed($item)) { + return true; + } - return false; + return false; } @@ -415,23 +425,26 @@ function absolutely_no_comments($item) { * @param string $hash * xchan_hash of the channel that sent the item */ -function add_source_route($iid, $hash) { -// logger('add_source_route ' . $iid . ' ' . $hash, LOGGER_DEBUG); +function add_source_route($iid, $hash) +{ +// logger('add_source_route ' . $iid . ' ' . $hash, LOGGER_DEBUG); - if ((! $iid) || (! $hash)) { - return; - } + if ((! $iid) || (! $hash)) { + return; + } - $r = q("select route from item where id = %d limit 1", - intval($iid) - ); - if ($r) { - $new_route = (($r[0]['route']) ? $r[0]['route'] . ',' : '') . $hash; - q("update item set route = '%s' where id = %d", - dbesc($new_route), - intval($iid) - ); - } + $r = q( + "select route from item where id = %d limit 1", + intval($iid) + ); + if ($r) { + $new_route = (($r[0]['route']) ? $r[0]['route'] . ',' : '') . $hash; + q( + "update item set route = '%s' where id = %d", + dbesc($new_route), + intval($iid) + ); + } } @@ -449,125 +462,133 @@ function add_source_route($iid, $hash) { * * \e boolean \b success true or false * * \e array \b activity the resulting activity if successful */ -function post_activity_item($arr, $allow_code = false, $deliver = true) { +function post_activity_item($arr, $allow_code = false, $deliver = true) +{ - $ret = [ 'success' => false ]; + $ret = [ 'success' => false ]; - $is_comment = false; - if ((isset($arr['parent']) && $arr['parent'] && $arr['parent'] != $arr['id']) || (isset($arr['parent_mid']) && $arr['parent_mid'] && $arr['parent_mid'] != $arr['mid'])) { - $is_comment = true; - } - if (! array_key_exists('item_origin',$arr)) { - $arr['item_origin'] = 1; - } - if (! array_key_exists('item_wall',$arr) && (! $is_comment)) { - $arr['item_wall'] = 0; - } - if (! array_key_exists('item_thread_top',$arr) && (! $is_comment)) { - $arr['item_thread_top'] = 1; - } + $is_comment = false; + if ((isset($arr['parent']) && $arr['parent'] && $arr['parent'] != $arr['id']) || (isset($arr['parent_mid']) && $arr['parent_mid'] && $arr['parent_mid'] != $arr['mid'])) { + $is_comment = true; + } + if (! array_key_exists('item_origin', $arr)) { + $arr['item_origin'] = 1; + } + if (! array_key_exists('item_wall', $arr) && (! $is_comment)) { + $arr['item_wall'] = 0; + } + if (! array_key_exists('item_thread_top', $arr) && (! $is_comment)) { + $arr['item_thread_top'] = 1; + } - $channel = App::get_channel(); - $observer = App::get_observer(); + $channel = App::get_channel(); + $observer = App::get_observer(); - $arr['aid'] = ((isset($arr['aid'])) ? $arr['aid'] : $channel['channel_account_id']); - $arr['uid'] = ((isset($arr['uid'])) ? $arr['uid'] : $channel['channel_id']); + $arr['aid'] = ((isset($arr['aid'])) ? $arr['aid'] : $channel['channel_account_id']); + $arr['uid'] = ((isset($arr['uid'])) ? $arr['uid'] : $channel['channel_id']); - if (! perm_is_allowed($arr['uid'],$observer['xchan_hash'],(($is_comment) ? 'post_comments' : 'post_wall'))) { - $ret['message'] = t('Permission denied'); - return $ret; - } + if (! perm_is_allowed($arr['uid'], $observer['xchan_hash'], (($is_comment) ? 'post_comments' : 'post_wall'))) { + $ret['message'] = t('Permission denied'); + return $ret; + } - if (! array_key_exists('mimetype',$arr)) { - $arr['mimetype'] = 'text/bbcode'; - } + if (! array_key_exists('mimetype', $arr)) { + $arr['mimetype'] = 'text/bbcode'; + } if (! (isset($arr['mid']) && $arr['mid'])) { $arr['uuid'] = ((isset($arr['uuid'])) ? $arr['uuid'] : new_uuid()); } $arr['mid'] = ((isset($arr['mid'])) ? $arr['mid'] : z_root() . '/item/' . $arr['uuid']); - $arr['parent_mid'] = ((isset($arr['parent_mid'])) ? $arr['parent_mid'] : $arr['mid']); - $arr['thr_parent'] = ((isset($arr['thr_parent'])) ? $arr['thr_parent'] : $arr['mid']); + $arr['parent_mid'] = ((isset($arr['parent_mid'])) ? $arr['parent_mid'] : $arr['mid']); + $arr['thr_parent'] = ((isset($arr['thr_parent'])) ? $arr['thr_parent'] : $arr['mid']); - $arr['owner_xchan'] = ((isset($arr['owner_xchan'])) ? $arr['owner_xchan'] : $channel['channel_hash']); - $arr['author_xchan'] = ((isset($arr['author_xchan'])) ? $arr['author_xchan'] : $observer['xchan_hash']); + $arr['owner_xchan'] = ((isset($arr['owner_xchan'])) ? $arr['owner_xchan'] : $channel['channel_hash']); + $arr['author_xchan'] = ((isset($arr['author_xchan'])) ? $arr['author_xchan'] : $observer['xchan_hash']); - $arr['verb'] = ((x($arr,'verb')) ? $arr['verb'] : ACTIVITY_POST); - $arr['obj_type'] = ((x($arr,'obj_type')) ? $arr['obj_type'] : ACTIVITY_OBJ_ARTICLE); + $arr['verb'] = ((x($arr, 'verb')) ? $arr['verb'] : ACTIVITY_POST); + $arr['obj_type'] = ((x($arr, 'obj_type')) ? $arr['obj_type'] : ACTIVITY_OBJ_ARTICLE); - if(! ( array_key_exists('allow_cid',$arr) || array_key_exists('allow_gid',$arr) - || array_key_exists('deny_cid',$arr) || array_key_exists('deny_gid',$arr))) { - $arr['allow_cid'] = $channel['channel_allow_cid']; - $arr['allow_gid'] = $channel['channel_allow_gid']; - $arr['deny_cid'] = $channel['channel_deny_cid']; - $arr['deny_gid'] = $channel['channel_deny_gid']; - } + if ( + ! ( array_key_exists('allow_cid', $arr) || array_key_exists('allow_gid', $arr) + || array_key_exists('deny_cid', $arr) || array_key_exists('deny_gid', $arr)) + ) { + $arr['allow_cid'] = $channel['channel_allow_cid']; + $arr['allow_gid'] = $channel['channel_allow_gid']; + $arr['deny_cid'] = $channel['channel_deny_cid']; + $arr['deny_gid'] = $channel['channel_deny_gid']; + } - $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments')); + $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'post_comments')); - if ((! $arr['plink']) && (intval($arr['item_thread_top']))) { - $arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']),0,190); - } + if ((! $arr['plink']) && (intval($arr['item_thread_top']))) { + $arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']), 0, 190); + } - // for the benefit of plugins, we will behave as if this is an API call rather than a normal online post + // for the benefit of plugins, we will behave as if this is an API call rather than a normal online post - $_REQUEST['api_source'] = 1; + $_REQUEST['api_source'] = 1; - /** - * @hooks post_local - * Called when an item has been posted on this machine via mod/item.php (also via API). - */ - call_hooks('post_local', $arr); + /** + * @hooks post_local + * Called when an item has been posted on this machine via mod/item.php (also via API). + */ + call_hooks('post_local', $arr); - if(x($arr, 'cancel')) { - logger('Post cancelled by plugin.'); - return $ret; - } + if (x($arr, 'cancel')) { + logger('Post cancelled by plugin.'); + return $ret; + } - $post = item_store($arr,$allow_code,$deliver); + $post = item_store($arr, $allow_code, $deliver); - if($post['success']) { - $post_id = $post['item_id']; - $ret['success'] = true; - $ret['item_id'] = $post_id; - $ret['activity'] = $post['item']; + if ($post['success']) { + $post_id = $post['item_id']; + $ret['success'] = true; + $ret['item_id'] = $post_id; + $ret['activity'] = $post['item']; - /** - * @hooks post_local_end - * Called after a local post operation has completed. - * * \e array - the item returned from item_store() - */ - call_hooks('post_local_end', $ret['activity']); - } + /** + * @hooks post_local_end + * Called after a local post operation has completed. + * * \e array - the item returned from item_store() + */ + call_hooks('post_local_end', $ret['activity']); + } - if($post_id && $deliver) { - Run::Summon([ 'Notifier','activity',$post_id ]); - } + if ($post_id && $deliver) { + Run::Summon([ 'Notifier','activity',$post_id ]); + } - $ret['success'] = true; + $ret['success'] = true; - return $ret; + return $ret; } -function validate_item_elements($message,$arr) { +function validate_item_elements($message, $arr) +{ - $result = array('success' => false); + $result = array('success' => false); - if(! array_key_exists('created',$arr)) - $result['message'] = 'missing created, possible author/owner lookup failure'; + if (! array_key_exists('created', $arr)) { + $result['message'] = 'missing created, possible author/owner lookup failure'; + } - if((! $arr['mid']) || (! $arr['parent_mid'])) - $result['message'] = 'missing message-id or parent message-id'; + if ((! $arr['mid']) || (! $arr['parent_mid'])) { + $result['message'] = 'missing message-id or parent message-id'; + } - if(array_key_exists('flags',$message) && in_array('relay',$message['flags']) && $arr['mid'] === $arr['parent_mid']) - $result['message'] = 'relay set on top level post'; + if (array_key_exists('flags', $message) && in_array('relay', $message['flags']) && $arr['mid'] === $arr['parent_mid']) { + $result['message'] = 'relay set on top level post'; + } - if(! $result['message']) - $result['success'] = true; + if (! $result['message']) { + $result['success'] = true; + } - return $result; + return $result; } @@ -580,386 +601,391 @@ function validate_item_elements($message,$arr) { * @param string $body * @return string */ -function limit_body_size($body) { +function limit_body_size($body) +{ - $maxlen = get_max_import_size(); + $maxlen = get_max_import_size(); - // If the length of the body, including the embedded images, is smaller - // than the maximum, then don't waste time looking for the images - if($maxlen && (strlen($body) > $maxlen)) { + // If the length of the body, including the embedded images, is smaller + // than the maximum, then don't waste time looking for the images + if ($maxlen && (strlen($body) > $maxlen)) { + $orig_body = $body; + $new_body = ''; + $textlen = 0; - $orig_body = $body; - $new_body = ''; - $textlen = 0; + $img_start = strpos($orig_body, '[img'); + $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); + $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); + while (($img_st_close !== false) && ($img_end !== false)) { + $img_st_close++; // make it point to AFTER the closing bracket + $img_end += $img_start; + $img_end += strlen('[/img]'); - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - while(($img_st_close !== false) && ($img_end !== false)) { + if (! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { + // This is an embedded image - $img_st_close++; // make it point to AFTER the closing bracket - $img_end += $img_start; - $img_end += strlen('[/img]'); + if (($textlen + $img_start) > $maxlen) { + if ($textlen < $maxlen) { + logger('The limit happens before an embedded image', LOGGER_DEBUG); + $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); + $textlen = $maxlen; + } + } else { + $new_body = $new_body . substr($orig_body, 0, $img_start); + $textlen += $img_start; + } - if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { - // This is an embedded image + $new_body = $new_body . substr($orig_body, $img_start, $img_end - $img_start); + } else { + if (($textlen + $img_end) > $maxlen) { + if ($textlen < $maxlen) { + $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); + $textlen = $maxlen; + } + } else { + $new_body = $new_body . substr($orig_body, 0, $img_end); + $textlen += $img_end; + } + } + $orig_body = substr($orig_body, $img_end); - if( ($textlen + $img_start) > $maxlen ) { - if($textlen < $maxlen) { - logger('The limit happens before an embedded image', LOGGER_DEBUG); - $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); - $textlen = $maxlen; - } - } - else { - $new_body = $new_body . substr($orig_body, 0, $img_start); - $textlen += $img_start; - } + if ($orig_body === false) { // in case the body ends on a closing image tag + $orig_body = ''; + } - $new_body = $new_body . substr($orig_body, $img_start, $img_end - $img_start); - } - else { - if( ($textlen + $img_end) > $maxlen ) { - if($textlen < $maxlen) { - $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); - $textlen = $maxlen; - } - } - else { - $new_body = $new_body . substr($orig_body, 0, $img_end); - $textlen += $img_end; - } - } - $orig_body = substr($orig_body, $img_end); + $img_start = strpos($orig_body, '[img'); + $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); + $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); + } - if($orig_body === false) // in case the body ends on a closing image tag - $orig_body = ''; + if (($textlen + strlen($orig_body)) > $maxlen) { + if ($textlen < $maxlen) { + $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); + $textlen = $maxlen; + } + } else { + $new_body = $new_body . $orig_body; + $textlen += strlen($orig_body); + } - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - } - - if( ($textlen + strlen($orig_body)) > $maxlen) { - if($textlen < $maxlen) { - $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); - $textlen = $maxlen; - } - } - else { - $new_body = $new_body . $orig_body; - $textlen += strlen($orig_body); - } - - return $new_body; - } - else - return $body; + return $new_body; + } else { + return $body; + } } -function get_item_elements($x,$allow_code = false) { +function get_item_elements($x, $allow_code = false) +{ - $arr = []; + $arr = []; - $arr['body'] = $x['body']; - $arr['summary'] = $x['summary']; + $arr['body'] = $x['body']; + $arr['summary'] = $x['summary']; - $maxlen = get_max_import_size(); + $maxlen = get_max_import_size(); - if($maxlen && mb_strlen($arr['body']) > $maxlen) { - $arr['body'] = mb_substr($arr['body'],0,$maxlen,'UTF-8'); - logger('get_item_elements: message length exceeds max_import_size: truncated'); - } + if ($maxlen && mb_strlen($arr['body']) > $maxlen) { + $arr['body'] = mb_substr($arr['body'], 0, $maxlen, 'UTF-8'); + logger('get_item_elements: message length exceeds max_import_size: truncated'); + } - if($maxlen && mb_strlen($arr['summary']) > $maxlen) { - $arr['summary'] = mb_substr($arr['summary'],0,$maxlen,'UTF-8'); - logger('get_item_elements: message summary length exceeds max_import_size: truncated'); - } + if ($maxlen && mb_strlen($arr['summary']) > $maxlen) { + $arr['summary'] = mb_substr($arr['summary'], 0, $maxlen, 'UTF-8'); + logger('get_item_elements: message summary length exceeds max_import_size: truncated'); + } - $arr['created'] = datetime_convert('UTC','UTC',$x['created']); - $arr['edited'] = datetime_convert('UTC','UTC',$x['edited']); + $arr['created'] = datetime_convert('UTC', 'UTC', $x['created']); + $arr['edited'] = datetime_convert('UTC', 'UTC', $x['edited']); - $arr['expires'] = ((x($x,'expires') && $x['expires']) - ? datetime_convert('UTC','UTC',$x['expires']) - : NULL_DATE); + $arr['expires'] = ((x($x, 'expires') && $x['expires']) + ? datetime_convert('UTC', 'UTC', $x['expires']) + : NULL_DATE); - $arr['commented'] = ((x($x,'commented') && $x['commented']) - ? datetime_convert('UTC','UTC',$x['commented']) - : $arr['created']); - $arr['comments_closed'] = ((x($x,'comments_closed') && $x['comments_closed']) - ? datetime_convert('UTC','UTC',$x['comments_closed']) - : NULL_DATE); + $arr['commented'] = ((x($x, 'commented') && $x['commented']) + ? datetime_convert('UTC', 'UTC', $x['commented']) + : $arr['created']); + $arr['comments_closed'] = ((x($x, 'comments_closed') && $x['comments_closed']) + ? datetime_convert('UTC', 'UTC', $x['comments_closed']) + : NULL_DATE); - $arr['title'] = (($x['title']) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['title'] = (($x['title']) ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8', false) : ''); - if(mb_strlen($arr['title']) > 255) - $arr['title'] = mb_substr($arr['title'],0,255); + if (mb_strlen($arr['title']) > 255) { + $arr['title'] = mb_substr($arr['title'], 0, 255); + } - $arr['uuid'] = (($x['uuid']) ? htmlspecialchars($x['uuid'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['app'] = (($x['app']) ? htmlspecialchars($x['app'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['route'] = (($x['route']) ? htmlspecialchars($x['route'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['mid'] = (($x['message_id']) ? htmlspecialchars($x['message_id'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['parent_mid'] = (($x['message_top']) ? htmlspecialchars($x['message_top'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['thr_parent'] = (($x['message_parent']) ? htmlspecialchars($x['message_parent'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['uuid'] = (($x['uuid']) ? htmlspecialchars($x['uuid'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['app'] = (($x['app']) ? htmlspecialchars($x['app'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['route'] = (($x['route']) ? htmlspecialchars($x['route'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['mid'] = (($x['message_id']) ? htmlspecialchars($x['message_id'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['parent_mid'] = (($x['message_top']) ? htmlspecialchars($x['message_top'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['thr_parent'] = (($x['message_parent']) ? htmlspecialchars($x['message_parent'], ENT_COMPAT, 'UTF-8', false) : ''); - $arr['plink'] = (($x['permalink']) ? htmlspecialchars($x['permalink'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['location'] = (($x['location']) ? htmlspecialchars($x['location'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['coord'] = (($x['longlat']) ? htmlspecialchars($x['longlat'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['verb'] = (($x['verb']) ? htmlspecialchars($x['verb'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['mimetype'] = (($x['mimetype']) ? htmlspecialchars($x['mimetype'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['obj_type'] = (($x['object_type']) ? htmlspecialchars($x['object_type'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['tgt_type'] = (($x['target_type']) ? htmlspecialchars($x['target_type'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['plink'] = (($x['permalink']) ? htmlspecialchars($x['permalink'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['location'] = (($x['location']) ? htmlspecialchars($x['location'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['coord'] = (($x['longlat']) ? htmlspecialchars($x['longlat'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['verb'] = (($x['verb']) ? htmlspecialchars($x['verb'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['mimetype'] = (($x['mimetype']) ? htmlspecialchars($x['mimetype'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['obj_type'] = (($x['object_type']) ? htmlspecialchars($x['object_type'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['tgt_type'] = (($x['target_type']) ? htmlspecialchars($x['target_type'], ENT_COMPAT, 'UTF-8', false) : ''); - // convert AS1 namespaced elements to AS-JSONLD + // convert AS1 namespaced elements to AS-JSONLD - $arr['verb'] = Activity::activity_mapper($arr['verb']); - $arr['obj_type'] = Activity::activity_obj_mapper($arr['obj_type']); - $arr['tgt_type'] = Activity::activity_obj_mapper($arr['tgt_type']); + $arr['verb'] = Activity::activity_mapper($arr['verb']); + $arr['obj_type'] = Activity::activity_obj_mapper($arr['obj_type']); + $arr['tgt_type'] = Activity::activity_obj_mapper($arr['tgt_type']); - $arr['comment_policy'] = (($x['comment_scope']) ? htmlspecialchars($x['comment_scope'], ENT_COMPAT,'UTF-8',false) : 'contacts'); + $arr['comment_policy'] = (($x['comment_scope']) ? htmlspecialchars($x['comment_scope'], ENT_COMPAT, 'UTF-8', false) : 'contacts'); - $arr['sig'] = (($x['signature']) ? htmlspecialchars($x['signature'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['sig'] = (($x['signature']) ? htmlspecialchars($x['signature'], ENT_COMPAT, 'UTF-8', false) : ''); - // fix old-style signatures imported from hubzilla via polling and zot_feed - // so they verify. + // fix old-style signatures imported from hubzilla via polling and zot_feed + // so they verify. - if($arr['sig'] && (! strpos($arr['sig'],'.'))) { - $arr['sig'] = 'sha256.' . $arr['sig']; - } + if ($arr['sig'] && (! strpos($arr['sig'], '.'))) { + $arr['sig'] = 'sha256.' . $arr['sig']; + } - $arr['obj'] = activity_sanitise($x['object']); + $arr['obj'] = activity_sanitise($x['object']); - if($arr['obj'] && is_array($arr['obj']) && array_key_exists('asld',$arr['obj'])) { - $arr['obj'] = $arr['obj']['asld']; - } + if ($arr['obj'] && is_array($arr['obj']) && array_key_exists('asld', $arr['obj'])) { + $arr['obj'] = $arr['obj']['asld']; + } - $arr['target'] = activity_sanitise($x['target']); + $arr['target'] = activity_sanitise($x['target']); - if($arr['target'] && is_array($arr['target']) && array_key_exists('asld',$arr['target'])) { - $arr['target'] = $arr['target']['asld']; - } + if ($arr['target'] && is_array($arr['target']) && array_key_exists('asld', $arr['target'])) { + $arr['target'] = $arr['target']['asld']; + } - $arr['attach'] = activity_sanitise($x['attach']); - $arr['replyto'] = activity_sanitise($c['replyto']); - $arr['term'] = decode_tags($x['tags']); - $arr['iconfig'] = decode_item_meta($x['meta']); + $arr['attach'] = activity_sanitise($x['attach']); + $arr['replyto'] = activity_sanitise($c['replyto']); + $arr['term'] = decode_tags($x['tags']); + $arr['iconfig'] = decode_item_meta($x['meta']); - $arr['item_private'] = 0; - $arr['item_flags'] = 0; + $arr['item_private'] = 0; + $arr['item_flags'] = 0; - if(array_key_exists('flags',$x)) { + if (array_key_exists('flags', $x)) { + if (in_array('consensus', $x['flags'])) { + $arr['item_consensus'] = 1; + } - if(in_array('consensus',$x['flags'])) - $arr['item_consensus'] = 1; + if (in_array('deleted', $x['flags'])) { + $arr['item_deleted'] = 1; + } - if(in_array('deleted',$x['flags'])) - $arr['item_deleted'] = 1; + if (in_array('notshown', $x['flags'])) { + $arr['item_notshown'] = 1; + } - if(in_array('notshown',$x['flags'])) - $arr['item_notshown'] = 1; + if (in_array('obscured', $x['flags'])) { + $arr['item_obscured'] = 1; + } - if(in_array('obscured',$x['flags'])) - $arr['item_obscured'] = 1; + // hidden item are no longer propagated - notshown may be a suitable alternative - // hidden item are no longer propagated - notshown may be a suitable alternative + if (in_array('hidden', $x['flags'])) { + $arr['item_hidden'] = 1; + } - if(in_array('hidden',$x['flags'])) - $arr['item_hidden'] = 1; + if (in_array('private', $x['flags'])) { + $arr['item_private'] = 1; + } - if(in_array('private',$x['flags'])) - $arr['item_private'] = 1; + if (in_array('direct', $x['flags'])) { + $arr['item_private'] = 2; + } + } - if(in_array('direct',$x['flags'])) - $arr['item_private'] = 2; + // Here's the deal - the site might be down or whatever but if there's a new person you've never + // seen before sending stuff to your stream, we MUST be able to look them up and import their data from their + // hub and verify that they are legit - or else we're going to toss the post. We only need to do this + // once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier + // and not enough info to be able to look you up from your hash - which is the only thing stored with the post. - } + $xchan_hash = import_author_xchan($x['author']); + if ($xchan_hash) { + $arr['author_xchan'] = $xchan_hash; + } else { + return []; + } - // Here's the deal - the site might be down or whatever but if there's a new person you've never - // seen before sending stuff to your stream, we MUST be able to look them up and import their data from their - // hub and verify that they are legit - or else we're going to toss the post. We only need to do this - // once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier - // and not enough info to be able to look you up from your hash - which is the only thing stored with the post. + $xchan_hash = import_author_xchan($x['owner']); + if ($xchan_hash) { + $arr['owner_xchan'] = $xchan_hash; + } else { + return []; + } - $xchan_hash = import_author_xchan($x['author']); - if($xchan_hash) - $arr['author_xchan'] = $xchan_hash; - else - return []; + // Check signature on the body text received. + // This presents an issue that we aren't verifying the text that is actually displayed + // on this site. We are however verifying the received text was exactly as received. + // We have every right to strip content that poses a security risk. You are welcome to + // create a plugin to verify the content after filtering if this offends you. - $xchan_hash = import_author_xchan($x['owner']); - if($xchan_hash) { - $arr['owner_xchan'] = $xchan_hash; - } - else { - return []; - } + if ($arr['sig']) { + // check the supplied signature against the supplied content. + // Note that we will purify the content which could change it. - // Check signature on the body text received. - // This presents an issue that we aren't verifying the text that is actually displayed - // on this site. We are however verifying the received text was exactly as received. - // We have every right to strip content that poses a security risk. You are welcome to - // create a plugin to verify the content after filtering if this offends you. + $r = q( + "select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", + dbesc($arr['author_xchan']) + ); + if ($r) { + if ($r[0]['xchan_pubkey']) { + if (Libzot::verify($x['body'], $arr['sig'], $r[0]['xchan_pubkey'])) { + $arr['item_verified'] = 1; + } else { + logger('get_item_elements: message verification failed.'); + } + } else { + // If we don't have a public key, strip the signature so it won't show as invalid. + // This won't happen in normal use, but could happen if import_author_xchan() + // failed to load the zot-info packet due to a server failure and had + // to create an alternate xchan with network 'unknown' - if($arr['sig']) { + unset($arr['sig']); + } + } + } - // check the supplied signature against the supplied content. - // Note that we will purify the content which could change it. + // Strip old-style hubzilla bookmarks + // Do this after signature verification - $r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", - dbesc($arr['author_xchan']) - ); - if($r) { - if($r[0]['xchan_pubkey']) { - if(Libzot::verify($x['body'],$arr['sig'],$r[0]['xchan_pubkey'])) { - $arr['item_verified'] = 1; - } - else { - logger('get_item_elements: message verification failed.'); - } - } - else { + if (strpos($x['body'], "#^[") !== false) { + $x['body'] = str_replace("#^[", "[", $x['body']); + } - // If we don't have a public key, strip the signature so it won't show as invalid. - // This won't happen in normal use, but could happen if import_author_xchan() - // failed to load the zot-info packet due to a server failure and had - // to create an alternate xchan with network 'unknown' + // if the input is markdown, remove one level of html escaping. + // It will be re-applied in item_store() and/or item_store_update(). + // Do this after signature checking as the original signature + // was generated on the escaped content. - unset($arr['sig']); - } - } - } + if ($arr['mimetype'] === 'text/markdown') { + $arr['summary'] = MarkdownSoap::unescape($arr['summary']); + $arr['body'] = MarkdownSoap::unescape($arr['body']); + } - // Strip old-style hubzilla bookmarks - // Do this after signature verification + if (array_key_exists('revision', $x)) { + // extended export encoding - if(strpos($x['body'],"#^[") !== false) { - $x['body'] = str_replace("#^[","[",$x['body']); - } + $arr['revision'] = $x['revision']; + $arr['allow_cid'] = $x['allow_cid']; + $arr['allow_gid'] = $x['allow_gid']; + $arr['deny_cid'] = $x['deny_cid']; + $arr['deny_gid'] = $x['deny_gid']; + $arr['layout_mid'] = $x['layout_mid']; + $arr['postopts'] = $x['postopts']; + $arr['resource_id'] = $x['resource_id']; + $arr['resource_type'] = $x['resource_type']; + $arr['attach'] = $x['attach']; + $arr['item_origin'] = intval($x['item_origin']); + $arr['item_unseen'] = intval($x['item_unseen']); + $arr['item_starred'] = intval($x['item_starred']); + $arr['item_uplink'] = intval($x['item_uplink']); + $arr['item_consensus'] = intval($x['item_consensus']); + $arr['item_wall'] = intval($x['item_wall']); + $arr['item_thread_top'] = intval($x['item_thread_top']); + $arr['item_notshown'] = intval($x['item_notshown']); + $arr['item_nsfw'] = intval($x['item_nsfw']); + // local only $arr['item_relay'] = $x['item_relay']; + $arr['item_mentionsme'] = intval($x['item_mentionsme']); + $arr['item_nocomment'] = intval($x['item_nocomment']); + $arr['item_obscured'] = intval($x['item_obscured']); + // local only $arr['item_verified'] = $x['item_verified']; + $arr['item_retained'] = intval($x['item_retained']); + $arr['item_rss'] = intval($x['item_rss']); + $arr['item_deleted'] = intval($x['item_deleted']); + $arr['item_type'] = intval($x['item_type']); + $arr['item_hidden'] = intval($x['item_hidden']); + $arr['item_unpublished'] = intval($x['item_unpublished']); + $arr['item_delayed'] = intval($x['item_delayed']); + $arr['item_pending_remove'] = intval($x['item_pending_remove']); + $arr['item_blocked'] = intval($x['item_blocked']); + $arr['item_restrict'] = intval($x['item_restrict']); + $arr['item_flags'] = intval($x['item_flags']); + } - // if the input is markdown, remove one level of html escaping. - // It will be re-applied in item_store() and/or item_store_update(). - // Do this after signature checking as the original signature - // was generated on the escaped content. - - if($arr['mimetype'] === 'text/markdown') { - $arr['summary'] = MarkdownSoap::unescape($arr['summary']); - $arr['body'] = MarkdownSoap::unescape($arr['body']); - } - - if(array_key_exists('revision',$x)) { - - // extended export encoding - - $arr['revision'] = $x['revision']; - $arr['allow_cid'] = $x['allow_cid']; - $arr['allow_gid'] = $x['allow_gid']; - $arr['deny_cid'] = $x['deny_cid']; - $arr['deny_gid'] = $x['deny_gid']; - $arr['layout_mid'] = $x['layout_mid']; - $arr['postopts'] = $x['postopts']; - $arr['resource_id'] = $x['resource_id']; - $arr['resource_type'] = $x['resource_type']; - $arr['attach'] = $x['attach']; - $arr['item_origin'] = intval($x['item_origin']); - $arr['item_unseen'] = intval($x['item_unseen']); - $arr['item_starred'] = intval($x['item_starred']); - $arr['item_uplink'] = intval($x['item_uplink']); - $arr['item_consensus'] = intval($x['item_consensus']); - $arr['item_wall'] = intval($x['item_wall']); - $arr['item_thread_top'] = intval($x['item_thread_top']); - $arr['item_notshown'] = intval($x['item_notshown']); - $arr['item_nsfw'] = intval($x['item_nsfw']); - // local only $arr['item_relay'] = $x['item_relay']; - $arr['item_mentionsme'] = intval($x['item_mentionsme']); - $arr['item_nocomment'] = intval($x['item_nocomment']); - $arr['item_obscured'] = intval($x['item_obscured']); - // local only $arr['item_verified'] = $x['item_verified']; - $arr['item_retained'] = intval($x['item_retained']); - $arr['item_rss'] = intval($x['item_rss']); - $arr['item_deleted'] = intval($x['item_deleted']); - $arr['item_type'] = intval($x['item_type']); - $arr['item_hidden'] = intval($x['item_hidden']); - $arr['item_unpublished'] = intval($x['item_unpublished']); - $arr['item_delayed'] = intval($x['item_delayed']); - $arr['item_pending_remove'] = intval($x['item_pending_remove']); - $arr['item_blocked'] = intval($x['item_blocked']); - $arr['item_restrict'] = intval($x['item_restrict']); - $arr['item_flags'] = intval($x['item_flags']); - - } - - return $arr; + return $arr; } -function import_author_xchan($x) { +function import_author_xchan($x) +{ - if(! $x) { - return false; - } + if (! $x) { + return false; + } - $arr = [ - 'xchan' => $x, - 'xchan_hash' => '' - ]; - /** - * @hooks import_author_xchan - * Called when looking up an author of a post by xchan_hash to ensure they have an xchan record on our site. - * * \e array \b xchan - * * \e string \b xchan_hash - The returned value - */ - call_hooks('import_author_xchan', $arr); - if($arr['xchan_hash']) - return $arr['xchan_hash']; + $arr = [ + 'xchan' => $x, + 'xchan_hash' => '' + ]; + /** + * @hooks import_author_xchan + * Called when looking up an author of a post by xchan_hash to ensure they have an xchan record on our site. + * * \e array \b xchan + * * \e string \b xchan_hash - The returned value + */ + call_hooks('import_author_xchan', $arr); + if ($arr['xchan_hash']) { + return $arr['xchan_hash']; + } - $y = false; + $y = false; - if((! array_key_exists('network', $x)) || ($x['network'] === 'zot6')) { - $y = Libzot::import_author_zot($x); - } + if ((! array_key_exists('network', $x)) || ($x['network'] === 'zot6')) { + $y = Libzot::import_author_zot($x); + } - // if we were told that it's a zot connection, don't probe/import anything else - if(array_key_exists('network',$x) && $x['network'] === 'zot6') - return $y; + // if we were told that it's a zot connection, don't probe/import anything else + if (array_key_exists('network', $x) && $x['network'] === 'zot6') { + return $y; + } - if(! $y) { - $y = import_author_activitypub($x); - } + if (! $y) { + $y = import_author_activitypub($x); + } - if(! $y) { - $y = import_author_unknown($x); - } + if (! $y) { + $y = import_author_unknown($x); + } - return($y); + return($y); } -function import_author_activitypub($x) { +function import_author_activitypub($x) +{ - if(! $x['url']) - return false; + if (! $x['url']) { + return false; + } // let somebody upgrade from an 'unknown' connection which has no xchan_addr and resolve issues with identities from multiple protocols using the same url - $r = q("select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'", + $r = q( + "select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'", dbesc($x['url']) ); - if(! $r) { - $r = q("select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan where xchan_hash = '%s' ", + if (! $r) { + $r = q( + "select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan where xchan_hash = '%s' ", dbesc($x['url']) ); } - if($r) { - $ptr = null; - foreach($r as $rv) { - if (strpos($rv['xchan_network'],'zot') !== false) { - $ptr = $rv; - } - } - if(! $ptr) { - $ptr = $r[0]; - } + if ($r) { + $ptr = null; + foreach ($r as $rv) { + if (strpos($rv['xchan_network'], 'zot') !== false) { + $ptr = $rv; + } + } + if (! $ptr) { + $ptr = $r[0]; + } logger('in_cache: ' . $ptr['xchan_name'], LOGGER_DATA); return $ptr['xchan_hash']; @@ -967,21 +993,23 @@ function import_author_activitypub($x) { $z = discover_by_webbie($x['url']); - if($z) { - $r = q("select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'", + if ($z) { + $r = q( + "select xchan_hash, xchan_url, xchan_network, xchan_name, xchan_photo_s from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'", dbesc($x['url']) ); - if(! $r) { - $r = q("select xchan_hash, xchan_url, xchan_name, xchan_photo_s from xchan where xchan_hash = '%s' ", + if (! $r) { + $r = q( + "select xchan_hash, xchan_url, xchan_name, xchan_photo_s from xchan where xchan_hash = '%s' ", dbesc($x['url']) ); } - if($r) { - foreach($r as $rv) { - if (strpos($rv['xchan_network'],'zot') !== false) { - return $rv['xchan_hash']; - } - } + if ($r) { + foreach ($r as $rv) { + if (strpos($rv['xchan_network'], 'zot') !== false) { + return $rv['xchan_hash']; + } + } return $r[0]['xchan_hash']; } } @@ -990,185 +1018,202 @@ function import_author_activitypub($x) { } -function import_author_unknown($x) { +function import_author_unknown($x) +{ - $arr = [ - 'author' => $x, - 'result' => false - ]; - /** - * @hooks import_author - * * \e array \b author - * * \e boolean|string \b result - Return value, default false - */ - call_hooks('import_author', $arr); - if($arr['result']) - return $arr['result']; + $arr = [ + 'author' => $x, + 'result' => false + ]; + /** + * @hooks import_author + * * \e array \b author + * * \e boolean|string \b result - Return value, default false + */ + call_hooks('import_author', $arr); + if ($arr['result']) { + return $arr['result']; + } - if(! $x['url']) - return false; + if (! $x['url']) { + return false; + } - $r = q("select xchan_hash from xchan where xchan_network = 'unknown' and xchan_url = '%s' limit 1", - dbesc($x['url']) - ); - if($r) { - logger('In cache' , LOGGER_DEBUG); - return $r[0]['xchan_hash']; - } + $r = q( + "select xchan_hash from xchan where xchan_network = 'unknown' and xchan_url = '%s' limit 1", + dbesc($x['url']) + ); + if ($r) { + logger('In cache', LOGGER_DEBUG); + return $r[0]['xchan_hash']; + } - $name = trim($x['name']); + $name = trim($x['name']); - $r = xchan_store_lowlevel( - [ - 'xchan_hash' => $x['url'], - 'xchan_guid' => $x['url'], - 'xchan_url' => $x['url'], - 'xchan_updated' => datetime_convert(), - 'xchan_name' => (($name) ? $name : t('(Unknown)')), - 'xchan_name_date' => datetime_convert(), - 'xchan_network' => 'unknown' - ] - ); + $r = xchan_store_lowlevel( + [ + 'xchan_hash' => $x['url'], + 'xchan_guid' => $x['url'], + 'xchan_url' => $x['url'], + 'xchan_updated' => datetime_convert(), + 'xchan_name' => (($name) ? $name : t('(Unknown)')), + 'xchan_name_date' => datetime_convert(), + 'xchan_network' => 'unknown' + ] + ); - if($r && $x['photo']) { + if ($r && $x['photo']) { + $photos = import_remote_xchan_photo($x['photo']['src'], $x['url']); - $photos = import_remote_xchan_photo($x['photo']['src'],$x['url']); + if ($photos) { + $r = q( + "update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' and xchan_network = 'unknown'", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($x['url']) + ); + if ($r) { + return $x['url']; + } + } + } - if($photos) { - $r = q("update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' and xchan_network = 'unknown'", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($x['url']) - ); - if($r) - return $x['url']; - } - } - - return false; + return false; } -function empty_acl($item) { - return (($item['allow_cid'] === EMPTY_STR && $item['allow_gid'] === EMPTY_STR && $item['deny_cid'] === EMPTY_STR && $item['deny_gid'] === EMPTY_STR) ? true : false); +function empty_acl($item) +{ + return (($item['allow_cid'] === EMPTY_STR && $item['allow_gid'] === EMPTY_STR && $item['deny_cid'] === EMPTY_STR && $item['deny_gid'] === EMPTY_STR) ? true : false); } -function encode_item($item,$mirror = false) { - $x = []; - $x['type'] = 'activity'; - $x['encoding'] = 'zot'; +function encode_item($item, $mirror = false) +{ + $x = []; + $x['type'] = 'activity'; + $x['encoding'] = 'zot'; - $r = q("select channel_id from channel where channel_id = %d limit 1", - intval($item['uid']) - ); + $r = q( + "select channel_id from channel where channel_id = %d limit 1", + intval($item['uid']) + ); - if($r) - $comment_scope = PermissionLimits::Get($item['uid'],'post_comments'); - else - $comment_scope = 0; + if ($r) { + $comment_scope = PermissionLimits::Get($item['uid'], 'post_comments'); + } else { + $comment_scope = 0; + } - $c_scope = map_scope($comment_scope); + $c_scope = map_scope($comment_scope); - $key = get_config('system','prvkey'); + $key = get_config('system', 'prvkey'); - // If we're trying to backup an item so that it's recoverable or for export/imprt, - // add all the attributes we need to recover it + // If we're trying to backup an item so that it's recoverable or for export/imprt, + // add all the attributes we need to recover it - if($mirror) { - $x['id'] = $item['id']; - $x['parent'] = $item['parent']; - $x['uid'] = $item['uid']; - $x['allow_cid'] = $item['allow_cid']; - $x['allow_gid'] = $item['allow_gid']; - $x['deny_cid'] = $item['deny_cid']; - $x['deny_gid'] = $item['deny_gid']; - $x['revision'] = $item['revision']; - $x['layout_mid'] = $item['layout_mid']; - $x['postopts'] = $item['postopts']; - $x['resource_id'] = $item['resource_id']; - $x['resource_type'] = $item['resource_type']; - $x['attach'] = $item['attach']; - $x['item_origin'] = $item['item_origin']; - $x['item_unseen'] = $item['item_unseen']; - $x['item_starred'] = $item['item_starred']; - $x['item_uplink'] = $item['item_uplink']; - $x['item_consensus'] = $item['item_consensus']; - $x['item_wall'] = $item['item_wall']; - $x['item_thread_top'] = $item['item_thread_top']; - $x['item_notshown'] = $item['item_notshown']; - $x['item_nsfw'] = $item['item_nsfw']; - $x['item_relay'] = $item['item_relay']; - $x['item_mentionsme'] = $item['item_mentionsme']; - $x['item_nocomment'] = $item['item_nocomment']; - $x['item_obscured'] = $item['item_obscured']; - $x['item_verified'] = $item['item_verified']; - $x['item_retained'] = $item['item_retained']; - $x['item_rss'] = $item['item_rss']; - $x['item_deleted'] = $item['item_deleted']; - $x['item_type'] = $item['item_type']; - $x['item_hidden'] = $item['item_hidden']; - $x['item_unpublished'] = $item['item_unpublished']; - $x['item_delayed'] = $item['item_delayed']; - $x['item_pending_remove'] = $item['item_pending_remove']; - $x['item_blocked'] = $item['item_blocked']; - } + if ($mirror) { + $x['id'] = $item['id']; + $x['parent'] = $item['parent']; + $x['uid'] = $item['uid']; + $x['allow_cid'] = $item['allow_cid']; + $x['allow_gid'] = $item['allow_gid']; + $x['deny_cid'] = $item['deny_cid']; + $x['deny_gid'] = $item['deny_gid']; + $x['revision'] = $item['revision']; + $x['layout_mid'] = $item['layout_mid']; + $x['postopts'] = $item['postopts']; + $x['resource_id'] = $item['resource_id']; + $x['resource_type'] = $item['resource_type']; + $x['attach'] = $item['attach']; + $x['item_origin'] = $item['item_origin']; + $x['item_unseen'] = $item['item_unseen']; + $x['item_starred'] = $item['item_starred']; + $x['item_uplink'] = $item['item_uplink']; + $x['item_consensus'] = $item['item_consensus']; + $x['item_wall'] = $item['item_wall']; + $x['item_thread_top'] = $item['item_thread_top']; + $x['item_notshown'] = $item['item_notshown']; + $x['item_nsfw'] = $item['item_nsfw']; + $x['item_relay'] = $item['item_relay']; + $x['item_mentionsme'] = $item['item_mentionsme']; + $x['item_nocomment'] = $item['item_nocomment']; + $x['item_obscured'] = $item['item_obscured']; + $x['item_verified'] = $item['item_verified']; + $x['item_retained'] = $item['item_retained']; + $x['item_rss'] = $item['item_rss']; + $x['item_deleted'] = $item['item_deleted']; + $x['item_type'] = $item['item_type']; + $x['item_hidden'] = $item['item_hidden']; + $x['item_unpublished'] = $item['item_unpublished']; + $x['item_delayed'] = $item['item_delayed']; + $x['item_pending_remove'] = $item['item_pending_remove']; + $x['item_blocked'] = $item['item_blocked']; + } - $x['uuid'] = $item['uuid']; - $x['message_id'] = $item['mid']; - $x['message_top'] = $item['parent_mid']; - $x['message_parent'] = $item['thr_parent']; - $x['created'] = $item['created']; - $x['edited'] = $item['edited']; - // always send 0's over the wire - $x['expires'] = (($item['expires'] == '0001-01-01 00:00:00') ? '0000-00-00 00:00:00' : $item['expires']); - $x['commented'] = $item['commented']; - $x['mimetype'] = $item['mimetype']; - $x['title'] = $item['title']; - $x['summary'] = $item['summary']; - $x['body'] = $item['body']; - $x['app'] = $item['app']; - $x['verb'] = $item['verb']; - $x['object_type'] = $item['obj_type']; - $x['target_type'] = $item['tgt_type']; - $x['permalink'] = $item['plink']; - $x['location'] = $item['location']; - $x['longlat'] = $item['coord']; - $x['signature'] = $item['sig']; - $x['route'] = $item['route']; - $x['replyto'] = $item['replyto']; - $x['owner'] = encode_item_xchan($item['owner']); - $x['author'] = encode_item_xchan($item['author']); + $x['uuid'] = $item['uuid']; + $x['message_id'] = $item['mid']; + $x['message_top'] = $item['parent_mid']; + $x['message_parent'] = $item['thr_parent']; + $x['created'] = $item['created']; + $x['edited'] = $item['edited']; + // always send 0's over the wire + $x['expires'] = (($item['expires'] == '0001-01-01 00:00:00') ? '0000-00-00 00:00:00' : $item['expires']); + $x['commented'] = $item['commented']; + $x['mimetype'] = $item['mimetype']; + $x['title'] = $item['title']; + $x['summary'] = $item['summary']; + $x['body'] = $item['body']; + $x['app'] = $item['app']; + $x['verb'] = $item['verb']; + $x['object_type'] = $item['obj_type']; + $x['target_type'] = $item['tgt_type']; + $x['permalink'] = $item['plink']; + $x['location'] = $item['location']; + $x['longlat'] = $item['coord']; + $x['signature'] = $item['sig']; + $x['route'] = $item['route']; + $x['replyto'] = $item['replyto']; + $x['owner'] = encode_item_xchan($item['owner']); + $x['author'] = encode_item_xchan($item['author']); - if($item['obj']) - $x['object'] = json_decode($item['obj'],true); - if($item['target']) - $x['target'] = json_decode($item['target'],true); - if($item['attach']) - $x['attach'] = json_decode($item['attach'],true); - if($y = encode_item_flags($item)) - $x['flags'] = $y; + if ($item['obj']) { + $x['object'] = json_decode($item['obj'], true); + } + if ($item['target']) { + $x['target'] = json_decode($item['target'], true); + } + if ($item['attach']) { + $x['attach'] = json_decode($item['attach'], true); + } + if ($y = encode_item_flags($item)) { + $x['flags'] = $y; + } - if($item['comments_closed'] > NULL_DATE) - $x['comments_closed'] = $item['comments_closed']; + if ($item['comments_closed'] > NULL_DATE) { + $x['comments_closed'] = $item['comments_closed']; + } - if($item['item_nocomment']) - $x['comment_scope'] = 'none'; - else - $x['comment_scope'] = $c_scope; + if ($item['item_nocomment']) { + $x['comment_scope'] = 'none'; + } else { + $x['comment_scope'] = $c_scope; + } - if($item['term']) - $x['tags'] = encode_item_terms($item['term'],$mirror); + if ($item['term']) { + $x['tags'] = encode_item_terms($item['term'], $mirror); + } - if($item['iconfig']) - $x['meta'] = encode_item_meta($item['iconfig'],$mirror); + if ($item['iconfig']) { + $x['meta'] = encode_item_meta($item['iconfig'], $mirror); + } - logger('encode_item: ' . print_r($x,true), LOGGER_DATA); + logger('encode_item: ' . print_r($x, true), LOGGER_DATA); - return $x; + return $x; } /** @@ -1178,29 +1223,31 @@ function encode_item($item,$mirror = false) { * @param bool $strip (optional) default false * @return string */ -function map_scope($scope, $strip = false) { - switch($scope) { - case 0: - return 'self'; - case PERMS_PUBLIC: - if($strip) - return ''; - return 'public'; - case PERMS_NETWORK: - return 'network: red'; - case PERMS_AUTHED: - return 'authenticated'; - case PERMS_SITE: - return 'site: ' . App::get_hostname(); - case PERMS_PENDING: - return 'any connections'; -// uncomment a few releases after the corresponding changes are made in can_comment_on_post. Here it was done on 2021-11-18 -// case PERMS_SPECIFIC: -// return 'specific'; - case PERMS_CONTACTS: - default: - return 'contacts'; - } +function map_scope($scope, $strip = false) +{ + switch ($scope) { + case 0: + return 'self'; + case PERMS_PUBLIC: + if ($strip) { + return ''; + } + return 'public'; + case PERMS_NETWORK: + return 'network: red'; + case PERMS_AUTHED: + return 'authenticated'; + case PERMS_SITE: + return 'site: ' . App::get_hostname(); + case PERMS_PENDING: + return 'any connections'; +// uncomment a few releases after the corresponding changes are made in can_comment_on_post. Here it was done on 2021-11-18 +// case PERMS_SPECIFIC: +// return 'specific'; + case PERMS_CONTACTS: + default: + return 'contacts'; + } } /** @@ -1209,23 +1256,32 @@ function map_scope($scope, $strip = false) { * @param string $scope * @return string translated string describing the scope */ -function translate_scope($scope) { - if(! $scope || $scope === 'public') - return t('Visible to anybody on the internet.'); - if(strpos($scope,'self') === 0) - return t('Visible to you only.'); - if(strpos($scope,'network:') === 0) - return t('Visible to anybody in this network.'); - if(strpos($scope,'authenticated') === 0) - return t('Visible to anybody authenticated.'); - if(strpos($scope,'site:') === 0) - return sprintf( t('Visible to anybody on %s.'), strip_tags(substr($scope,6))); - if(strpos($scope,'any connections') === 0) - return t('Visible to all connections.'); - if(strpos($scope,'contacts') === 0) - return t('Visible to approved connections.'); - if(strpos($scope,'specific') === 0) - return t('Visible to specific connections.'); +function translate_scope($scope) +{ + if (! $scope || $scope === 'public') { + return t('Visible to anybody on the internet.'); + } + if (strpos($scope, 'self') === 0) { + return t('Visible to you only.'); + } + if (strpos($scope, 'network:') === 0) { + return t('Visible to anybody in this network.'); + } + if (strpos($scope, 'authenticated') === 0) { + return t('Visible to anybody authenticated.'); + } + if (strpos($scope, 'site:') === 0) { + return sprintf(t('Visible to anybody on %s.'), strip_tags(substr($scope, 6))); + } + if (strpos($scope, 'any connections') === 0) { + return t('Visible to all connections.'); + } + if (strpos($scope, 'contacts') === 0) { + return t('Visible to approved connections.'); + } + if (strpos($scope, 'specific') === 0) { + return t('Visible to specific connections.'); + } } /** @@ -1234,63 +1290,69 @@ function translate_scope($scope) { * @param array $xchan * @return array an associative array */ -function encode_item_xchan($xchan) { - $ret = []; +function encode_item_xchan($xchan) +{ + $ret = []; - $ret['name'] = $xchan['xchan_name']; - $ret['address'] = $xchan['xchan_addr']; - $ret['url'] = $xchan['xchan_url']; - $ret['network'] = $xchan['xchan_network']; - $ret['photo'] = [ 'mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m'] ]; - $ret['id'] = $xchan['xchan_guid']; - $ret['id_sig'] = $xchan['xchan_guid_sig']; - $ret['key'] = $xchan['xchan_pubkey']; + $ret['name'] = $xchan['xchan_name']; + $ret['address'] = $xchan['xchan_addr']; + $ret['url'] = $xchan['xchan_url']; + $ret['network'] = $xchan['xchan_network']; + $ret['photo'] = [ 'mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m'] ]; + $ret['id'] = $xchan['xchan_guid']; + $ret['id_sig'] = $xchan['xchan_guid_sig']; + $ret['key'] = $xchan['xchan_pubkey']; - return $ret; + return $ret; } -function encode_item_terms($terms,$mirror = false) { - $ret = []; +function encode_item_terms($terms, $mirror = false) +{ + $ret = []; - $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK, TERM_COMMUNITYTAG, TERM_FORUM ); + $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK, TERM_COMMUNITYTAG, TERM_FORUM ); - if($mirror) { - $allowed_export_terms[] = TERM_PCATEGORY; - $allowed_export_terms[] = TERM_FILE; - } + if ($mirror) { + $allowed_export_terms[] = TERM_PCATEGORY; + $allowed_export_terms[] = TERM_FILE; + } - if($terms) { - foreach($terms as $term) { - if(in_array($term['ttype'],$allowed_export_terms)) - $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['ttype'])); - } - } + if ($terms) { + foreach ($terms as $term) { + if (in_array($term['ttype'], $allowed_export_terms)) { + $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['ttype'])); + } + } + } - return $ret; + return $ret; } -function encode_item_meta($meta,$mirror = false) { - $ret = []; +function encode_item_meta($meta, $mirror = false) +{ + $ret = []; - if($meta) { - foreach($meta as $m) { - if($m['sharing'] || $mirror) - $ret[] = array('family' => $m['cat'], 'key' => $m['k'], 'value' => $m['v'], 'sharing' => intval($m['sharing'])); - } - } + if ($meta) { + foreach ($meta as $m) { + if ($m['sharing'] || $mirror) { + $ret[] = array('family' => $m['cat'], 'key' => $m['k'], 'value' => $m['v'], 'sharing' => intval($m['sharing'])); + } + } + } - return $ret; + return $ret; } -function decode_item_meta($meta) { - $ret = []; +function decode_item_meta($meta) +{ + $ret = []; - if(is_array($meta) && $meta) { - foreach($meta as $m) { - $ret[] = array('cat' => escape_tags($m['family']),'k' => escape_tags($m['key']),'v' => $m['value'],'sharing' => $m['sharing']); - } - } - return $ret; + if (is_array($meta) && $meta) { + foreach ($meta as $m) { + $ret[] = array('cat' => escape_tags($m['family']),'k' => escape_tags($m['key']),'v' => $m['value'],'sharing' => $m['sharing']); + } + } + return $ret; } /** @@ -1299,10 +1361,11 @@ function decode_item_meta($meta) { * @param int $t * @return string */ -function termtype($t) { - $types = array('unknown','hashtag','mention','category','personal_category','file','search','thing','bookmark', 'hierarchy', 'communitytag', 'forum'); +function termtype($t) +{ + $types = array('unknown','hashtag','mention','category','personal_category','file','search','thing','bookmark', 'hierarchy', 'communitytag', 'forum'); - return(($types[$t]) ? $types[$t] : 'unknown'); + return(($types[$t]) ? $types[$t] : 'unknown'); } /** @@ -1314,76 +1377,76 @@ function termtype($t) { * * \e string \b url * * \e int \b type */ -function decode_tags($t) { - if($t) { - $ret = []; - foreach($t as $x) { - $tag = []; - $tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT, 'UTF-8', false); - $tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT, 'UTF-8', false); - switch($x['type']) { - case 'hashtag': - $tag['ttype'] = TERM_HASHTAG; - break; - case 'mention': - $tag['ttype'] = TERM_MENTION; - break; - case 'category': - $tag['ttype'] = TERM_CATEGORY; - break; - case 'personal_category': - $tag['ttype'] = TERM_PCATEGORY; - break; - case 'file': - $tag['ttype'] = TERM_FILE; - break; - case 'search': - $tag['ttype'] = TERM_SEARCH; - break; - case 'thing': - $tag['ttype'] = TERM_THING; - break; - case 'bookmark': - $tag['ttype'] = TERM_BOOKMARK; - break; - case 'communitytag': - $tag['ttype'] = TERM_COMMUNITYTAG; - break; - case 'forum': - $tag['ttype'] = TERM_FORUM; - break; - default: - case 'unknown': - $tag['ttype'] = TERM_UNKNOWN; - break; - } - $ret[] = $tag; - } +function decode_tags($t) +{ + if ($t) { + $ret = []; + foreach ($t as $x) { + $tag = []; + $tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT, 'UTF-8', false); + $tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT, 'UTF-8', false); + switch ($x['type']) { + case 'hashtag': + $tag['ttype'] = TERM_HASHTAG; + break; + case 'mention': + $tag['ttype'] = TERM_MENTION; + break; + case 'category': + $tag['ttype'] = TERM_CATEGORY; + break; + case 'personal_category': + $tag['ttype'] = TERM_PCATEGORY; + break; + case 'file': + $tag['ttype'] = TERM_FILE; + break; + case 'search': + $tag['ttype'] = TERM_SEARCH; + break; + case 'thing': + $tag['ttype'] = TERM_THING; + break; + case 'bookmark': + $tag['ttype'] = TERM_BOOKMARK; + break; + case 'communitytag': + $tag['ttype'] = TERM_COMMUNITYTAG; + break; + case 'forum': + $tag['ttype'] = TERM_FORUM; + break; + default: + case 'unknown': + $tag['ttype'] = TERM_UNKNOWN; + break; + } + $ret[] = $tag; + } - return $ret; - } + return $ret; + } - return ''; + return ''; } -function purify_imported_object($obj) { - $ret = null; - if (is_array($obj)) { - foreach ( $obj as $k => $v ) { - if (is_array($v)) { - $ret[$k] = purify_imported_object($v); - } - elseif (is_string($v)) { - $ret[$k] = purify_html($v); - } - } - } - elseif (is_string($obj)) { - $ret = purify_html($obj); - } +function purify_imported_object($obj) +{ + $ret = null; + if (is_array($obj)) { + foreach ($obj as $k => $v) { + if (is_array($v)) { + $ret[$k] = purify_imported_object($v); + } elseif (is_string($v)) { + $ret[$k] = purify_html($v); + } + } + } elseif (is_string($obj)) { + $ret = purify_html($obj); + } - return $ret; + return $ret; } @@ -1396,42 +1459,43 @@ function purify_imported_object($obj) { * @param array $arr * @return array|string */ - -function activity_sanitise($arr) { - if($arr) { - if(is_array($arr)) { - $ret = []; - foreach($arr as $k => $x) { - if ($k === 'source' && array_path_exists('source/mediaType',$arr)) { - if (array_path_exists('source/content',$arr) && isset($arr['source']['mediaType']) && in_array($arr['source']['mediaType'], [ 'text/bbcode', 'text/x-multicode' ])) { - // @FIXME multicode - $ret[$k] = [ 'mediaType' => 'text/bbcode' ]; - if (is_string($arr['source']['content'])) { - $ret[$k]['content'] = multicode_purify($arr['source']['content']); - } - if (array_path_exists('source/summary',$arr) && is_string($arr['source']['summary'])) { - $ret[$k]['summary'] = multicode_purify($arr['source']['summary']); - } - continue; - } - } - if (in_array($k, [ 'content', 'summary', 'contentMap', 'summaryMap' ])) { - $ret[$k] = purify_imported_object($arr[$k]); - continue; - } - if(is_array($x)) - $ret[$k] = activity_sanitise($x); - else - $ret[$k] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false); - } - return $ret; - } - else { - return htmlspecialchars($arr, ENT_COMPAT, 'UTF-8', false); - } - } - return ''; +function activity_sanitise($arr) +{ + if ($arr) { + if (is_array($arr)) { + $ret = []; + foreach ($arr as $k => $x) { + if ($k === 'source' && array_path_exists('source/mediaType', $arr)) { + if (array_path_exists('source/content', $arr) && isset($arr['source']['mediaType']) && in_array($arr['source']['mediaType'], [ 'text/bbcode', 'text/x-multicode' ])) { + // @FIXME multicode + $ret[$k] = [ 'mediaType' => 'text/bbcode' ]; + if (is_string($arr['source']['content'])) { + $ret[$k]['content'] = multicode_purify($arr['source']['content']); + } + if (array_path_exists('source/summary', $arr) && is_string($arr['source']['summary'])) { + $ret[$k]['summary'] = multicode_purify($arr['source']['summary']); + } + continue; + } + } + if (in_array($k, [ 'content', 'summary', 'contentMap', 'summaryMap' ])) { + $ret[$k] = purify_imported_object($arr[$k]); + continue; + } + if (is_array($x)) { + $ret[$k] = activity_sanitise($x); + } else { + $ret[$k] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false); + } + } + return $ret; + } else { + return htmlspecialchars($arr, ENT_COMPAT, 'UTF-8', false); + } + } + + return ''; } /** @@ -1440,73 +1504,86 @@ function activity_sanitise($arr) { * @param array $arr * @return array|string */ -function array_sanitise($arr) { - if($arr) { - $ret = []; - foreach($arr as $x) { - $ret[] = htmlspecialchars($x, ENT_COMPAT,'UTF-8',false); - } - return $ret; - } +function array_sanitise($arr) +{ + if ($arr) { + $ret = []; + foreach ($arr as $x) { + $ret[] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false); + } + return $ret; + } - return ''; + return ''; } -function encode_item_flags($item) { +function encode_item_flags($item) +{ -// most of item_flags and item_restrict are local settings which don't apply when transmitted. +// most of item_flags and item_restrict are local settings which don't apply when transmitted. // We may need those for the case of syncing other hub locations which you are attached to. - $ret = []; + $ret = []; - if(intval($item['item_deleted'])) - $ret[] = 'deleted'; - if(intval($item['item_hidden'])) - $ret[] = 'hidden'; - if(intval($item['item_notshown'])) - $ret[] = 'notshown'; - if(intval($item['item_thread_top'])) - $ret[] = 'thread_parent'; - if(intval($item['item_nsfw'])) - $ret[] = 'nsfw'; - if(intval($item['item_consensus'])) - $ret[] = 'consensus'; - if(intval($item['item_obscured'])) - $ret[] = 'obscured'; - if(intval($item['item_private'])) - $ret[] = 'private'; - if(intval($item['item_private']) === 2) + if (intval($item['item_deleted'])) { + $ret[] = 'deleted'; + } + if (intval($item['item_hidden'])) { + $ret[] = 'hidden'; + } + if (intval($item['item_notshown'])) { + $ret[] = 'notshown'; + } + if (intval($item['item_thread_top'])) { + $ret[] = 'thread_parent'; + } + if (intval($item['item_nsfw'])) { + $ret[] = 'nsfw'; + } + if (intval($item['item_consensus'])) { + $ret[] = 'consensus'; + } + if (intval($item['item_obscured'])) { + $ret[] = 'obscured'; + } + if (intval($item['item_private'])) { + $ret[] = 'private'; + } + if (intval($item['item_private']) === 2) { $ret[] = 'direct'; + } - return $ret; + return $ret; } -function get_profile_elements($x) { +function get_profile_elements($x) +{ - $arr = []; + $arr = []; - if(($xchan_hash = import_author_xchan($x['from'])) !== false) - $arr['xprof_hash'] = $xchan_hash; - else - return []; + if (($xchan_hash = import_author_xchan($x['from'])) !== false) { + $arr['xprof_hash'] = $xchan_hash; + } else { + return []; + } - $arr['desc'] = (($x['title']) ? htmlspecialchars($x['title'],ENT_COMPAT,'UTF-8',false) : ''); + $arr['desc'] = (($x['title']) ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8', false) : ''); - $arr['dob'] = datetime_convert('UTC','UTC',$x['birthday'],'Y-m-d'); - $arr['age'] = (($x['age']) ? intval($x['age']) : 0); + $arr['dob'] = datetime_convert('UTC', 'UTC', $x['birthday'], 'Y-m-d'); + $arr['age'] = (($x['age']) ? intval($x['age']) : 0); - $arr['gender'] = (($x['gender']) ? htmlspecialchars($x['gender'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['marital'] = (($x['marital']) ? htmlspecialchars($x['marital'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['sexual'] = (($x['sexual']) ? htmlspecialchars($x['sexual'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['locale'] = (($x['locale']) ? htmlspecialchars($x['locale'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['region'] = (($x['region']) ? htmlspecialchars($x['region'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['postcode'] = (($x['postcode']) ? htmlspecialchars($x['postcode'], ENT_COMPAT,'UTF-8',false) : ''); - $arr['country'] = (($x['country']) ? htmlspecialchars($x['country'], ENT_COMPAT,'UTF-8',false) : ''); + $arr['gender'] = (($x['gender']) ? htmlspecialchars($x['gender'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['marital'] = (($x['marital']) ? htmlspecialchars($x['marital'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['sexual'] = (($x['sexual']) ? htmlspecialchars($x['sexual'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['locale'] = (($x['locale']) ? htmlspecialchars($x['locale'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['region'] = (($x['region']) ? htmlspecialchars($x['region'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['postcode'] = (($x['postcode']) ? htmlspecialchars($x['postcode'], ENT_COMPAT, 'UTF-8', false) : ''); + $arr['country'] = (($x['country']) ? htmlspecialchars($x['country'], ENT_COMPAT, 'UTF-8', false) : ''); - $arr['keywords'] = (($x['keywords'] && is_array($x['keywords'])) ? array_sanitise($x['keywords']) : []); + $arr['keywords'] = (($x['keywords'] && is_array($x['keywords'])) ? array_sanitise($x['keywords']) : []); - return $arr; + return $arr; } @@ -1515,20 +1592,24 @@ function get_profile_elements($x) { * * @param[in,out] array $item */ -function item_sign(&$item) { +function item_sign(&$item) +{ - if(array_key_exists('sig',$item) && $item['sig']) - return; + if (array_key_exists('sig', $item) && $item['sig']) { + return; + } - $r = q("select channel_prvkey from channel where channel_id = %d and channel_hash = '%s' ", - intval($item['uid']), - dbesc($item['author_xchan']) - ); - if(! $r) - return; + $r = q( + "select channel_prvkey from channel where channel_id = %d and channel_hash = '%s' ", + intval($item['uid']), + dbesc($item['author_xchan']) + ); + if (! $r) { + return; + } - $item['sig'] = Libzot::sign($item['body'], $r[0]['channel_prvkey']); - $item['item_verified'] = 1; + $item['sig'] = Libzot::sign($item['body'], $r[0]['channel_prvkey']); + $item['item_verified'] = 1; } // packs json data for storage. @@ -1537,26 +1618,26 @@ function item_sign(&$item) { // If it is an array, sanitise it and then json_encode it. -function item_json_encapsulate($arr,$k) { - $retval = null; - - if (isset($arr[$k])) { - if (is_string($arr[$k])) { - // determine if it is json encoded already - $test = json_decode($arr[$k]); - // assume it is json encoded already - $retval = $arr[$k]; - if ($test === NULL) { - $retval = json_encode($arr[$k], JSON_UNESCAPED_SLASHES); - } - } - else { - activity_sanitise($arr[$k]); - $retval = json_encode($arr[$k], JSON_UNESCAPED_SLASHES); - } - } +function item_json_encapsulate($arr, $k) +{ + $retval = null; - return $retval; + if (isset($arr[$k])) { + if (is_string($arr[$k])) { + // determine if it is json encoded already + $test = json_decode($arr[$k]); + // assume it is json encoded already + $retval = $arr[$k]; + if ($test === null) { + $retval = json_encode($arr[$k], JSON_UNESCAPED_SLASHES); + } + } else { + activity_sanitise($arr[$k]); + $retval = json_encode($arr[$k], JSON_UNESCAPED_SLASHES); + } + } + + return $retval; } /** @@ -1570,510 +1651,526 @@ function item_json_encapsulate($arr,$k) { * * \e boolean \b success * * \e int \b item_id */ -function item_store($arr, $allow_exec = false, $deliver = true, $linkid = true) { +function item_store($arr, $allow_exec = false, $deliver = true, $linkid = true) +{ - $d = [ - 'item' => $arr, - 'allow_exec' => $allow_exec - ]; - /** - * @hooks item_store_before - * Called when item_store() stores a record of type item. - * * \e array \b item - * * \e boolean \b allow_exec - */ - call_hooks('item_store_before', $d); - $arr = $d['item']; - $allow_exec = $d['allow_exec']; + $d = [ + 'item' => $arr, + 'allow_exec' => $allow_exec + ]; + /** + * @hooks item_store_before + * Called when item_store() stores a record of type item. + * * \e array \b item + * * \e boolean \b allow_exec + */ + call_hooks('item_store_before', $d); + $arr = $d['item']; + $allow_exec = $d['allow_exec']; - $ret = array('success' => false, 'item_id' => 0); + $ret = array('success' => false, 'item_id' => 0); - if(array_key_exists('cancel',$arr) && $arr['cancel']) { - logger('cancelled by plugin'); - return $ret; - } + if (array_key_exists('cancel', $arr) && $arr['cancel']) { + logger('cancelled by plugin'); + return $ret; + } - if(! $arr['uid']) { - logger('item_store: no uid'); - $ret['message'] = 'No uid.'; - return $ret; - } + if (! $arr['uid']) { + logger('item_store: no uid'); + $ret['message'] = 'No uid.'; + return $ret; + } - //$uplinked_comment = false; + //$uplinked_comment = false; - // If a page layout is provided, ensure it exists and belongs to us. + // If a page layout is provided, ensure it exists and belongs to us. - if(array_key_exists('layout_mid',$arr) && $arr['layout_mid']) { - $l = q("select item_type from item where mid = '%s' and uid = %d limit 1", - dbesc($arr['layout_mid']), - intval($arr['uid']) - ); - if((! $l) || ($l[0]['item_type'] != ITEM_TYPE_PDL)) - unset($arr['layout_mid']); - } + if (array_key_exists('layout_mid', $arr) && $arr['layout_mid']) { + $l = q( + "select item_type from item where mid = '%s' and uid = %d limit 1", + dbesc($arr['layout_mid']), + intval($arr['uid']) + ); + if ((! $l) || ($l[0]['item_type'] != ITEM_TYPE_PDL)) { + unset($arr['layout_mid']); + } + } - // Don't let anybody set these, either intentionally or accidentally + // Don't let anybody set these, either intentionally or accidentally - if(array_key_exists('id',$arr)) - unset($arr['id']); - if(array_key_exists('parent',$arr)) - unset($arr['parent']); + if (array_key_exists('id', $arr)) { + unset($arr['id']); + } + if (array_key_exists('parent', $arr)) { + unset($arr['parent']); + } - $arr['mimetype'] = ((x($arr,'mimetype')) ? notags(trim($arr['mimetype'])) : 'text/bbcode'); + $arr['mimetype'] = ((x($arr, 'mimetype')) ? notags(trim($arr['mimetype'])) : 'text/bbcode'); - if(($arr['mimetype'] == 'application/x-php') && (! $allow_exec)) { - logger('item_store: php mimetype but allow_exec is denied.'); - $ret['message'] = 'exec denied.'; - return $ret; - } + if (($arr['mimetype'] == 'application/x-php') && (! $allow_exec)) { + logger('item_store: php mimetype but allow_exec is denied.'); + $ret['message'] = 'exec denied.'; + return $ret; + } - $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim(escape_tags($arr['title'])) : ''); - $arr['summary'] = ((array_key_exists('summary',$arr) && strlen($arr['summary'])) ? trim($arr['summary']) : ''); - $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); + $arr['title'] = ((array_key_exists('title', $arr) && strlen($arr['title'])) ? trim(escape_tags($arr['title'])) : ''); + $arr['summary'] = ((array_key_exists('summary', $arr) && strlen($arr['summary'])) ? trim($arr['summary']) : ''); + $arr['body'] = ((array_key_exists('body', $arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); - $arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : ''); - $arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : ''); - $arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : ''); - $arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : ''); - $arr['postopts'] = ((x($arr,'postopts')) ? trim($arr['postopts']) : ''); - $arr['route'] = ((x($arr,'route')) ? trim($arr['route']) : ''); - $arr['uuid'] = ((x($arr,'uuid')) ? trim($arr['uuid']) : ''); - $arr['item_private'] = ((x($arr,'item_private')) ? intval($arr['item_private']) : 0 ); - $arr['item_wall'] = ((x($arr,'item_wall')) ? intval($arr['item_wall']) : 0 ); - $arr['item_type'] = ((x($arr,'item_type')) ? intval($arr['item_type']) : 0 ); - $arr['item_verified'] = ((x($arr,'item_verified')) ? intval($arr['item_verified']) : 0 ); + $arr['allow_cid'] = ((x($arr, 'allow_cid')) ? trim($arr['allow_cid']) : ''); + $arr['allow_gid'] = ((x($arr, 'allow_gid')) ? trim($arr['allow_gid']) : ''); + $arr['deny_cid'] = ((x($arr, 'deny_cid')) ? trim($arr['deny_cid']) : ''); + $arr['deny_gid'] = ((x($arr, 'deny_gid')) ? trim($arr['deny_gid']) : ''); + $arr['postopts'] = ((x($arr, 'postopts')) ? trim($arr['postopts']) : ''); + $arr['route'] = ((x($arr, 'route')) ? trim($arr['route']) : ''); + $arr['uuid'] = ((x($arr, 'uuid')) ? trim($arr['uuid']) : ''); + $arr['item_private'] = ((x($arr, 'item_private')) ? intval($arr['item_private']) : 0 ); + $arr['item_wall'] = ((x($arr, 'item_wall')) ? intval($arr['item_wall']) : 0 ); + $arr['item_type'] = ((x($arr, 'item_type')) ? intval($arr['item_type']) : 0 ); + $arr['item_verified'] = ((x($arr, 'item_verified')) ? intval($arr['item_verified']) : 0 ); - // obsolete, but needed so as not to throw not-null constraints on some database driveres - $arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 ); + // obsolete, but needed so as not to throw not-null constraints on some database driveres + $arr['item_flags'] = ((x($arr, 'item_flags')) ? intval($arr['item_flags']) : 0 ); - $arr['lang'] = detect_language($arr['body']); + $arr['lang'] = detect_language($arr['body']); - // apply the input filter here + // apply the input filter here - $arr['summary'] = trim(z_input_filter($arr['summary'],$arr['mimetype'],$allow_exec)); - $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec)); + $arr['summary'] = trim(z_input_filter($arr['summary'], $arr['mimetype'], $allow_exec)); + $arr['body'] = trim(z_input_filter($arr['body'], $arr['mimetype'], $allow_exec)); - item_sign($arr); + item_sign($arr); - if(! array_key_exists('sig',$arr)) - $arr['sig'] = ''; + if (! array_key_exists('sig', $arr)) { + $arr['sig'] = ''; + } - $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); + $allowed_languages = get_pconfig($arr['uid'], 'system', 'allowed_languages'); - if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { - $translate = [ - 'item' => $arr, - 'from' => $arr['lang'], - 'to' => $allowed_languages, - 'translated' => false - ]; - /** - * @hooks item_translate - * Called from item_store and item_store_update after the post language has been autodetected. - * * \e array \b item - * * \e string \b from - * * \e string \b to - * * \e boolean \b translated - */ - call_hooks('item_translate', $translate); - if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { - logger('language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); - $ret['message'] = 'language not accepted'; - return $ret; - } - $arr = $translate['item']; - } + if ((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'], $allowed_languages))) { + $translate = [ + 'item' => $arr, + 'from' => $arr['lang'], + 'to' => $allowed_languages, + 'translated' => false + ]; + /** + * @hooks item_translate + * Called from item_store and item_store_update after the post language has been autodetected. + * * \e array \b item + * * \e string \b from + * * \e string \b to + * * \e boolean \b translated + */ + call_hooks('item_translate', $translate); + if ((! $translate['translated']) && (intval(get_pconfig($arr['uid'], 'system', 'reject_disallowed_languages')))) { + logger('language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); + $ret['message'] = 'language not accepted'; + return $ret; + } + $arr = $translate['item']; + } - if(x($arr,'obj')) { - $arr['obj'] = item_json_encapsulate($arr,'obj'); - } + if (x($arr, 'obj')) { + $arr['obj'] = item_json_encapsulate($arr, 'obj'); + } - if(x($arr,'target')) { - $arr['target'] = item_json_encapsulate($arr,'target'); - } + if (x($arr, 'target')) { + $arr['target'] = item_json_encapsulate($arr, 'target'); + } - if(x($arr,'attach')) { - $arr['attach'] = item_json_encapsulate($arr,'attach'); - } + if (x($arr, 'attach')) { + $arr['attach'] = item_json_encapsulate($arr, 'attach'); + } - $arr['aid'] = ((x($arr,'aid')) ? intval($arr['aid']) : 0); - $arr['mid'] = ((x($arr,'mid')) ? notags(trim($arr['mid'])) : random_string()); - $arr['revision'] = ((x($arr,'revision') && intval($arr['revision']) > 0) ? intval($arr['revision']) : 0); + $arr['aid'] = ((x($arr, 'aid')) ? intval($arr['aid']) : 0); + $arr['mid'] = ((x($arr, 'mid')) ? notags(trim($arr['mid'])) : random_string()); + $arr['revision'] = ((x($arr, 'revision') && intval($arr['revision']) > 0) ? intval($arr['revision']) : 0); - $arr['author_xchan'] = ((x($arr,'author_xchan')) ? notags(trim($arr['author_xchan'])) : ''); - $arr['owner_xchan'] = ((x($arr,'owner_xchan')) ? notags(trim($arr['owner_xchan'])) : ''); - $arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert()); - $arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert()); - $arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : NULL_DATE); - $arr['commented'] = ((x($arr,'commented') !== false) ? datetime_convert('UTC','UTC',$arr['commented']) : datetime_convert()); - $arr['comments_closed'] = ((x($arr,'comments_closed') !== false) ? datetime_convert('UTC','UTC',$arr['comments_closed']) : NULL_DATE); - $arr['html'] = ((array_key_exists('html',$arr)) ? $arr['html'] : ''); + $arr['author_xchan'] = ((x($arr, 'author_xchan')) ? notags(trim($arr['author_xchan'])) : ''); + $arr['owner_xchan'] = ((x($arr, 'owner_xchan')) ? notags(trim($arr['owner_xchan'])) : ''); + $arr['created'] = ((x($arr, 'created') !== false) ? datetime_convert('UTC', 'UTC', $arr['created']) : datetime_convert()); + $arr['edited'] = ((x($arr, 'edited') !== false) ? datetime_convert('UTC', 'UTC', $arr['edited']) : datetime_convert()); + $arr['expires'] = ((x($arr, 'expires') !== false) ? datetime_convert('UTC', 'UTC', $arr['expires']) : NULL_DATE); + $arr['commented'] = ((x($arr, 'commented') !== false) ? datetime_convert('UTC', 'UTC', $arr['commented']) : datetime_convert()); + $arr['comments_closed'] = ((x($arr, 'comments_closed') !== false) ? datetime_convert('UTC', 'UTC', $arr['comments_closed']) : NULL_DATE); + $arr['html'] = ((array_key_exists('html', $arr)) ? $arr['html'] : ''); - if($deliver) { - $arr['received'] = datetime_convert(); - $arr['changed'] = datetime_convert(); - } - else { + if ($deliver) { + $arr['received'] = datetime_convert(); + $arr['changed'] = datetime_convert(); + } else { + // When deliver flag is false, we are *probably* performing an import or bulk migration. + // If one updates the changed timestamp it will be made available to zotfeed and delivery + // will still take place through backdoor methods. Since these fields are rarely used + // otherwise, just preserve the original timestamp. - // When deliver flag is false, we are *probably* performing an import or bulk migration. - // If one updates the changed timestamp it will be made available to zotfeed and delivery - // will still take place through backdoor methods. Since these fields are rarely used - // otherwise, just preserve the original timestamp. + $arr['received'] = ((x($arr, 'received') !== false) ? datetime_convert('UTC', 'UTC', $arr['received']) : datetime_convert()); + $arr['changed'] = ((x($arr, 'changed') !== false) ? datetime_convert('UTC', 'UTC', $arr['changed']) : datetime_convert()); + } - $arr['received'] = ((x($arr,'received') !== false) ? datetime_convert('UTC','UTC',$arr['received']) : datetime_convert()); - $arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert()); - } + $arr['location'] = ((x($arr, 'location')) ? notags(trim($arr['location'])) : ''); + $arr['coord'] = ((x($arr, 'coord')) ? notags(trim($arr['coord'])) : ''); + $arr['parent_mid'] = ((x($arr, 'parent_mid')) ? notags(trim($arr['parent_mid'])) : ''); + $arr['thr_parent'] = ((x($arr, 'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']); + $arr['verb'] = ((x($arr, 'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST); + $arr['obj_type'] = ((x($arr, 'obj_type')) ? notags(trim($arr['obj_type'])) : ACTIVITY_OBJ_NOTE); + $arr['obj'] = ((x($arr, 'obj')) ? trim($arr['obj']) : ''); + $arr['tgt_type'] = ((x($arr, 'tgt_type')) ? notags(trim($arr['tgt_type'])) : ''); + $arr['target'] = ((x($arr, 'target')) ? trim($arr['target']) : ''); + $arr['plink'] = ((x($arr, 'plink')) ? notags(trim($arr['plink'])) : ''); + $arr['attach'] = ((x($arr, 'attach')) ? notags(trim($arr['attach'])) : ''); + $arr['app'] = ((x($arr, 'app')) ? notags(trim($arr['app'])) : ''); + $arr['replyto'] = ((x($arr, 'replyto')) ? serialise($arr['replyto']) : ''); - $arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : ''); - $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : ''); - $arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : ''); - $arr['thr_parent'] = ((x($arr,'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']); - $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST); - $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : ACTIVITY_OBJ_NOTE); - $arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : ''); - $arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : ''); - $arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : ''); - $arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : ''); - $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : ''); - $arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : ''); - $arr['replyto'] = ((x($arr,'replyto')) ? serialise($arr['replyto']) : ''); + $arr['public_policy'] = ''; - $arr['public_policy'] = ''; + $arr['comment_policy'] = ((x($arr, 'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' ); - $arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' ); + $arr['item_unseen'] = ((array_key_exists('item_unseen', $arr)) ? intval($arr['item_unseen']) : 1 ); + $arr['item_restrict'] = ((array_key_exists('item_restrict', $arr)) ? intval($arr['item_restrict']) : 0 ); - $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : 1 ); - $arr['item_restrict'] = ((array_key_exists('item_restrict',$arr)) ? intval($arr['item_restrict']) : 0 ); + if ((! array_key_exists('item_nocomment', $arr)) && ($arr['comment_policy'] == 'none')) { + $arr['item_nocomment'] = 1; + } - if((! array_key_exists('item_nocomment',$arr)) && ($arr['comment_policy'] == 'none')) - $arr['item_nocomment'] = 1; + // handle time travelers + // Allow a bit of fudge in case somebody just has a slightly slow/fast clock - // handle time travelers - // Allow a bit of fudge in case somebody just has a slightly slow/fast clock + $d1 = new DateTime('now +10 minutes', new DateTimeZone('UTC')); + $d2 = new DateTime($arr['created'] . '+00:00'); + if ($d2 > $d1) { + $arr['item_delayed'] = 1; + } - $d1 = new DateTime('now +10 minutes', new DateTimeZone('UTC')); - $d2 = new DateTime($arr['created'] . '+00:00'); - if($d2 > $d1) - $arr['item_delayed'] = 1; + $arr['llink'] = z_root() . '/display/' . gen_link_id($arr['mid']); - $arr['llink'] = z_root() . '/display/' . gen_link_id($arr['mid']); + if (! $arr['plink']) { + $arr['plink'] = $arr['llink']; + } - if(! $arr['plink']) - $arr['plink'] = $arr['llink']; + if ($arr['parent_mid'] === $arr['mid']) { + $parent_id = 0; + $parent_deleted = 0; + $allow_cid = $arr['allow_cid']; + $allow_gid = $arr['allow_gid']; + $deny_cid = $arr['deny_cid']; + $deny_gid = $arr['deny_gid']; + $comments_closed = $arr['comments_closed']; + $arr['item_thread_top'] = 1; + $arr['item_level'] = 0; + } else { + // find the parent and snarf the item id and ACL's + // and anything else we need to inherit - if($arr['parent_mid'] === $arr['mid']) { - $parent_id = 0; - $parent_deleted = 0; - $allow_cid = $arr['allow_cid']; - $allow_gid = $arr['allow_gid']; - $deny_cid = $arr['deny_cid']; - $deny_gid = $arr['deny_gid']; - $comments_closed = $arr['comments_closed']; - $arr['item_thread_top'] = 1; - $arr['item_level'] = 0; - } - else { + $r = q( + "SELECT item_level FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", + dbesc($arr['thr_parent']), + intval($arr['uid']) + ); + if ($r) { + $arr['item_level'] = intval($r[0]['item_level']) + 1; + } else { + $arr['item_level'] = 1; + } - // find the parent and snarf the item id and ACL's - // and anything else we need to inherit + $r = q( + "SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", + dbesc($arr['parent_mid']), + intval($arr['uid']) + ); - $r = q("SELECT item_level FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", - dbesc($arr['thr_parent']), - intval($arr['uid']) - ); - if($r) { - $arr['item_level'] = intval($r[0]['item_level']) + 1; - } - else { - $arr['item_level'] = 1; - } + // We may have this parent_mid without a token, so try that if we find a token - $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", - dbesc($arr['parent_mid']), - intval($arr['uid']) - ); + if (! $r) { + if (strpos($arr['parent_mid'], 'token=')) { + $r = q( + "SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", + dbesc(substr($arr['parent_mid'], 0, strpos($arr['parent_mid'], '?'))), + intval($arr['uid']) + ); + if ($r) { + $arr['parent_mid'] = $arr['thr_parent'] = substr($arr['parent_mid'], 0, strpos($arr['parent_mid'], '?')); + } + } + } - // We may have this parent_mid without a token, so try that if we find a token + if ($r) { + // in case item_store was killed before the parent's parent attribute got set, + // set it now. This happens with some regularity on Dreamhost. This will keep + // us from getting notifications for threads that exist but which we can't see. - if (! $r) { - if (strpos($arr['parent_mid'],'token=')) { - $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", - dbesc(substr($arr['parent_mid'],0,strpos($arr['parent_mid'],'?'))), - intval($arr['uid']) - ); - if ($r) { - $arr['parent_mid'] = $arr['thr_parent'] = substr($arr['parent_mid'],0,strpos($arr['parent_mid'],'?')); - } - } - } + if (($r[0]['mid'] === $r[0]['parent_mid']) && (! intval($r[0]['parent']))) { + q( + "update item set parent = id where id = %d", + intval($r[0]['id']) + ); + } - if ($r) { + if (comments_are_now_closed($r[0])) { + logger('item_store: comments closed'); + $ret['message'] = 'Comments closed.'; + return $ret; + } - // in case item_store was killed before the parent's parent attribute got set, - // set it now. This happens with some regularity on Dreamhost. This will keep - // us from getting notifications for threads that exist but which we can't see. + if (($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['obj'])) { + $arr['obj_type'] = ACTIVITY_OBJ_COMMENT; + } - if(($r[0]['mid'] === $r[0]['parent_mid']) && (! intval($r[0]['parent']))) { - q("update item set parent = id where id = %d", - intval($r[0]['id']) - ); - } + // is the new message multi-level threaded? + // even though we don't support it now, preserve the info + // and re-attach to the conversation parent. - if(comments_are_now_closed($r[0])) { - logger('item_store: comments closed'); - $ret['message'] = 'Comments closed.'; - return $ret; - } - - if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['obj'])) - $arr['obj_type'] = ACTIVITY_OBJ_COMMENT; - - // is the new message multi-level threaded? - // even though we don't support it now, preserve the info - // and re-attach to the conversation parent. - - if($r[0]['mid'] != $r[0]['parent_mid']) { - $arr['parent_mid'] = $r[0]['parent_mid']; - $z = q("SELECT * FROM item WHERE mid = '%s' AND parent_mid = '%s' AND uid = %d + if ($r[0]['mid'] != $r[0]['parent_mid']) { + $arr['parent_mid'] = $r[0]['parent_mid']; + $z = q( + "SELECT * FROM item WHERE mid = '%s' AND parent_mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1", - dbesc($r[0]['parent_mid']), - dbesc($r[0]['parent_mid']), - intval($arr['uid']) - ); - if($z && count($z)) - $r = $z; - } + dbesc($r[0]['parent_mid']), + dbesc($r[0]['parent_mid']), + intval($arr['uid']) + ); + if ($z && count($z)) { + $r = $z; + } + } - $parent_id = $r[0]['id']; - $parent_deleted = $r[0]['item_deleted']; + $parent_id = $r[0]['id']; + $parent_deleted = $r[0]['item_deleted']; - // item_restrict indicates an activitypub reply with a different - // delivery algorithm than the "parent-relay" or inherited privacy mode + // item_restrict indicates an activitypub reply with a different + // delivery algorithm than the "parent-relay" or inherited privacy mode - if(! (intval($arr['item_restrict']) & 1)) { - $allow_cid = $r[0]['allow_cid']; - $allow_gid = $r[0]['allow_gid']; - $deny_cid = $r[0]['deny_cid']; - $deny_gid = $r[0]['deny_gid']; - } + if (! (intval($arr['item_restrict']) & 1)) { + $allow_cid = $r[0]['allow_cid']; + $allow_gid = $r[0]['allow_gid']; + $deny_cid = $r[0]['deny_cid']; + $deny_gid = $r[0]['deny_gid']; + } - $comments_closed = $r[0]['comments_closed']; + $comments_closed = $r[0]['comments_closed']; - if(intval($r[0]['item_wall'])) - $arr['item_wall'] = 1; + if (intval($r[0]['item_wall'])) { + $arr['item_wall'] = 1; + } - // An uplinked comment might arrive with a downstream owner. - // Fix it. + // An uplinked comment might arrive with a downstream owner. + // Fix it. - if($r[0]['owner_xchan'] !== $arr['owner_xchan']) { - $arr['owner_xchan'] = $r[0]['owner_xchan']; - // $uplinked_comment = true; - } + if ($r[0]['owner_xchan'] !== $arr['owner_xchan']) { + $arr['owner_xchan'] = $r[0]['owner_xchan']; + // $uplinked_comment = true; + } - // if the parent is private and the child is not, force privacy for the entire conversation - // if the child is private, leave it alone regardless of the parent privacy state - - if(intval($r[0]['item_private']) && (! intval($arr['item_private']))) { - $arr['item_private'] = $r[0]['item_private']; - } + // if the parent is private and the child is not, force privacy for the entire conversation + // if the child is private, leave it alone regardless of the parent privacy state - // Edge case. We host a public forum that was originally posted to privately. - // The original author commented, but as this is a comment, the permissions - // weren't fixed up so it will still show the comment as private unless we fix it here. + if (intval($r[0]['item_private']) && (! intval($arr['item_private']))) { + $arr['item_private'] = $r[0]['item_private']; + } - if(intval($r[0]['item_uplink']) && (! $r[0]['item_private'])) - $arr['item_private'] = 0; + // Edge case. We host a public forum that was originally posted to privately. + // The original author commented, but as this is a comment, the permissions + // weren't fixed up so it will still show the comment as private unless we fix it here. - if(in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { - Activity::update_poll($r[0],$arr); - } - } - else { - logger('item_store: item parent was not found - ignoring item'); - $ret['message'] = 'parent not found.'; - return $ret; - } - } + if (intval($r[0]['item_uplink']) && (! $r[0]['item_private'])) { + $arr['item_private'] = 0; + } - if($parent_deleted) - $arr['item_deleted'] = 1; + if (in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { + Activity::update_poll($r[0], $arr); + } + } else { + logger('item_store: item parent was not found - ignoring item'); + $ret['message'] = 'parent not found.'; + return $ret; + } + } - $r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d and revision = %d LIMIT 1", - dbesc($arr['mid']), - intval($arr['uid']), - intval($arr['revision']) - ); - if($r) { - logger('duplicate item ignored. ' . print_r($arr,true)); - $ret['message'] = 'duplicate post.'; - return $ret; - } + if ($parent_deleted) { + $arr['item_deleted'] = 1; + } - if (LibBlock::fetch_by_entity($arr['uid'],$arr['owner_xchan']) || LibBlock::fetch_by_entity($arr['uid'],$arr['author_xchan'])) { - logger('Post cancelled by block rule.'); - $ret['message'] = 'cancelled.'; - return $ret; - } - - /** - * @hooks item_store - * Called when item_store() stores a record of type item. - */ + $r = q( + "SELECT id FROM item WHERE mid = '%s' AND uid = %d and revision = %d LIMIT 1", + dbesc($arr['mid']), + intval($arr['uid']), + intval($arr['revision']) + ); + if ($r) { + logger('duplicate item ignored. ' . print_r($arr, true)); + $ret['message'] = 'duplicate post.'; + return $ret; + } - call_hooks('item_store', $arr); + if (LibBlock::fetch_by_entity($arr['uid'], $arr['owner_xchan']) || LibBlock::fetch_by_entity($arr['uid'], $arr['author_xchan'])) { + logger('Post cancelled by block rule.'); + $ret['message'] = 'cancelled.'; + return $ret; + } - /** - * @hooks post_remote - * Called when an activity arrives from another site. - * This hook remains for backward compatibility. - */ - call_hooks('post_remote', $arr); + /** + * @hooks item_store + * Called when item_store() stores a record of type item. + */ - if(x($arr, 'cancel')) { - logger('Post cancelled by plugin.'); - $ret['message'] = 'cancelled.'; - return $ret; - } + call_hooks('item_store', $arr); - // pull out all the taxonomy stuff for separate storage + /** + * @hooks post_remote + * Called when an activity arrives from another site. + * This hook remains for backward compatibility. + */ + call_hooks('post_remote', $arr); - $terms = null; - if(array_key_exists('term',$arr)) { - $terms = $arr['term']; - unset($arr['term']); - } + if (x($arr, 'cancel')) { + logger('Post cancelled by plugin.'); + $ret['message'] = 'cancelled.'; + return $ret; + } - $meta = null; - if(array_key_exists('iconfig',$arr)) { - $meta = $arr['iconfig']; - unset($arr['iconfig']); - } + // pull out all the taxonomy stuff for separate storage + + $terms = null; + if (array_key_exists('term', $arr)) { + $terms = $arr['term']; + unset($arr['term']); + } + + $meta = null; + if (array_key_exists('iconfig', $arr)) { + $meta = $arr['iconfig']; + unset($arr['iconfig']); + } - $private = intval($arr['item_private']); + $private = intval($arr['item_private']); - if (! $private) { - if (strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) { - $private = 1; - } - } + if (! $private) { + if (strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) { + $private = 1; + } + } - $arr['parent'] = $parent_id; - $arr['allow_cid'] = $allow_cid; - $arr['allow_gid'] = $allow_gid; - $arr['deny_cid'] = $deny_cid; - $arr['deny_gid'] = $deny_gid; - $arr['item_private'] = $private; - $arr['comments_closed'] = $comments_closed; + $arr['parent'] = $parent_id; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; + $arr['comments_closed'] = $comments_closed; - logger('item_store: ' . print_r($arr,true), LOGGER_DATA); + logger('item_store: ' . print_r($arr, true), LOGGER_DATA); - create_table_from_array('item',$arr); + create_table_from_array('item', $arr); - // find the item we just created + // find the item we just created - $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d and revision = %d ORDER BY id ASC ", - $arr['mid'], // already dbesc'd - intval($arr['uid']), - intval($arr['revision']) - ); + $r = q( + "SELECT * FROM item WHERE mid = '%s' AND uid = %d and revision = %d ORDER BY id ASC ", + $arr['mid'], // already dbesc'd + intval($arr['uid']), + intval($arr['revision']) + ); - if($r) { - // This will gives us a fresh copy of what's now in the DB and undo the db escaping, - // which really messes up the notifications + if ($r) { + // This will gives us a fresh copy of what's now in the DB and undo the db escaping, + // which really messes up the notifications - $current_post = $r[0]['id']; - $arr = $r[0]; - logger('item_store: created item ' . $current_post, LOGGER_DEBUG); - } - else { - logger('item_store: could not locate stored item'); - $ret['message'] = 'unable to retrieve.'; - return $ret; - } - if(count($r) > 1) { - logger('item_store: duplicated post occurred. Removing duplicates.'); - q("DELETE FROM item WHERE mid = '%s' AND uid = %d AND id != %d ", - $arr['mid'], - intval($arr['uid']), - intval($current_post) - ); - } + $current_post = $r[0]['id']; + $arr = $r[0]; + logger('item_store: created item ' . $current_post, LOGGER_DEBUG); + } else { + logger('item_store: could not locate stored item'); + $ret['message'] = 'unable to retrieve.'; + return $ret; + } + if (count($r) > 1) { + logger('item_store: duplicated post occurred. Removing duplicates.'); + q( + "DELETE FROM item WHERE mid = '%s' AND uid = %d AND id != %d ", + $arr['mid'], + intval($arr['uid']), + intval($current_post) + ); + } - $arr['id'] = $current_post; + $arr['id'] = $current_post; - if(! intval($r[0]['parent'])) { - $x = q("update item set parent = id where id = %d", - intval($r[0]['id']) - ); - $arr['parent'] = $r[0]['id']; - } + if (! intval($r[0]['parent'])) { + $x = q( + "update item set parent = id where id = %d", + intval($r[0]['id']) + ); + $arr['parent'] = $r[0]['id']; + } - // Store taxonomy + // Store taxonomy - if(($terms) && (is_array($terms))) { - foreach($terms as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) + if (($terms) && (is_array($terms))) { + foreach ($terms as $t) { + q( + "insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", - intval($arr['uid']), - intval($current_post), - intval(TERM_OBJ_POST), - intval($t['ttype']), - dbesc($t['term']), - dbesc($t['url']) - ); - } + intval($arr['uid']), + intval($current_post), + intval(TERM_OBJ_POST), + intval($t['ttype']), + dbesc($t['term']), + dbesc($t['url']) + ); + } - $arr['term'] = $terms; - } + $arr['term'] = $terms; + } - if($meta) { - foreach($meta as $m) { - set_iconfig($current_post,$m['cat'],$m['k'],$m['v'],$m['sharing']); - } - $arr['iconfig'] = $meta; - } + if ($meta) { + foreach ($meta as $m) { + set_iconfig($current_post, $m['cat'], $m['k'], $m['v'], $m['sharing']); + } + $arr['iconfig'] = $meta; + } - $ret['item'] = $arr; + $ret['item'] = $arr; - /** - * @hooks post_remote_end - * Called after processing a remote post. - */ - call_hooks('post_remote_end', $arr); + /** + * @hooks post_remote_end + * Called after processing a remote post. + */ + call_hooks('post_remote_end', $arr); - item_update_parent_commented($arr); + item_update_parent_commented($arr); - if((strpos($arr['body'],'[embed]') !== false) || (strpos($arr['body'],'[/img]') !== false) || (strpos($arr['body'],'[/zmg]') !== false)) { - Run::Summon([ 'Cache_embeds', $current_post ]); - } + if ((strpos($arr['body'], '[embed]') !== false) || (strpos($arr['body'], '[/img]') !== false) || (strpos($arr['body'], '[/zmg]') !== false)) { + Run::Summon([ 'Cache_embeds', $current_post ]); + } - // If _creating_ a deleted item, don't propagate it further or send out notifications. - // We need to store the item details just in case the delete came in before the original post, - // so that we have an item in the DB that's marked deleted and won't store a fresh post - // that isn't aware that we were already told to delete it. + // If _creating_ a deleted item, don't propagate it further or send out notifications. + // We need to store the item details just in case the delete came in before the original post, + // so that we have an item in the DB that's marked deleted and won't store a fresh post + // that isn't aware that we were already told to delete it. - if(($deliver) && (! intval($arr['item_deleted']))) { - send_status_notifications($current_post,$arr); - tag_deliver($arr['uid'],$current_post); - } + if (($deliver) && (! intval($arr['item_deleted']))) { + send_status_notifications($current_post, $arr); + tag_deliver($arr['uid'], $current_post); + } - $ret['success'] = true; - $ret['item_id'] = $current_post; + $ret['success'] = true; + $ret['item_id'] = $current_post; -// if($linkid) { -// $li = [ $ret['item'] ]; -// xchan_query($li); -// $sync_item = fetch_post_tags($li); -// Libsync::build_link_packet($arr['uid'],[ 'item' => [ encode_item($sync_item[0],true) ] ]); -// } +// if($linkid) { +// $li = [ $ret['item'] ]; +// xchan_query($li); +// $sync_item = fetch_post_tags($li); +// Libsync::build_link_packet($arr['uid'],[ 'item' => [ encode_item($sync_item[0],true) ] ]); +// } - return $ret; + return $ret; } @@ -2085,477 +2182,499 @@ function item_store($arr, $allow_exec = false, $deliver = true, $linkid = true) * @param bool $deliver (optional) default true * @return array */ -function item_store_update($arr, $allow_exec = false, $deliver = true, $linkid = true) { +function item_store_update($arr, $allow_exec = false, $deliver = true, $linkid = true) +{ - $d = [ - 'item' => $arr, - 'allow_exec' => $allow_exec - ]; - /** - * @hooks item_store_update_before - * Called when item_store_update() is called to update a stored item. It - * overwrites the function's parameters $arr and $allow_exec. - * * \e array \b item - * * \e boolean \b allow_exec - */ - call_hooks('item_store_update_before', $d); - $arr = $d['item']; - $allow_exec = $d['allow_exec']; + $d = [ + 'item' => $arr, + 'allow_exec' => $allow_exec + ]; + /** + * @hooks item_store_update_before + * Called when item_store_update() is called to update a stored item. It + * overwrites the function's parameters $arr and $allow_exec. + * * \e array \b item + * * \e boolean \b allow_exec + */ + call_hooks('item_store_update_before', $d); + $arr = $d['item']; + $allow_exec = $d['allow_exec']; - $ret = array('success' => false, 'item_id' => 0); + $ret = array('success' => false, 'item_id' => 0); - if(array_key_exists('cancel',$arr) && $arr['cancel']) { - logger('cancelled by plugin'); - return $ret; - } + if (array_key_exists('cancel', $arr) && $arr['cancel']) { + logger('cancelled by plugin'); + return $ret; + } - if(! intval($arr['uid'])) { - logger('no uid'); - $ret['message'] = 'no uid.'; - return $ret; - } - if(! intval($arr['id'])) { - logger('no id'); - $ret['message'] = 'no id.'; - return $ret; - } + if (! intval($arr['uid'])) { + logger('no uid'); + $ret['message'] = 'no uid.'; + return $ret; + } + if (! intval($arr['id'])) { + logger('no id'); + $ret['message'] = 'no id.'; + return $ret; + } - $orig_post_id = $arr['id']; - $uid = $arr['uid']; + $orig_post_id = $arr['id']; + $uid = $arr['uid']; - $orig = q("select * from item where id = %d and uid = %d limit 1", - intval($orig_post_id), - intval($uid) - ); - if(! $orig) { - logger('Original post not found: ' . $orig_post_id); - $ret['message'] = 'no original'; - return $ret; - } + $orig = q( + "select * from item where id = %d and uid = %d limit 1", + intval($orig_post_id), + intval($uid) + ); + if (! $orig) { + logger('Original post not found: ' . $orig_post_id); + $ret['message'] = 'no original'; + return $ret; + } - // override the unseen flag with the original + // override the unseen flag with the original - $arr['item_unseen'] = $orig[0]['item_unseen']; + $arr['item_unseen'] = $orig[0]['item_unseen']; - $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim(escape_tags($arr['title'])) : ''); - $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); - $arr['html'] = ((array_key_exists('html',$arr) && strlen($arr['html'])) ? trim($arr['html']) : ''); + $arr['title'] = ((array_key_exists('title', $arr) && strlen($arr['title'])) ? trim(escape_tags($arr['title'])) : ''); + $arr['body'] = ((array_key_exists('body', $arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); + $arr['html'] = ((array_key_exists('html', $arr) && strlen($arr['html'])) ? trim($arr['html']) : ''); - if(array_key_exists('edit',$arr)) - unset($arr['edit']); + if (array_key_exists('edit', $arr)) { + unset($arr['edit']); + } - $arr['mimetype'] = ((x($arr,'mimetype')) ? notags(trim($arr['mimetype'])) : 'text/bbcode'); + $arr['mimetype'] = ((x($arr, 'mimetype')) ? notags(trim($arr['mimetype'])) : 'text/bbcode'); - if(($arr['mimetype'] == 'application/x-php') && (! $allow_exec)) { - logger('item_store: php mimetype but allow_exec is denied.'); - $ret['message'] = 'exec denied.'; - return $ret; - } + if (($arr['mimetype'] == 'application/x-php') && (! $allow_exec)) { + logger('item_store: php mimetype but allow_exec is denied.'); + $ret['message'] = 'exec denied.'; + return $ret; + } - $arr['lang'] = detect_language($arr['body']); + $arr['lang'] = detect_language($arr['body']); - // apply the input filter here + // apply the input filter here - $arr['summary'] = trim(z_input_filter($arr['summary'],$arr['mimetype'],$allow_exec)); - $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec)); + $arr['summary'] = trim(z_input_filter($arr['summary'], $arr['mimetype'], $allow_exec)); + $arr['body'] = trim(z_input_filter($arr['body'], $arr['mimetype'], $allow_exec)); - item_sign($arr); + item_sign($arr); - $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); + $allowed_languages = get_pconfig($arr['uid'], 'system', 'allowed_languages'); - if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) { - $translate = [ - 'item' => $arr, - 'from' => $arr['lang'], - 'to' => $allowed_languages, - 'translated' => false - ]; - /** - * @hooks item_translate - * Called from item_store() and item_store_update() after the post language has been autodetected. - * * \e array \b item - returned value - * * \e string \b from - * * \e string \b to - * * \e boolean \b translated - default false, set true if hook translated it and provide it in item - */ - call_hooks('item_translate', $translate); - if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) { - logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); - $ret['message'] = 'language not accepted'; - return $ret; - } - $arr = $translate['item']; - } + if ((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'], $allowed_languages))) { + $translate = [ + 'item' => $arr, + 'from' => $arr['lang'], + 'to' => $allowed_languages, + 'translated' => false + ]; + /** + * @hooks item_translate + * Called from item_store() and item_store_update() after the post language has been autodetected. + * * \e array \b item - returned value + * * \e string \b from + * * \e string \b to + * * \e boolean \b translated - default false, set true if hook translated it and provide it in item + */ + call_hooks('item_translate', $translate); + if ((! $translate['translated']) && (intval(get_pconfig($arr['uid'], 'system', 'reject_disallowed_languages')))) { + logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']); + $ret['message'] = 'language not accepted'; + return $ret; + } + $arr = $translate['item']; + } - if(x($arr,'obj')) { - $arr['obj'] = item_json_encapsulate($arr,'obj'); - } + if (x($arr, 'obj')) { + $arr['obj'] = item_json_encapsulate($arr, 'obj'); + } - if(x($arr,'target')) { - $arr['target'] = item_json_encapsulate($arr,'target'); - } + if (x($arr, 'target')) { + $arr['target'] = item_json_encapsulate($arr, 'target'); + } - if(x($arr,'attach')) { - $arr['attach'] = item_json_encapsulate($arr,'attach'); - } + if (x($arr, 'attach')) { + $arr['attach'] = item_json_encapsulate($arr, 'attach'); + } - unset($arr['id']); - unset($arr['uid']); - unset($arr['aid']); - unset($arr['uuid']); - unset($arr['mid']); - unset($arr['parent']); - unset($arr['parent_mid']); - unset($arr['author_xchan']); - unset($arr['owner_xchan']); - unset($arr['source_xchan']); - unset($arr['thr_parent']); - unset($arr['llink']); + unset($arr['id']); + unset($arr['uid']); + unset($arr['aid']); + unset($arr['uuid']); + unset($arr['mid']); + unset($arr['parent']); + unset($arr['parent_mid']); + unset($arr['author_xchan']); + unset($arr['owner_xchan']); + unset($arr['source_xchan']); + unset($arr['thr_parent']); + unset($arr['llink']); - if (intval($orig[0]['item_unpublished'])) { + if (intval($orig[0]['item_unpublished'])) { + $arr['created'] = ((x($arr, 'created') !== false) ? datetime_convert('UTC', 'UTC', $arr['created']) : datetime_convert()); + $arr['edited'] = $arr['created']; + $arr['expires'] = ((x($arr, 'expires') !== false) ? datetime_convert('UTC', 'UTC', $arr['expires']) : NULL_DATE); - $arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert()); - $arr['edited'] = $arr['created']; - $arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : NULL_DATE); + if (array_key_exists('comments_closed', $arr) && $arr['comments_closed'] > NULL_DATE) { + $arr['comments_closed'] = datetime_convert('UTC', 'UTC', $arr['comments_closed']); + } else { + $arr['comments_closed'] = NULL_DATE; + } - if(array_key_exists('comments_closed',$arr) && $arr['comments_closed'] > NULL_DATE) - $arr['comments_closed'] = datetime_convert('UTC','UTC',$arr['comments_closed']); - else - $arr['comments_closed'] = NULL_DATE; + $arr['commented'] = $arr['created']; - $arr['commented'] = $arr['created']; + $arr['received'] = $arr['created']; + $arr['changed'] = $arr['created']; + } else { + unset($arr['created']); - $arr['received'] = $arr['created']; - $arr['changed'] = $arr['created']; - } - - else { - unset($arr['created']); - - $arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : $orig[0]['expires']); + $arr['expires'] = ((x($arr, 'expires') !== false) ? datetime_convert('UTC', 'UTC', $arr['expires']) : $orig[0]['expires']); - if(array_key_exists('comments_closed',$arr) && $arr['comments_closed'] > NULL_DATE) - $arr['comments_closed'] = datetime_convert('UTC','UTC',$arr['comments_closed']); - else - $arr['comments_closed'] = $orig[0]['comments_closed']; + if (array_key_exists('comments_closed', $arr) && $arr['comments_closed'] > NULL_DATE) { + $arr['comments_closed'] = datetime_convert('UTC', 'UTC', $arr['comments_closed']); + } else { + $arr['comments_closed'] = $orig[0]['comments_closed']; + } - $arr['commented'] = $orig[0]['commented']; - $arr['received'] = $orig[0]['received']; - $arr['changed'] = $orig[0]['changed']; - } + $arr['commented'] = $orig[0]['commented']; + $arr['received'] = $orig[0]['received']; + $arr['changed'] = $orig[0]['changed']; + } - $arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert()); - $arr['revision'] = ((x($arr,'revision') && $arr['revision'] > 0) ? intval($arr['revision']) : 0); - $arr['route'] = ((array_key_exists('route',$arr)) ? trim($arr['route']) : $orig[0]['route']); + $arr['edited'] = ((x($arr, 'edited') !== false) ? datetime_convert('UTC', 'UTC', $arr['edited']) : datetime_convert()); + $arr['revision'] = ((x($arr, 'revision') && $arr['revision'] > 0) ? intval($arr['revision']) : 0); + $arr['route'] = ((array_key_exists('route', $arr)) ? trim($arr['route']) : $orig[0]['route']); - $arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']); - $arr['uuid'] = ((x($arr,'uuid')) ? notags(trim($arr['uuid'])) : $orig[0]['uuid']); - $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']); - $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']); - $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : $orig[0]['obj_type']); - $arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : $orig[0]['obj']); - $arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : $orig[0]['tgt_type']); - $arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : $orig[0]['target']); - $arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : $orig[0]['plink']); - $arr['replyto'] = ((x($arr,'replyto')) ? serialise($arr['replyto']) : $orig[0]['replyto']); + $arr['location'] = ((x($arr, 'location')) ? notags(trim($arr['location'])) : $orig[0]['location']); + $arr['uuid'] = ((x($arr, 'uuid')) ? notags(trim($arr['uuid'])) : $orig[0]['uuid']); + $arr['coord'] = ((x($arr, 'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']); + $arr['verb'] = ((x($arr, 'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']); + $arr['obj_type'] = ((x($arr, 'obj_type')) ? notags(trim($arr['obj_type'])) : $orig[0]['obj_type']); + $arr['obj'] = ((x($arr, 'obj')) ? trim($arr['obj']) : $orig[0]['obj']); + $arr['tgt_type'] = ((x($arr, 'tgt_type')) ? notags(trim($arr['tgt_type'])) : $orig[0]['tgt_type']); + $arr['target'] = ((x($arr, 'target')) ? trim($arr['target']) : $orig[0]['target']); + $arr['plink'] = ((x($arr, 'plink')) ? notags(trim($arr['plink'])) : $orig[0]['plink']); + $arr['replyto'] = ((x($arr, 'replyto')) ? serialise($arr['replyto']) : $orig[0]['replyto']); - $arr['allow_cid'] = ((array_key_exists('allow_cid',$arr)) ? trim($arr['allow_cid']) : $orig[0]['allow_cid']); - $arr['allow_gid'] = ((array_key_exists('allow_gid',$arr)) ? trim($arr['allow_gid']) : $orig[0]['allow_gid']); - $arr['deny_cid'] = ((array_key_exists('deny_cid',$arr)) ? trim($arr['deny_cid']) : $orig[0]['deny_cid']); - $arr['deny_gid'] = ((array_key_exists('deny_gid',$arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']); - $arr['item_private'] = ((array_key_exists('item_private',$arr)) ? intval($arr['item_private']) : $orig[0]['item_private']); + $arr['allow_cid'] = ((array_key_exists('allow_cid', $arr)) ? trim($arr['allow_cid']) : $orig[0]['allow_cid']); + $arr['allow_gid'] = ((array_key_exists('allow_gid', $arr)) ? trim($arr['allow_gid']) : $orig[0]['allow_gid']); + $arr['deny_cid'] = ((array_key_exists('deny_cid', $arr)) ? trim($arr['deny_cid']) : $orig[0]['deny_cid']); + $arr['deny_gid'] = ((array_key_exists('deny_gid', $arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']); + $arr['item_private'] = ((array_key_exists('item_private', $arr)) ? intval($arr['item_private']) : $orig[0]['item_private']); - $arr['attach'] = ((array_key_exists('attach',$arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']); - $arr['app'] = ((array_key_exists('app',$arr)) ? notags(trim($arr['app'])) : $orig[0]['app']); + $arr['attach'] = ((array_key_exists('attach', $arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']); + $arr['app'] = ((array_key_exists('app', $arr)) ? notags(trim($arr['app'])) : $orig[0]['app']); - $arr['item_origin'] = ((array_key_exists('item_origin',$arr)) ? intval($arr['item_origin']) : $orig[0]['item_origin'] ); - $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : $orig[0]['item_unseen'] ); - $arr['item_starred'] = ((array_key_exists('item_starred',$arr)) ? intval($arr['item_starred']) : $orig[0]['item_starred'] ); - $arr['item_uplink'] = ((array_key_exists('item_uplink',$arr)) ? intval($arr['item_uplink']) : $orig[0]['item_uplink'] ); - $arr['item_consensus'] = ((array_key_exists('item_consensus',$arr)) ? intval($arr['item_consensus']) : $orig[0]['item_consensus'] ); - $arr['item_wall'] = ((array_key_exists('item_wall',$arr)) ? intval($arr['item_wall']) : $orig[0]['item_wall'] ); - $arr['item_thread_top'] = ((array_key_exists('item_thread_top',$arr)) ? intval($arr['item_thread_top']) : $orig[0]['item_thread_top'] ); - $arr['item_notshown'] = ((array_key_exists('item_notshown',$arr)) ? intval($arr['item_notshown']) : $orig[0]['item_notshown'] ); - $arr['item_nsfw'] = ((array_key_exists('item_nsfw',$arr)) ? intval($arr['item_nsfw']) : $orig[0]['item_nsfw'] ); - $arr['item_relay'] = ((array_key_exists('item_relay',$arr)) ? intval($arr['item_relay']) : $orig[0]['item_relay'] ); - $arr['item_mentionsme'] = ((array_key_exists('item_mentionsme',$arr)) ? intval($arr['item_mentionsme']) : $orig[0]['item_mentionsme'] ); - $arr['item_nocomment'] = ((array_key_exists('item_nocomment',$arr)) ? intval($arr['item_nocomment']) : $orig[0]['item_nocomment'] ); - $arr['item_obscured'] = ((array_key_exists('item_obscured',$arr)) ? intval($arr['item_obscured']) : $orig[0]['item_obscured'] ); - $arr['item_verified'] = ((array_key_exists('item_verified',$arr)) ? intval($arr['item_verified']) : $orig[0]['item_verified'] ); - $arr['item_retained'] = ((array_key_exists('item_retained',$arr)) ? intval($arr['item_retained']) : $orig[0]['item_retained'] ); - $arr['item_rss'] = ((array_key_exists('item_rss',$arr)) ? intval($arr['item_rss']) : $orig[0]['item_rss'] ); - $arr['item_deleted'] = ((array_key_exists('item_deleted',$arr)) ? intval($arr['item_deleted']) : $orig[0]['item_deleted'] ); - $arr['item_type'] = ((array_key_exists('item_type',$arr)) ? intval($arr['item_type']) : $orig[0]['item_type'] ); - $arr['item_hidden'] = ((array_key_exists('item_hidden',$arr)) ? intval($arr['item_hidden']) : $orig[0]['item_hidden'] ); - $arr['item_unpublished'] = ((array_key_exists('item_unpublished',$arr)) ? intval($arr['item_unpublished']) : $orig[0]['item_unpublished'] ); - $arr['item_delayed'] = ((array_key_exists('item_delayed',$arr)) ? intval($arr['item_delayed']) : $orig[0]['item_delayed'] ); - $arr['item_pending_remove'] = ((array_key_exists('item_pending_remove',$arr)) ? intval($arr['item_pending_remove']) : $orig[0]['item_pending_remove'] ); - $arr['item_blocked'] = ((array_key_exists('item_blocked',$arr)) ? intval($arr['item_blocked']) : $orig[0]['item_blocked'] ); + $arr['item_origin'] = ((array_key_exists('item_origin', $arr)) ? intval($arr['item_origin']) : $orig[0]['item_origin'] ); + $arr['item_unseen'] = ((array_key_exists('item_unseen', $arr)) ? intval($arr['item_unseen']) : $orig[0]['item_unseen'] ); + $arr['item_starred'] = ((array_key_exists('item_starred', $arr)) ? intval($arr['item_starred']) : $orig[0]['item_starred'] ); + $arr['item_uplink'] = ((array_key_exists('item_uplink', $arr)) ? intval($arr['item_uplink']) : $orig[0]['item_uplink'] ); + $arr['item_consensus'] = ((array_key_exists('item_consensus', $arr)) ? intval($arr['item_consensus']) : $orig[0]['item_consensus'] ); + $arr['item_wall'] = ((array_key_exists('item_wall', $arr)) ? intval($arr['item_wall']) : $orig[0]['item_wall'] ); + $arr['item_thread_top'] = ((array_key_exists('item_thread_top', $arr)) ? intval($arr['item_thread_top']) : $orig[0]['item_thread_top'] ); + $arr['item_notshown'] = ((array_key_exists('item_notshown', $arr)) ? intval($arr['item_notshown']) : $orig[0]['item_notshown'] ); + $arr['item_nsfw'] = ((array_key_exists('item_nsfw', $arr)) ? intval($arr['item_nsfw']) : $orig[0]['item_nsfw'] ); + $arr['item_relay'] = ((array_key_exists('item_relay', $arr)) ? intval($arr['item_relay']) : $orig[0]['item_relay'] ); + $arr['item_mentionsme'] = ((array_key_exists('item_mentionsme', $arr)) ? intval($arr['item_mentionsme']) : $orig[0]['item_mentionsme'] ); + $arr['item_nocomment'] = ((array_key_exists('item_nocomment', $arr)) ? intval($arr['item_nocomment']) : $orig[0]['item_nocomment'] ); + $arr['item_obscured'] = ((array_key_exists('item_obscured', $arr)) ? intval($arr['item_obscured']) : $orig[0]['item_obscured'] ); + $arr['item_verified'] = ((array_key_exists('item_verified', $arr)) ? intval($arr['item_verified']) : $orig[0]['item_verified'] ); + $arr['item_retained'] = ((array_key_exists('item_retained', $arr)) ? intval($arr['item_retained']) : $orig[0]['item_retained'] ); + $arr['item_rss'] = ((array_key_exists('item_rss', $arr)) ? intval($arr['item_rss']) : $orig[0]['item_rss'] ); + $arr['item_deleted'] = ((array_key_exists('item_deleted', $arr)) ? intval($arr['item_deleted']) : $orig[0]['item_deleted'] ); + $arr['item_type'] = ((array_key_exists('item_type', $arr)) ? intval($arr['item_type']) : $orig[0]['item_type'] ); + $arr['item_hidden'] = ((array_key_exists('item_hidden', $arr)) ? intval($arr['item_hidden']) : $orig[0]['item_hidden'] ); + $arr['item_unpublished'] = ((array_key_exists('item_unpublished', $arr)) ? intval($arr['item_unpublished']) : $orig[0]['item_unpublished'] ); + $arr['item_delayed'] = ((array_key_exists('item_delayed', $arr)) ? intval($arr['item_delayed']) : $orig[0]['item_delayed'] ); + $arr['item_pending_remove'] = ((array_key_exists('item_pending_remove', $arr)) ? intval($arr['item_pending_remove']) : $orig[0]['item_pending_remove'] ); + $arr['item_blocked'] = ((array_key_exists('item_blocked', $arr)) ? intval($arr['item_blocked']) : $orig[0]['item_blocked'] ); - $arr['sig'] = ((x($arr,'sig')) ? $arr['sig'] : ''); - $arr['layout_mid'] = ((array_key_exists('layout_mid',$arr)) ? dbesc($arr['layout_mid']) : $orig[0]['layout_mid'] ); + $arr['sig'] = ((x($arr, 'sig')) ? $arr['sig'] : ''); + $arr['layout_mid'] = ((array_key_exists('layout_mid', $arr)) ? dbesc($arr['layout_mid']) : $orig[0]['layout_mid'] ); - $arr['public_policy'] = ''; - $arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : $orig[0]['comment_policy'] ); + $arr['public_policy'] = ''; + $arr['comment_policy'] = ((x($arr, 'comment_policy')) ? notags(trim($arr['comment_policy'])) : $orig[0]['comment_policy'] ); - /** - * @hooks post_remote_update - * Called when processing a remote post that involved an edit or update. - */ - call_hooks('post_remote_update', $arr); + /** + * @hooks post_remote_update + * Called when processing a remote post that involved an edit or update. + */ + call_hooks('post_remote_update', $arr); - if(x($arr, 'cancel')) { - logger('Post cancelled by plugin.'); - $ret['message'] = 'cancelled.'; - return $ret; - } + if (x($arr, 'cancel')) { + logger('Post cancelled by plugin.'); + $ret['message'] = 'cancelled.'; + return $ret; + } - // pull out all the taxonomy stuff for separate storage + // pull out all the taxonomy stuff for separate storage - $terms = null; - if(array_key_exists('term',$arr)) { - $terms = $arr['term']; - unset($arr['term']); - } + $terms = null; + if (array_key_exists('term', $arr)) { + $terms = $arr['term']; + unset($arr['term']); + } - $meta = null; - if(array_key_exists('iconfig',$arr)) { - $meta = $arr['iconfig']; - unset($arr['iconfig']); - } + $meta = null; + if (array_key_exists('iconfig', $arr)) { + $meta = $arr['iconfig']; + unset($arr['iconfig']); + } - logger('item_store_update: ' . print_r($arr,true), LOGGER_DATA); + logger('item_store_update: ' . print_r($arr, true), LOGGER_DATA); - $str = ''; - foreach($arr as $k => $v) { - if($str) - $str .= ","; - $str .= " " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) . "' "; - } + $str = ''; + foreach ($arr as $k => $v) { + if ($str) { + $str .= ","; + } + $str .= " " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) . "' "; + } - $r = dbq("update item set " . $str . " where id = " . $orig_post_id ); + $r = dbq("update item set " . $str . " where id = " . $orig_post_id); - if($r) - logger('Updated item ' . $orig_post_id, LOGGER_DEBUG); - else { - logger('Could not update item'); - $ret['message'] = 'DB update failed.'; - return $ret; - } + if ($r) { + logger('Updated item ' . $orig_post_id, LOGGER_DEBUG); + } else { + logger('Could not update item'); + $ret['message'] = 'DB update failed.'; + return $ret; + } - // fetch an unescaped complete copy of the stored item + // fetch an unescaped complete copy of the stored item - $r = q("select * from item where id = %d", - intval($orig_post_id) - ); - if($r) - $arr = $r[0]; + $r = q( + "select * from item where id = %d", + intval($orig_post_id) + ); + if ($r) { + $arr = $r[0]; + } - $r = q("delete from term where oid = %d and otype = %d", - intval($orig_post_id), - intval(TERM_OBJ_POST) - ); + $r = q( + "delete from term where oid = %d and otype = %d", + intval($orig_post_id), + intval(TERM_OBJ_POST) + ); - if(is_array($terms)) { - foreach($terms as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) + if (is_array($terms)) { + foreach ($terms as $t) { + q( + "insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", - intval($uid), - intval($orig_post_id), - intval(TERM_OBJ_POST), - intval($t['ttype']), - dbesc($t['term']), - dbesc($t['url']) - ); - } - $arr['term'] = $terms; - } + intval($uid), + intval($orig_post_id), + intval(TERM_OBJ_POST), + intval($t['ttype']), + dbesc($t['term']), + dbesc($t['url']) + ); + } + $arr['term'] = $terms; + } - $r = q("delete from iconfig where iid = %d", - intval($orig_post_id) - ); + $r = q( + "delete from iconfig where iid = %d", + intval($orig_post_id) + ); - if($meta) { - foreach($meta as $m) { - set_iconfig($orig_post_id,$m['cat'],$m['k'],$m['v'],$m['sharing']); - } - $arr['iconfig'] = $meta; - } + if ($meta) { + foreach ($meta as $m) { + set_iconfig($orig_post_id, $m['cat'], $m['k'], $m['v'], $m['sharing']); + } + $arr['iconfig'] = $meta; + } - $ret['item'] = $arr; + $ret['item'] = $arr; - /** - * @hooks post_remote_update_end - * Called after processing a remote post that involved an edit or update. - */ - call_hooks('post_remote_update_end', $arr); + /** + * @hooks post_remote_update_end + * Called after processing a remote post that involved an edit or update. + */ + call_hooks('post_remote_update_end', $arr); - if((strpos($arr['body'],'[embed]') !== false) || (strpos($arr['body'],'[/img]') !== false)) { - Run::Summon([ 'Cache_embeds', $orig_post_id ]); - } + if ((strpos($arr['body'], '[embed]') !== false) || (strpos($arr['body'], '[/img]') !== false)) { + Run::Summon([ 'Cache_embeds', $orig_post_id ]); + } - if($deliver) { - // don't send notify_comment for edits - // send_status_notifications($orig_post_id,$arr); - tag_deliver($uid,$orig_post_id); - } + if ($deliver) { + // don't send notify_comment for edits + // send_status_notifications($orig_post_id,$arr); + tag_deliver($uid, $orig_post_id); + } - $ret['success'] = true; - $ret['item_id'] = $orig_post_id; + $ret['success'] = true; + $ret['item_id'] = $orig_post_id; -// if($linkid) { -// $li = [ $ret['item'] ]; -// xchan_query($li); -// $sync_item = fetch_post_tags($li); -// Libsync::build_link_packet($arr['uid'],[ 'item' => [ encode_item($sync_item[0],true) ] ]); -// } +// if($linkid) { +// $li = [ $ret['item'] ]; +// xchan_query($li); +// $sync_item = fetch_post_tags($li); +// Libsync::build_link_packet($arr['uid'],[ 'item' => [ encode_item($sync_item[0],true) ] ]); +// } - return $ret; + return $ret; } -function item_update_parent_commented($item) { +function item_update_parent_commented($item) +{ - $update_parent = true; - - // update the commented timestamp on the parent - // - unless this is a moderated comment or a potential clone of an older item - // which we don't wish to bring to the surface. As the queue only holds deliveries - // for 3 days, it's suspected of being an older cloned item if the creation time - // is older than that. + $update_parent = true; - if(intval($item['item_blocked']) === ITEM_MODERATED) - $update_parent = false; - - if($item['created'] < datetime_convert('','','now - 4 days')) - $update_parent = false; + // update the commented timestamp on the parent + // - unless this is a moderated comment or a potential clone of an older item + // which we don't wish to bring to the surface. As the queue only holds deliveries + // for 3 days, it's suspected of being an older cloned item if the creation time + // is older than that. - if($update_parent) { - $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ", - dbesc($item['parent_mid']), - intval($item['uid']) - ); + if (intval($item['item_blocked']) === ITEM_MODERATED) { + $update_parent = false; + } - q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d", - dbesc(($z) ? $z[0]['commented'] : datetime_convert()), - dbesc(datetime_convert()), - intval($item['parent']) - ); - } + if ($item['created'] < datetime_convert('', '', 'now - 4 days')) { + $update_parent = false; + } + + if ($update_parent) { + $z = q( + "select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + + q( + "UPDATE item set commented = '%s', changed = '%s' WHERE id = %d", + dbesc(($z) ? $z[0]['commented'] : datetime_convert()), + dbesc(datetime_convert()), + intval($item['parent']) + ); + } } -function send_status_notifications($post_id,$item) { +function send_status_notifications($post_id, $item) +{ - // only send notifications for comments + // only send notifications for comments - if($item['mid'] == $item['parent_mid']) - return; + if ($item['mid'] == $item['parent_mid']) { + return; + } - $notify = false; - $unfollowed = false; + $notify = false; + $unfollowed = false; - $parent = 0; + $parent = 0; - if(array_key_exists('verb',$item) && (activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE))) { + if (array_key_exists('verb', $item) && (activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE))) { + $r = q( + "select id from item where mid = '%s' and uid = %d limit 1", + dbesc($item['thr_parent']), + intval($item['uid']) + ); - $r = q("select id from item where mid = '%s' and uid = %d limit 1", - dbesc($item['thr_parent']), - intval($item['uid']) - ); + $thr_parent_id = $r[0]['id']; + } - $thr_parent_id = $r[0]['id']; - } + $r = q( + "select channel_hash from channel where channel_id = %d limit 1", + intval($item['uid']) + ); + if (! $r) { + return; + } - $r = q("select channel_hash from channel where channel_id = %d limit 1", - intval($item['uid']) - ); - if(! $r) - return; - - // my own post - no notification needed - if($item['author_xchan'] === $r[0]['channel_hash']) - return; + // my own post - no notification needed + if ($item['author_xchan'] === $r[0]['channel_hash']) { + return; + } - // I'm the owner - notify me + // I'm the owner - notify me - if($item['owner_xchan'] === $r[0]['channel_hash']) - $notify = true; + if ($item['owner_xchan'] === $r[0]['channel_hash']) { + $notify = true; + } - // Was I involved in this conversation? + // Was I involved in this conversation? - $x = q("select * from item where parent_mid = '%s' and uid = %d", - dbesc($item['parent_mid']), - intval($item['uid']) - ); - if($x) { - foreach($x as $xx) { - if($xx['author_xchan'] === $r[0]['channel_hash']) { + $x = q( + "select * from item where parent_mid = '%s' and uid = %d", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + if ($x) { + foreach ($x as $xx) { + if ($xx['author_xchan'] === $r[0]['channel_hash']) { + $notify = true; - $notify = true; + // check for an unfollow thread activity - we should probably decode the obj and check the id + // but it will be extremely rare for this to be wrong. - // check for an unfollow thread activity - we should probably decode the obj and check the id - // but it will be extremely rare for this to be wrong. + if ( + ($xx['verb'] === ACTIVITY_IGNORE) + && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO) + && ($xx['parent'] != $xx['id']) + ) { + $unfollowed = true; + } + } + if ($xx['id'] == $xx['parent']) { + $parent = $xx['parent']; + } + } + } - if(($xx['verb'] === ACTIVITY_IGNORE) - && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO) - && ($xx['parent'] != $xx['id'])) - $unfollowed = true; - } - if($xx['id'] == $xx['parent']) { - $parent = $xx['parent']; - } - } - } + if ($unfollowed) { + return; + } - if($unfollowed) - return; + $link = z_root() . '/display/' . gen_link_id($item['mid']); - $link = z_root() . '/display/' . gen_link_id($item['mid']); + $y = q( + "select id from notify where link = '%s' and uid = %d limit 1", + dbesc($link), + intval($item['uid']) + ); - $y = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($link), - intval($item['uid']) - ); + if ($y) { + $notify = false; + } - if ($y) { - $notify = false; - } - - if (intval($item['item_private']) === 2) { - $notify_type = NOTIFY_MAIL; - } - elseif ($item['verb'] === 'Announce') { - $notify_type = NOTIFY_RESHARE; - } - else { - $notify_type = NOTIFY_COMMENT; - } + if (intval($item['item_private']) === 2) { + $notify_type = NOTIFY_MAIL; + } elseif ($item['verb'] === 'Announce') { + $notify_type = NOTIFY_RESHARE; + } else { + $notify_type = NOTIFY_COMMENT; + } - if (! $notify) { - return; - } + if (! $notify) { + return; + } - Enotify::submit(array( - 'type' => $notify_type, - 'from_xchan' => $item['author_xchan'], - 'to_xchan' => $r[0]['channel_hash'], - 'item' => $item, - 'link' => $link, - 'verb' => $item['verb'], - 'otype' => 'item', - 'parent' => $thr_parent_id ? $thr_parent_id : $parent, - 'parent_mid' => $thr_parent_id ? $item['thr_parent'] : $item['parent_mid'] - )); + Enotify::submit(array( + 'type' => $notify_type, + 'from_xchan' => $item['author_xchan'], + 'to_xchan' => $r[0]['channel_hash'], + 'item' => $item, + 'link' => $link, + 'verb' => $item['verb'], + 'otype' => 'item', + 'parent' => $thr_parent_id ? $thr_parent_id : $parent, + 'parent_mid' => $thr_parent_id ? $item['thr_parent'] : $item['parent_mid'] + )); } /** @@ -2567,338 +2686,340 @@ function send_status_notifications($post_id,$item) { * @param int $uid * @param int $item_id */ -function tag_deliver($uid, $item_id) { +function tag_deliver($uid, $item_id) +{ - $role = get_pconfig($uid,'system','permissions_role'); - $rolesettings = PermissionRoles::role_perms($role); - $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; + $role = get_pconfig($uid, 'system', 'permissions_role'); + $rolesettings = PermissionRoles::role_perms($role); + $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; - $is_group = (($channel_type === 'group') ? true : false); - $is_collection = (($channel_type === 'collection') ? true : false); + $is_group = (($channel_type === 'group') ? true : false); + $is_collection = (($channel_type === 'collection') ? true : false); - $mention = false; + $mention = false; - /* - * Fetch stuff we need - a channel and an item - */ + /* + * Fetch stuff we need - a channel and an item + */ - $u = channelx_by_n($uid); - if (! $u) { - return; - } + $u = channelx_by_n($uid); + if (! $u) { + return; + } - $i = q("select * from item where id = %d and uid = %d limit 1", - intval($item_id), - intval($uid) - ); - if (! $i) { - return; - } + $i = q( + "select * from item where id = %d and uid = %d limit 1", + intval($item_id), + intval($uid) + ); + if (! $i) { + return; + } - xchan_query($i,true); - $i = fetch_post_tags($i); + xchan_query($i, true); + $i = fetch_post_tags($i); - $item = array_shift($i); + $item = array_shift($i); - if (intval($item['item_uplink']) && $item['source_xchan'] - && intval($item['item_thread_top']) && ($item['edited'] != $item['created'])) { + if ( + intval($item['item_uplink']) && $item['source_xchan'] + && intval($item['item_thread_top']) && ($item['edited'] != $item['created']) + ) { + // this is an update (edit) to a post which was already processed by us and has a second delivery chain + // Just start the second delivery chain to deliver the updated post + // after resetting ownership and permission bits - // this is an update (edit) to a post which was already processed by us and has a second delivery chain - // Just start the second delivery chain to deliver the updated post - // after resetting ownership and permission bits - - logger('updating edited tag_deliver post for ' . $u['channel_address']); - start_delivery_chain($u, $item, $item_id, 0, false, true); - return; - } + logger('updating edited tag_deliver post for ' . $u['channel_address']); + start_delivery_chain($u, $item, $item_id, 0, false, true); + return; + } - // send mail (DM) notifications here, but only for top level posts. - // followups will be processed by send_status_notifications() - - $mail_notify = false; - if ((! $item['item_wall']) && intval($item['item_thread_top']) && $item['author_xchan'] !== $u['channel_hash'] && intval($item['item_private']) === 2) { - Enotify::submit(array( - 'to_xchan' => $u['channel_hash'], - 'from_xchan' => $item['author_xchan'], - 'type' => NOTIFY_MAIL, - 'item' => $item, - 'link' => $item['llink'], - 'verb' => 'DM', - 'otype' => 'item' - )); - $mail_notify = true; - } + // send mail (DM) notifications here, but only for top level posts. + // followups will be processed by send_status_notifications() - // important - ignore wall posts here else dm's by group owner will be sent to group. + $mail_notify = false; + if ((! $item['item_wall']) && intval($item['item_thread_top']) && $item['author_xchan'] !== $u['channel_hash'] && intval($item['item_private']) === 2) { + Enotify::submit(array( + 'to_xchan' => $u['channel_hash'], + 'from_xchan' => $item['author_xchan'], + 'type' => NOTIFY_MAIL, + 'item' => $item, + 'link' => $item['llink'], + 'verb' => 'DM', + 'otype' => 'item' + )); + $mail_notify = true; + } - if ($is_group && intval($item['item_private']) === 2 && intval($item['item_thread_top']) && (! intval($item['item_wall']))) { - // group delivery via DM - use post_wall permission since send_stream is probably turned off - // and this will be turned into an embedded wall-to-wall post - if(perm_is_allowed($uid,$item['author_xchan'],'post_wall')) { - logger('group DM delivery for ' . $u['channel_address']); - start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); - q("update item set item_blocked = %d where id = %d", - intval(ITEM_HIDDEN), - intval($item_id) - ); - } - return; - } + // important - ignore wall posts here else dm's by group owner will be sent to group. - // Deliver to group via target collection + if ($is_group && intval($item['item_private']) === 2 && intval($item['item_thread_top']) && (! intval($item['item_wall']))) { + // group delivery via DM - use post_wall permission since send_stream is probably turned off + // and this will be turned into an embedded wall-to-wall post + if (perm_is_allowed($uid, $item['author_xchan'], 'post_wall')) { + logger('group DM delivery for ' . $u['channel_address']); + start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + q( + "update item set item_blocked = %d where id = %d", + intval(ITEM_HIDDEN), + intval($item_id) + ); + } + return; + } - if ($is_group && intval($item['item_thread_top']) && (! intval($item['item_wall'])) && (strpos($item['tgt_type'],'Collection') !== false) && $item['target']) { - // group delivery via target - use post_wall permission since send_stream is probably turned off - // and this will be turned into an embedded wall-to-wall post - if (is_array($item['target'])) { - $a = $item['target']; - } - else { - $a = json_decode($item['target'],true); - } - - if ($a) { - $id = ((is_string($a)) ? $a : EMPTY_STR); - if (is_array($a) && isset($a['id'])) { - $id = $a['id']; - } - if ($id == z_root() . '/outbox/' . $u['channel_address']) { - if(perm_is_allowed($uid,$item['author_xchan'],'post_wall')) { - logger('group collection delivery for ' . $u['channel_address']); - start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); - q("update item set item_blocked = %d where id = %d", - intval(ITEM_HIDDEN), - intval($item_id) - ); - } - return; - } - } - } + // Deliver to group via target collection - if ($is_group && intval($item['item_thread_top']) && intval($item['item_wall']) && $item['author_xchan'] !== $item['owner_xchan']) { - if (strpos($item['body'],'[/share]')) { - logger('W2W post already shared'); - return; - } - // group delivery via W2W - logger('rewriting W2W post for ' . $u['channel_address']); - start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); - q("update item set item_wall = 0 where id = %d", - intval($item_id) - ); - return; - } + if ($is_group && intval($item['item_thread_top']) && (! intval($item['item_wall'])) && (strpos($item['tgt_type'], 'Collection') !== false) && $item['target']) { + // group delivery via target - use post_wall permission since send_stream is probably turned off + // and this will be turned into an embedded wall-to-wall post + if (is_array($item['target'])) { + $a = $item['target']; + } else { + $a = json_decode($item['target'], true); + } - /* - * A "union" is a message which our channel has sourced from another channel. - * This sets up a second delivery chain just like forum tags do. - * Find out if this is a source-able post. - */ + if ($a) { + $id = ((is_string($a)) ? $a : EMPTY_STR); + if (is_array($a) && isset($a['id'])) { + $id = $a['id']; + } + if ($id == z_root() . '/outbox/' . $u['channel_address']) { + if (perm_is_allowed($uid, $item['author_xchan'], 'post_wall')) { + logger('group collection delivery for ' . $u['channel_address']); + start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + q( + "update item set item_blocked = %d where id = %d", + intval(ITEM_HIDDEN), + intval($item_id) + ); + } + return; + } + } + } - $union = check_item_source($uid,$item); - if ($union) { - logger('check_item_source returns true'); - } + if ($is_group && intval($item['item_thread_top']) && intval($item['item_wall']) && $item['author_xchan'] !== $item['owner_xchan']) { + if (strpos($item['body'], '[/share]')) { + logger('W2W post already shared'); + return; + } + // group delivery via W2W + logger('rewriting W2W post for ' . $u['channel_address']); + start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + q( + "update item set item_wall = 0 where id = %d", + intval($item_id) + ); + return; + } - // This might be a followup (e.g. comment) to an already uplinked item - // If so setup a second delivery chain + /* + * A "union" is a message which our channel has sourced from another channel. + * This sets up a second delivery chain just like forum tags do. + * Find out if this is a source-able post. + */ - if (! intval($item['item_thread_top'])) { - $x = q("select * from item where id = parent and parent = %d and uid = %d limit 1", - intval($item['parent']), - intval($uid) - ); + $union = check_item_source($uid, $item); + if ($union) { + logger('check_item_source returns true'); + } - if ($x) { + // This might be a followup (e.g. comment) to an already uplinked item + // If so setup a second delivery chain - // group comments don't normally require a second delivery chain - // but we create a linked Announce so they will show up in the home timeline - // on microblog platforms and this creates a second delivery chain - - if ($is_group && intval($x[0]['item_wall'])) { - // don't let the forked delivery chain recurse - if ($item['verb'] === 'Announce' && $item['author_xchan'] === $u['channel_hash']) { - return; - } - // don't boost moderated content until it has been approved - if (intval($item['item_blocked']) === ITEM_MODERATED) { - return; - } - - // don't boost likes and other response activities as it is likely that - // few platforms will handle this in an elegant way - - if (ActivityStreams::is_response_activity($item['verb'])) { - return; - } - logger('group_comment'); - start_delivery_chain($u, $item, $item_id, $x[0], true, (($item['edited'] != $item['created']) || $item['item_deleted'])); - } - elseif (intval($x[0]['item_uplink'])) { - start_delivery_chain($u,$item,$item_id,$x[0]); - } - } - } + if (! intval($item['item_thread_top'])) { + $x = q( + "select * from item where id = parent and parent = %d and uid = %d limit 1", + intval($item['parent']), + intval($uid) + ); + + if ($x) { + // group comments don't normally require a second delivery chain + // but we create a linked Announce so they will show up in the home timeline + // on microblog platforms and this creates a second delivery chain + + if ($is_group && intval($x[0]['item_wall'])) { + // don't let the forked delivery chain recurse + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $u['channel_hash']) { + return; + } + // don't boost moderated content until it has been approved + if (intval($item['item_blocked']) === ITEM_MODERATED) { + return; + } + + // don't boost likes and other response activities as it is likely that + // few platforms will handle this in an elegant way + + if (ActivityStreams::is_response_activity($item['verb'])) { + return; + } + logger('group_comment'); + start_delivery_chain($u, $item, $item_id, $x[0], true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + } elseif (intval($x[0]['item_uplink'])) { + start_delivery_chain($u, $item, $item_id, $x[0]); + } + } + } - /* - * Now we've got those out of the way. Let's see if this is a post that's tagged for re-delivery - */ + /* + * Now we've got those out of the way. Let's see if this is a post that's tagged for re-delivery + */ - $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'],TERM_MENTION) : false); + $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'], TERM_MENTION) : false); - $pterms = ((isset($item['term'])) ? get_terms_oftype($item['term'], [TERM_PCATEGORY, TERM_HASHTAG] ) : false); + $pterms = ((isset($item['term'])) ? get_terms_oftype($item['term'], [TERM_PCATEGORY, TERM_HASHTAG]) : false); - if ($terms) { - logger('Post mentions: ' . print_r($terms,true), LOGGER_DATA); - } - - if ($pterms) { - logger('Post collections: ' . print_r($pterms,true), LOGGER_DATA); - } - - $link = normalise_link($u['xchan_url']); + if ($terms) { + logger('Post mentions: ' . print_r($terms, true), LOGGER_DATA); + } - if ($terms) { - foreach ($terms as $term) { + if ($pterms) { + logger('Post collections: ' . print_r($pterms, true), LOGGER_DATA); + } - if (! link_compare($term['url'],$link)) { - continue; - } + $link = normalise_link($u['xchan_url']); - $mention = true; + if ($terms) { + foreach ($terms as $term) { + if (! link_compare($term['url'], $link)) { + continue; + } - logger('Mention found for ' . $u['channel_name']); + $mention = true; - $r = q("update item set item_mentionsme = 1 where id = %d", - intval($item_id) - ); + logger('Mention found for ' . $u['channel_name']); - // At this point we've determined that the person receiving this post was mentioned in it or it is a union. - // Now let's check if this mention was inside a reshare so we don't spam a forum + $r = q( + "update item set item_mentionsme = 1 where id = %d", + intval($item_id) + ); - $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); + // At this point we've determined that the person receiving this post was mentioned in it or it is a union. + // Now let's check if this mention was inside a reshare so we don't spam a forum - $tagged = false; - $matches = []; + $body = preg_replace('/\[share(.*?)\[\/share\]/', '', $item['body']); - $pattern = '/[\!@]\!?\[[uz]rl\=' . preg_quote($term['url'],'/') . '\](.*?)\[\/[uz]rl\]/'; - if (preg_match($pattern,$body,$matches)) - $tagged = true; + $tagged = false; + $matches = []; - $pattern = '/\[[uz]rl\=' . preg_quote($term['url'],'/') . '\][\!@](.*?)\[\/[uz]rl\]/'; - if (preg_match($pattern,$body,$matches)) - $tagged = true; + $pattern = '/[\!@]\!?\[[uz]rl\=' . preg_quote($term['url'], '/') . '\](.*?)\[\/[uz]rl\]/'; + if (preg_match($pattern, $body, $matches)) { + $tagged = true; + } + + $pattern = '/\[[uz]rl\=' . preg_quote($term['url'], '/') . '\][\!@](.*?)\[\/[uz]rl\]/'; + if (preg_match($pattern, $body, $matches)) { + $tagged = true; + } - if (! $tagged ) { - logger('Mention was in a reshare - ignoring'); - continue; - } + if (! $tagged) { + logger('Mention was in a reshare - ignoring'); + continue; + } - $arr = [ - 'channel_id' => $uid, - 'item' => $item, - 'body' => $body - ]; + $arr = [ + 'channel_id' => $uid, + 'item' => $item, + 'body' => $body + ]; - /** - * @hooks tagged - * Called when a delivery is processed which results in you being tagged. - * * \e number \b channel_id - * * \e array \b item - * * \e string \b body - */ + /** + * @hooks tagged + * Called when a delivery is processed which results in you being tagged. + * * \e number \b channel_id + * * \e array \b item + * * \e string \b body + */ - call_hooks('tagged', $arr); + call_hooks('tagged', $arr); - /** - * post to a group (aka forum) via normal @-mentions *only if* the group is public - * but let the owner change this with a hidden pconfig and either allow - * or deny this option regardless of the type of group - */ - - if ($is_group && intval($item['item_thread_top']) && (! intval($item['item_wall']))) { - if (get_pconfig($uid,'system','post_via_mentions',in_array($role,['forum','forum_moderated'])) && perm_is_allowed($uid,$item['author_xchan'],'post_wall')) { - logger('group mention delivery for ' . $u['channel_address']); - start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); - q("update item set item_blocked = %d where id = %d", - intval(ITEM_HIDDEN), - intval($item_id) - ); - } - } + /** + * post to a group (aka forum) via normal @-mentions *only if* the group is public + * but let the owner change this with a hidden pconfig and either allow + * or deny this option regardless of the type of group + */ - /* - * Send a mention notification - unless we just sent a mail notification for the same item - */ + if ($is_group && intval($item['item_thread_top']) && (! intval($item['item_wall']))) { + if (get_pconfig($uid, 'system', 'post_via_mentions', in_array($role, ['forum','forum_moderated'])) && perm_is_allowed($uid, $item['author_xchan'], 'post_wall')) { + logger('group mention delivery for ' . $u['channel_address']); + start_delivery_chain($u, $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + q( + "update item set item_blocked = %d where id = %d", + intval(ITEM_HIDDEN), + intval($item_id) + ); + } + } - if (! $mail_notify) { - Enotify::submit(array( - 'to_xchan' => $u['channel_hash'], - 'from_xchan' => $item['author_xchan'], - 'type' => NOTIFY_TAGSELF, - 'item' => $item, - 'link' => $item['llink'], - 'verb' => ACTIVITY_TAG, - 'otype' => 'item' - )); - } - } - } - if ($is_collection && $pterms) { - foreach ($pterms as $term) { + /* + * Send a mention notification - unless we just sent a mail notification for the same item + */ - $ptagged = false; + if (! $mail_notify) { + Enotify::submit(array( + 'to_xchan' => $u['channel_hash'], + 'from_xchan' => $item['author_xchan'], + 'type' => NOTIFY_TAGSELF, + 'item' => $item, + 'link' => $item['llink'], + 'verb' => ACTIVITY_TAG, + 'otype' => 'item' + )); + } + } + } + if ($is_collection && $pterms) { + foreach ($pterms as $term) { + $ptagged = false; - if (link_compare($term['url'],$link)) { - $ptagged = true; - } - elseif ($term['ttype'] === TERM_HASHTAG && strtolower($term['term']) === strtolower($u['channel_address'])) { - $ptagged = true; - } - - if (! $ptagged) { - continue; - } + if (link_compare($term['url'], $link)) { + $ptagged = true; + } elseif ($term['ttype'] === TERM_HASHTAG && strtolower($term['term']) === strtolower($u['channel_address'])) { + $ptagged = true; + } - logger('Collection post found for ' . $u['channel_name']); + if (! $ptagged) { + continue; + } - // ptagged - keep going, next check permissions + logger('Collection post found for ' . $u['channel_name']); - if ((! perm_is_allowed($uid,$item['author_xchan'],'write_collection')) && ($item['author_xchan'] !== $u['channel_parent'])) { - logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); - continue; - } + // ptagged - keep going, next check permissions - // tgroup delivery - setup a second delivery chain - // prevent delivery looping - only proceed - // if the message originated elsewhere and is a top-level post + if ((! perm_is_allowed($uid, $item['author_xchan'], 'write_collection')) && ($item['author_xchan'] !== $u['channel_parent'])) { + logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); + continue; + } - if (intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { - logger('Item was local or a comment. rejected.'); - continue; - } + // tgroup delivery - setup a second delivery chain + // prevent delivery looping - only proceed + // if the message originated elsewhere and is a top-level post - logger('Creating second delivery chain.'); - start_delivery_chain($u,$item,$item_id,null); + if (intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { + logger('Item was local or a comment. rejected.'); + continue; + } - } - } + logger('Creating second delivery chain.'); + start_delivery_chain($u, $item, $item_id, null); + } + } - if ($union) { - if (intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { - logger('Item was local or a comment. rejected.'); - return; - } - - logger('Creating second delivery chain.'); - start_delivery_chain($u,$item,$item_id,null); - - } + if ($union) { + if (intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { + logger('Item was local or a comment. rejected.'); + return; + } + logger('Creating second delivery chain.'); + start_delivery_chain($u, $item, $item_id, null); + } } @@ -2915,123 +3036,129 @@ function tag_deliver($uid, $item_id) { * @return bool */ -function tgroup_check($uid, $item) { +function tgroup_check($uid, $item) +{ - $role = get_pconfig($uid,'system','permissions_role'); - $rolesettings = PermissionRoles::role_perms($role); - $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; + $role = get_pconfig($uid, 'system', 'permissions_role'); + $rolesettings = PermissionRoles::role_perms($role); + $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; - $is_group = (($channel_type === 'group') ? true : false); - $is_collection = (($channel_type === 'collection') ? true : false); + $is_group = (($channel_type === 'group') ? true : false); + $is_collection = (($channel_type === 'collection') ? true : false); - // If a comment, check if we have already accepted the top level post as an uplink - // Applies to collections only at this time - // @FIXME We need a comment clause for groups - - if ($item['mid'] !== $item['parent_mid']) { - $r = q("select id from item where mid = '%s' and uid = %d and item_uplink = 1 limit 1", - dbesc($item['parent_mid']), - intval($uid) - ); - if ($r) { - return true; - } - } + // If a comment, check if we have already accepted the top level post as an uplink + // Applies to collections only at this time + // @FIXME We need a comment clause for groups - $u = channelx_by_n($uid); - if (! $u) { - return false; - } + if ($item['mid'] !== $item['parent_mid']) { + $r = q( + "select id from item where mid = '%s' and uid = %d and item_uplink = 1 limit 1", + dbesc($item['parent_mid']), + intval($uid) + ); + if ($r) { + return true; + } + } - // post to group via DM + $u = channelx_by_n($uid); + if (! $u) { + return false; + } - if ($is_group) { - if (intval($item['item_private']) === 2 && $item['mid'] === $item['parent_mid']) { - return true; - } + // post to group via DM - if ($item['mid'] === $item['parent_mid'] && (! intval($item['item_wall'])) && (strpos($item['tgt_type'],'Collection') !== false) && $item['target']) { - // accept posts to collections only if the collection belongs to us - if ((is_string($item['target']) && strpos($item['target'],z_root()) !== false) - || (isset($item['target']['id']) && strpos($item['target']['id'],z_root()) !== false)) { - return true; - } - } + if ($is_group) { + if (intval($item['item_private']) === 2 && $item['mid'] === $item['parent_mid']) { + return true; + } - if (get_pconfig($uid,'system','post_via_mentions',in_array($role, ['forum','forum_moderated'])) && i_am_mentioned($u,$item)) { - return true; - } - } + if ($item['mid'] === $item['parent_mid'] && (! intval($item['item_wall'])) && (strpos($item['tgt_type'], 'Collection') !== false) && $item['target']) { + // accept posts to collections only if the collection belongs to us + if ( + (is_string($item['target']) && strpos($item['target'], z_root()) !== false) + || (isset($item['target']['id']) && strpos($item['target']['id'], z_root()) !== false) + ) { + return true; + } + } - // see if we already have this item. Maybe it is being updated. + if (get_pconfig($uid, 'system', 'post_via_mentions', in_array($role, ['forum','forum_moderated'])) && i_am_mentioned($u, $item)) { + return true; + } + } - $r = q("select id from item where mid = '%s' and uid = %d limit 1", - dbesc($item['mid']), - intval($uid) - ); + // see if we already have this item. Maybe it is being updated. - if ($r) { - return true; - } - - - if (($is_collection) && (perm_is_allowed($uid,$item['author_xchan'],'write_collection') || $item['author_xchan'] === $u['channel_parent'])) { - return true; - } + $r = q( + "select id from item where mid = '%s' and uid = %d limit 1", + dbesc($item['mid']), + intval($uid) + ); - // return true if we are mentioned and we permit delivery of mentions from strangers - - if (PConfig::Get($uid, 'system','permit_all_mentions') && i_am_mentioned($u,$item)) { - return true; - } + if ($r) { + return true; + } - $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'],TERM_HASHTAG) : false); - if ($terms) { - $followed_tags = PConfig::Get($uid,'system','followed_tags'); - if (! (is_array($followed_tags) && $followed_tags)) { - return false; - } - foreach ($terms as $term) { - foreach ($followed_tags as $tag) { - if (strcasecmp($term['term'],$tag) === 0) { - return true; - } - } - } - } + if (($is_collection) && (perm_is_allowed($uid, $item['author_xchan'], 'write_collection') || $item['author_xchan'] === $u['channel_parent'])) { + return true; + } - return false; + // return true if we are mentioned and we permit delivery of mentions from strangers + + if (PConfig::Get($uid, 'system', 'permit_all_mentions') && i_am_mentioned($u, $item)) { + return true; + } + + $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'], TERM_HASHTAG) : false); + if ($terms) { + $followed_tags = PConfig::Get($uid, 'system', 'followed_tags'); + if (! (is_array($followed_tags) && $followed_tags)) { + return false; + } + + foreach ($terms as $term) { + foreach ($followed_tags as $tag) { + if (strcasecmp($term['term'], $tag) === 0) { + return true; + } + } + } + } + + return false; } -function i_am_mentioned($channel,$item) { +function i_am_mentioned($channel, $item) +{ - $link = $channel['xchan_url']; + $link = $channel['xchan_url']; - $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); + $body = preg_replace('/\[share(.*?)\[\/share\]/', '', $item['body']); - $tagged = false; - $matches = []; + $tagged = false; + $matches = []; - $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'],TERM_MENTION) : false); + $terms = ((isset($item['term'])) ? get_terms_oftype($item['term'], TERM_MENTION) : false); - if ($terms) { - foreach ($terms as $term) { - if ($link === $term['url']) { - $pattern = '/[\!@]\!?\[[uz]rl\=' . preg_quote($term['url'],'/') . '\](.*?)\[\/[uz]rl\]/'; - if (preg_match($pattern,$body,$matches)) { - $tagged = true; - } - $pattern = '/\[[uz]rl\=' . preg_quote($term['url'],'/') . '\][\!@](.*?)\[\/[uz]rl\]/'; - if (preg_match($pattern,$body,$matches)) { - $tagged = true; - } - } - } - } - return $tagged; + if ($terms) { + foreach ($terms as $term) { + if ($link === $term['url']) { + $pattern = '/[\!@]\!?\[[uz]rl\=' . preg_quote($term['url'], '/') . '\](.*?)\[\/[uz]rl\]/'; + if (preg_match($pattern, $body, $matches)) { + $tagged = true; + } + $pattern = '/\[[uz]rl\=' . preg_quote($term['url'], '/') . '\][\!@](.*?)\[\/[uz]rl\]/'; + if (preg_match($pattern, $body, $matches)) { + $tagged = true; + } + } + } + } + return $tagged; } @@ -3047,349 +3174,352 @@ function i_am_mentioned($channel,$item) { * @param int $item_id * @param bool $parent */ -function start_delivery_chain($channel, $item, $item_id, $parent, $group = false, $edit = false) { +function start_delivery_chain($channel, $item, $item_id, $parent, $group = false, $edit = false) +{ - // btlogger('start_chain: ' . $channel['channel_id'] . ' item: ' . $item_id); - - $sourced = check_item_source($channel['channel_id'],$item); + // btlogger('start_chain: ' . $channel['channel_id'] . ' item: ' . $item_id); - if ($sourced) { - $r = q("select * from source where src_channel_id = %d and ( src_xchan = '%s' or src_xchan = '*' ) limit 1", - intval($channel['channel_id']), - dbesc(($item['source_xchan']) ? $item['source_xchan'] : $item['owner_xchan']) - ); - if ($r && ! $edit) { - $t = trim($r[0]['src_tag']); - if ($t) { - $tags = explode(',',$t); - if ($tags) { - foreach ($tags as $tt) { - $tt = trim($tt); - if ($tt) { - q("insert into term (uid,oid,otype,ttype,term,url) + $sourced = check_item_source($channel['channel_id'], $item); + + if ($sourced) { + $r = q( + "select * from source where src_channel_id = %d and ( src_xchan = '%s' or src_xchan = '*' ) limit 1", + intval($channel['channel_id']), + dbesc(($item['source_xchan']) ? $item['source_xchan'] : $item['owner_xchan']) + ); + if ($r && ! $edit) { + $t = trim($r[0]['src_tag']); + if ($t) { + $tags = explode(',', $t); + if ($tags) { + foreach ($tags as $tt) { + $tt = trim($tt); + if ($tt) { + q( + "insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", - intval($channel['channel_id']), - intval($item_id), - intval(TERM_OBJ_POST), - intval(TERM_CATEGORY), - dbesc($tt), - dbesc(z_root() . '/channel/' . $channel['channel_address'] . '?f=&cat=' . urlencode($tt)) - ); - } - } - } - } - } + intval($channel['channel_id']), + intval($item_id), + intval(TERM_OBJ_POST), + intval(TERM_CATEGORY), + dbesc($tt), + dbesc(z_root() . '/channel/' . $channel['channel_address'] . '?f=&cat=' . urlencode($tt)) + ); + } + } + } + } + } - // This will change the author to the post owner. Useful for RSS feeds which are to be syndicated - // to federated platforms which can't verify the identity of the author. - // This MAY cause you to run afoul of copyright law. + // This will change the author to the post owner. Useful for RSS feeds which are to be syndicated + // to federated platforms which can't verify the identity of the author. + // This MAY cause you to run afoul of copyright law. - $rewrite_author = intval(get_abconfig($channel['channel_id'],$item['owner_xchan'],'system','rself')); - if ($rewrite_author) { - $item['author_xchan'] = $channel['channel_hash']; + $rewrite_author = intval(get_abconfig($channel['channel_id'], $item['owner_xchan'], 'system', 'rself')); + if ($rewrite_author) { + $item['author_xchan'] = $channel['channel_hash']; - $r = q("update item set author_xchan = '%s' where id = %d", - dbesc($item['author_xchan']), - intval($item_id) - ); - } - } + $r = q( + "update item set author_xchan = '%s' where id = %d", + dbesc($item['author_xchan']), + intval($item_id) + ); + } + } - // This creates an embedded share authored by the group actor. - // The original message is no longer needed and its presence can cause - // confusion so make it hidden. + // This creates an embedded share authored by the group actor. + // The original message is no longer needed and its presence can cause + // confusion so make it hidden. - if ($group && (! $parent)) { + if ($group && (! $parent)) { + $arr = []; - $arr = []; + // hide original message + q( + "update item set item_hidden = 1 where id = %d", + intval($item_id) + ); - // hide original message - q("update item set item_hidden = 1 where id = %d", - intval($item_id) - ); - - if ($edit) { - // process edit or delete action - $r = q("select * from item where source_xchan = '%s' and body like '%s' and uid = %d limit 1", - dbesc($item['owner_xchan']), - dbesc("%message_id='" . $item['mid'] . "'%"), - intval($channel['channel_id']) - ); - if ($r) { - if (intval($item['item_deleted'])) { - drop_item($r[0]['id'],false,DROPITEM_PHASE1); - Run::Summon([ 'Notifier','drop',$r[0]['id'] ]); - return; - } - $arr['id'] = intval($r[0]['id']); - $arr['parent'] = intval($r[0]['parent']); - $arr['mid'] = $r[0]['mid']; - $arr['parent_mid'] = $r[0]['parent_mid']; - $arr['edited'] = datetime_convert(); - } - else { - logger('unable to locate original group post ' . $item['mid']); - return; - } + if ($edit) { + // process edit or delete action + $r = q( + "select * from item where source_xchan = '%s' and body like '%s' and uid = %d limit 1", + dbesc($item['owner_xchan']), + dbesc("%message_id='" . $item['mid'] . "'%"), + intval($channel['channel_id']) + ); + if ($r) { + if (intval($item['item_deleted'])) { + drop_item($r[0]['id'], false, DROPITEM_PHASE1); + Run::Summon([ 'Notifier','drop',$r[0]['id'] ]); + return; + } + $arr['id'] = intval($r[0]['id']); + $arr['parent'] = intval($r[0]['parent']); + $arr['mid'] = $r[0]['mid']; + $arr['parent_mid'] = $r[0]['parent_mid']; + $arr['edited'] = datetime_convert(); + } else { + logger('unable to locate original group post ' . $item['mid']); + return; + } + } else { + $arr['mid'] = item_message_id(); + $arr['parent_mid'] = $arr['mid']; + IConfig::Set($arr, 'activitypub', 'context', str_replace('/item/', '/conversation/', $arr['mid'])); + } - } - else { - $arr['mid'] = item_message_id(); - $arr['parent_mid'] = $arr['mid']; - IConfig::Set($arr,'activitypub','context', str_replace('/item/','/conversation/',$arr['mid'])); - } - - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $channel['channel_id']; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; - // WARNING: the presence of both source_xchan and non-zero item_uplink here will cause a delivery loop - $arr['item_uplink'] = 0; - $arr['source_xchan'] = $item['owner_xchan']; + // WARNING: the presence of both source_xchan and non-zero item_uplink here will cause a delivery loop + $arr['item_uplink'] = 0; + $arr['source_xchan'] = $item['owner_xchan']; - $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); - $arr['item_origin'] = 1; - - $arr['item_wall'] = 1; - $arr['item_thread_top'] = 1; - - $bb = "[share author='" . urlencode($item['author']['xchan_name']). - "' profile='" . $item['author']['xchan_url'] . - "' portable_id='" . $item['author']['xchan_hash'] . - "' avatar='" . $item['author']['xchan_photo_s'] . - "' link='" . $item['plink'] . - "' auth='" . (($item['author']['xchan_network'] === 'zot6') ? 'true' : 'false') . - "' posted='" . $item['created'] . - "' message_id='" . $item['mid'] . - "']"; - if ($item['title']) { - $bb .= '[b]' . $item['title'] . '[/b]' . "\r\n"; - $arr['title'] = $item['title']; - } - $bb .= $item['body']; - $bb .= "[/share]"; + $arr['item_origin'] = 1; - $arr['body'] = $bb; - - // Conversational objects shouldn't be copied, but other objects should. - if (in_array($item['obj_type'], [ 'Image', 'Event', 'Question' ])) { - $arr['obj'] = $item['obj']; - $t = json_decode($arr['obj'],true); - if ($t !== NULL) { - $arr['obj'] = $t; - } - $arr['obj']['content'] = bbcode($bb, [ 'export' => true ]); - $arr['obj']['source']['content'] = $bb; - $arr['obj']['id'] = $arr['mid']; - - if (! array_path_exists('obj/source/mediaType',$arr)) { - $arr['obj']['source']['mediaType'] = 'text/bbcode'; - } - } + $arr['item_wall'] = 1; + $arr['item_thread_top'] = 1; - $arr['tgt_type'] = $item['tgt_type']; - $arr['target'] = $item['target']; - - $arr['term'] = $item['term']; + $bb = "[share author='" . urlencode($item['author']['xchan_name']) . + "' profile='" . $item['author']['xchan_url'] . + "' portable_id='" . $item['author']['xchan_hash'] . + "' avatar='" . $item['author']['xchan_photo_s'] . + "' link='" . $item['plink'] . + "' auth='" . (($item['author']['xchan_network'] === 'zot6') ? 'true' : 'false') . + "' posted='" . $item['created'] . + "' message_id='" . $item['mid'] . + "']"; + if ($item['title']) { + $bb .= '[b]' . $item['title'] . '[/b]' . "\r\n"; + $arr['title'] = $item['title']; + } + $bb .= $item['body']; + $bb .= "[/share]"; - $arr['author_xchan'] = $channel['channel_hash']; - $arr['owner_xchan'] = $channel['channel_hash']; + $arr['body'] = $bb; - $arr['obj_type'] = $item['obj_type']; + // Conversational objects shouldn't be copied, but other objects should. + if (in_array($item['obj_type'], [ 'Image', 'Event', 'Question' ])) { + $arr['obj'] = $item['obj']; + $t = json_decode($arr['obj'], true); + if ($t !== null) { + $arr['obj'] = $t; + } + $arr['obj']['content'] = bbcode($bb, [ 'export' => true ]); + $arr['obj']['source']['content'] = $bb; + $arr['obj']['id'] = $arr['mid']; - $arr['verb'] = 'Create'; - - $arr['item_restrict'] = 1; + if (! array_path_exists('obj/source/mediaType', $arr)) { + $arr['obj']['source']['mediaType'] = 'text/bbcode'; + } + } - $arr['allow_cid'] = $channel['channel_allow_cid']; - $arr['allow_gid'] = $channel['channel_allow_gid']; - $arr['deny_cid'] = $channel['channel_deny_cid']; - $arr['deny_gid'] = $channel['channel_deny_gid']; - $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments')); + $arr['tgt_type'] = $item['tgt_type']; + $arr['target'] = $item['target']; - $arr['replyto'] = z_root() . '/channel/' . $channel['channel_address']; + $arr['term'] = $item['term']; - if ($arr['id']) { - $post = item_store_update($arr); - } - else { - $post = item_store($arr); - } + $arr['author_xchan'] = $channel['channel_hash']; + $arr['owner_xchan'] = $channel['channel_hash']; - $post_id = $post['item_id']; + $arr['obj_type'] = $item['obj_type']; - if($post_id) { - Run::Summon([ 'Notifier','tgroup',$post_id ]); - } + $arr['verb'] = 'Create'; - q("update channel set channel_lastpost = '%s' where channel_id = %d", - dbesc(datetime_convert()), - intval($channel['channel_id']) - ); + $arr['item_restrict'] = 1; - return; - } + $arr['allow_cid'] = $channel['channel_allow_cid']; + $arr['allow_gid'] = $channel['channel_allow_gid']; + $arr['deny_cid'] = $channel['channel_deny_cid']; + $arr['deny_gid'] = $channel['channel_deny_gid']; + $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'post_comments')); + + $arr['replyto'] = z_root() . '/channel/' . $channel['channel_address']; + + if ($arr['id']) { + $post = item_store_update($arr); + } else { + $post = item_store($arr); + } + + $post_id = $post['item_id']; + + if ($post_id) { + Run::Summon([ 'Notifier','tgroup',$post_id ]); + } + + q( + "update channel set channel_lastpost = '%s' where channel_id = %d", + dbesc(datetime_convert()), + intval($channel['channel_id']) + ); + + return; + } - // Send Announce activities for group comments so they will show up in microblog streams + // Send Announce activities for group comments so they will show up in microblog streams - if ($group && $parent) { - logger('comment arrived in group', LOGGER_DEBUG); - $arr = []; + if ($group && $parent) { + logger('comment arrived in group', LOGGER_DEBUG); + $arr = []; - // don't let this recurse. We checked for this before calling, but this ensures - // it doesn't sneak through another way because recursion is nasty. - - if ($item['verb'] === 'Announce' && $item['author_xchan'] === $channel['channel_hash']) { - return; - } + // don't let this recurse. We checked for this before calling, but this ensures + // it doesn't sneak through another way because recursion is nasty. - // Don't send Announce activities for poll responses. - - if ($item['obj_type'] === 'Answer') { - return; - } + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $channel['channel_hash']) { + return; + } - if ($edit) { - if (intval($item['item_deleted'])) { - drop_item($item['id'],false,DROPITEM_PHASE1); - Run::Summon([ 'Notifier','drop',$item['id'] ]); - return; - } - return; - } - else { - $arr['mid'] = item_message_id(); - $arr['parent_mid'] = $item['parent_mid']; - IConfig::Set($arr,'activitypub','context', str_replace('/item/','/conversation/',$item['parent_mid'])); - } - - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $channel['channel_id']; + // Don't send Announce activities for poll responses. - $arr['verb'] = 'Announce'; + if ($item['obj_type'] === 'Answer') { + return; + } - if (is_array($item['obj'])) { - $arr['obj'] = $item['obj']; - } - elseif (is_string($item['obj']) && strlen($item['obj'])) { - $arr['obj'] = json_decode($item['obj'],true); - } - - if (! $arr['obj']) { - $arr['obj'] = $item['mid']; - } + if ($edit) { + if (intval($item['item_deleted'])) { + drop_item($item['id'], false, DROPITEM_PHASE1); + Run::Summon([ 'Notifier','drop',$item['id'] ]); + return; + } + return; + } else { + $arr['mid'] = item_message_id(); + $arr['parent_mid'] = $item['parent_mid']; + IConfig::Set($arr, 'activitypub', 'context', str_replace('/item/', '/conversation/', $item['parent_mid'])); + } - if (is_array($arr['obj'])) { - $obj_actor = ((isset($arr['obj']['actor'])) ? $arr['obj']['actor'] : $arr['obj']['attributedTo']); - $mention = Activity::get_actor_bbmention($obj_actor); - $arr['body'] = sprintf( t('🔁 Repeated %1$s\'s %2$s'), $mention, $arr['obj']['type']); - } + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; - $arr['author_xchan'] = $channel['channel_hash']; + $arr['verb'] = 'Announce'; - $arr['item_wall'] = 1; + if (is_array($item['obj'])) { + $arr['obj'] = $item['obj']; + } elseif (is_string($item['obj']) && strlen($item['obj'])) { + $arr['obj'] = json_decode($item['obj'], true); + } - $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + if (! $arr['obj']) { + $arr['obj'] = $item['mid']; + } - $arr['item_origin'] = 1; - - $arr['item_thread_top'] = 0; - - $arr['allow_cid'] = $channel['channel_allow_cid']; - $arr['allow_gid'] = $channel['channel_allow_gid']; - $arr['deny_cid'] = $channel['channel_deny_cid']; - $arr['deny_gid'] = $channel['channel_deny_gid']; - $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments')); + if (is_array($arr['obj'])) { + $obj_actor = ((isset($arr['obj']['actor'])) ? $arr['obj']['actor'] : $arr['obj']['attributedTo']); + $mention = Activity::get_actor_bbmention($obj_actor); + $arr['body'] = sprintf(t('🔁 Repeated %1$s\'s %2$s'), $mention, $arr['obj']['type']); + } - $arr['replyto'] = z_root() . '/channel/' . $channel['channel_address']; + $arr['author_xchan'] = $channel['channel_hash']; + + $arr['item_wall'] = 1; + + $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + + $arr['item_origin'] = 1; + + $arr['item_thread_top'] = 0; + + $arr['allow_cid'] = $channel['channel_allow_cid']; + $arr['allow_gid'] = $channel['channel_allow_gid']; + $arr['deny_cid'] = $channel['channel_deny_cid']; + $arr['deny_gid'] = $channel['channel_deny_gid']; + $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'post_comments')); + + $arr['replyto'] = z_root() . '/channel/' . $channel['channel_address']; - $post = item_store($arr); - $post_id = $post['item_id']; + $post = item_store($arr); + $post_id = $post['item_id']; - if ($post_id) { - Run::Summon([ 'Notifier','tgroup',$post_id ]); - } + if ($post_id) { + Run::Summon([ 'Notifier','tgroup',$post_id ]); + } - q("update channel set channel_lastpost = '%s' where channel_id = %d", - dbesc(datetime_convert()), - intval($channel['channel_id']) - ); + q( + "update channel set channel_lastpost = '%s' where channel_id = %d", + dbesc(datetime_convert()), + intval($channel['channel_id']) + ); - return; - } + return; + } - // Change this copy of the post to a forum head message and deliver to all the tgroup members - // also reset all the privacy bits to the forum default permissions + // Change this copy of the post to a forum head message and deliver to all the tgroup members + // also reset all the privacy bits to the forum default permissions - $private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + $private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); - // Setting item_origin on a deleted item also seems to cause looping - if (! intval($arr['item_deleted'])) { - $arr['item_origin'] = 1; - } + // Setting item_origin on a deleted item also seems to cause looping + if (! intval($arr['item_deleted'])) { + $arr['item_origin'] = 1; + } - $item_wall = 1; - $item_uplink = 0; - $item_nocomment = 0; + $item_wall = 1; + $item_uplink = 0; + $item_nocomment = 0; - $flag_bits = $item['item_flags']; + $flag_bits = $item['item_flags']; - // maintain the original source, which will be the original item owner and was stored in source_xchan - // when we created the delivery fork + // maintain the original source, which will be the original item owner and was stored in source_xchan + // when we created the delivery fork - if ($parent) { - $r = q("update item set source_xchan = '%s' where id = %d", - dbesc($parent['source_xchan']), - intval($item_id) - ); - } - else { - $item_uplink = 1; - if (! $edit) { - $r = q("update item set source_xchan = owner_xchan where id = %d", - intval($item_id) - ); - } - } + if ($parent) { + $r = q( + "update item set source_xchan = '%s' where id = %d", + dbesc($parent['source_xchan']), + intval($item_id) + ); + } else { + $item_uplink = 1; + if (! $edit) { + $r = q( + "update item set source_xchan = owner_xchan where id = %d", + intval($item_id) + ); + } + } - $title = $item['title']; - $body = $item['body']; + $title = $item['title']; + $body = $item['body']; - $r = q("update item set item_uplink = %d, item_nocomment = %d, item_flags = %d, owner_xchan = '%s', replyto = '%s', allow_cid = '%s', allow_gid = '%s', + $r = q( + "update item set item_uplink = %d, item_nocomment = %d, item_flags = %d, owner_xchan = '%s', replyto = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d, comment_policy = '%s', title = '%s', body = '%s', item_wall = %d, item_origin = %d where id = %d", - intval($item_uplink), - intval($item_nocomment), - intval($flag_bits), - dbesc($channel['channel_hash']), - dbesc(channel_url($channel)), - dbesc($channel['channel_allow_cid']), - dbesc($channel['channel_allow_gid']), - dbesc($channel['channel_deny_cid']), - dbesc($channel['channel_deny_gid']), - intval($private), - dbesc(map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'))), - dbesc($title), - dbesc($body), - intval($item_wall), - intval($item_origin), - intval($item_id) - ); + intval($item_uplink), + intval($item_nocomment), + intval($flag_bits), + dbesc($channel['channel_hash']), + dbesc(channel_url($channel)), + dbesc($channel['channel_allow_cid']), + dbesc($channel['channel_allow_gid']), + dbesc($channel['channel_deny_cid']), + dbesc($channel['channel_deny_gid']), + intval($private), + dbesc(map_scope(PermissionLimits::Get($channel['channel_id'], 'post_comments'))), + dbesc($title), + dbesc($body), + intval($item_wall), + intval($item_origin), + intval($item_id) + ); - if ($r) { - Run::Summon([ 'Notifier','tgroup',$item_id ]); - } - else { - logger('start_delivery_chain: failed to update item'); - // reset the source xchan to prevent loops - $r = q("update item set source_xchan = '' where id = %d", - intval($item_id) - ); - } + if ($r) { + Run::Summon([ 'Notifier','tgroup',$item_id ]); + } else { + logger('start_delivery_chain: failed to update item'); + // reset the source xchan to prevent loops + $r = q( + "update item set source_xchan = '' where id = %d", + intval($item_id) + ); + } } /** @@ -3402,139 +3532,149 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false * @param int $uid * @param array $item */ -function check_item_source($uid, $item) { +function check_item_source($uid, $item) +{ - logger('source: uid: ' . $uid, LOGGER_DEBUG); - $xchan = ((isset($item['source_xchan']) && $item['source_xchan'] && isset($item['item_uplink']) && intval($item['item_uplink'])) ? $item['source_xchan'] : $item['owner_xchan']); + logger('source: uid: ' . $uid, LOGGER_DEBUG); + $xchan = ((isset($item['source_xchan']) && $item['source_xchan'] && isset($item['item_uplink']) && intval($item['item_uplink'])) ? $item['source_xchan'] : $item['owner_xchan']); - $r = q("select * from source where src_channel_id = %d and ( src_xchan = '%s' or src_xchan = '*' ) limit 1", - intval($uid), - dbesc($xchan) - ); + $r = q( + "select * from source where src_channel_id = %d and ( src_xchan = '%s' or src_xchan = '*' ) limit 1", + intval($uid), + dbesc($xchan) + ); - if (! $r) { - logger('source: no source record for this channel and source', LOGGER_DEBUG); - return false; - } + if (! $r) { + logger('source: no source record for this channel and source', LOGGER_DEBUG); + return false; + } - $x = q("select abook_feed from abook where abook_channel = %d and abook_xchan = '%s' limit 1", - intval($uid), - dbesc($xchan) - ); + $x = q( + "select abook_feed from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + intval($uid), + dbesc($xchan) + ); - if (! $x) { - logger('source: not connected to this channel.'); - return false; - } + if (! $x) { + logger('source: not connected to this channel.'); + return false; + } - if (! their_perms_contains($uid,$xchan,'republish')) { - logger('source: no republish permission'); - return false; - } + if (! their_perms_contains($uid, $xchan, 'republish')) { + logger('source: no republish permission'); + return false; + } - if ($item['item_private'] && (! intval($x[0]['abook_feed']))) { - logger('source: item is private'); - return false; - } + if ($item['item_private'] && (! intval($x[0]['abook_feed']))) { + logger('source: item is private'); + return false; + } - if ($r[0]['src_channel_xchan'] === $xchan) { - logger('source: cannot source yourself'); - return false; - } + if ($r[0]['src_channel_xchan'] === $xchan) { + logger('source: cannot source yourself'); + return false; + } - if (! $r[0]['src_patt']) { - logger('source: success'); - return true; - } + if (! $r[0]['src_patt']) { + logger('source: success'); + return true; + } - if (MessageFilter::evaluate($item, $r[0]['src_patt'], EMPTY_STR)) { - logger('source: text filter success'); - return true; - } + if (MessageFilter::evaluate($item, $r[0]['src_patt'], EMPTY_STR)) { + logger('source: text filter success'); + return true; + } - logger('source: filter fail'); - return false; + logger('source: filter fail'); + return false; } // Checks an incoming item against the per-channel and per-connection content filter. // This implements the backend of the 'Content Filter' system app -function post_is_importable($channel_id,$item,$abook) { +function post_is_importable($channel_id, $item, $abook) +{ - if (! $item) { - return false; - } + if (! $item) { + return false; + } - if (! Apps::system_app_installed($channel_id,'Content Filter')) { - return true; - } + if (! Apps::system_app_installed($channel_id, 'Content Filter')) { + return true; + } - $incl = PConfig::get($channel_id,'system','message_filter_incl',EMPTY_STR); - $excl = PConfig::get($channel_id,'system','message_filter_excl',EMPTY_STR); - if ($incl || $excl) { - $x = MessageFilter::evaluate($item,$incl,$excl); - if (! $x) { - logger('MessageFilter: channel blocked content',LOGGER_DEBUG,LOG_INFO); - return false; - } - } + $incl = PConfig::get($channel_id, 'system', 'message_filter_incl', EMPTY_STR); + $excl = PConfig::get($channel_id, 'system', 'message_filter_excl', EMPTY_STR); + if ($incl || $excl) { + $x = MessageFilter::evaluate($item, $incl, $excl); + if (! $x) { + logger('MessageFilter: channel blocked content', LOGGER_DEBUG, LOG_INFO); + return false; + } + } - if (! $abook) { - return true; - } - - foreach ($abook as $ab) { - // check eligibility - if (intval($ab['abook_self'])) { - continue; - } - if (! ($ab['abook_incl'] || $ab['abook_excl']) ) { - continue; - } + if (! $abook) { + return true; + } - $evaluator = MessageFilter::evaluate($item,$ab['abook_incl'],$ab['abook_excl']); - // A negative assessment for any individual connections - // is an instant fail - if (! $evaluater) { - return false; - } - } - return true; + foreach ($abook as $ab) { + // check eligibility + if (intval($ab['abook_self'])) { + continue; + } + if (! ($ab['abook_incl'] || $ab['abook_excl'])) { + continue; + } + + $evaluator = MessageFilter::evaluate($item, $ab['abook_incl'], $ab['abook_excl']); + // A negative assessment for any individual connections + // is an instant fail + if (! $evaluater) { + return false; + } + } + return true; } -function has_permissions($obj) { - if((isset($ob['allow_cid']) && $obj['allow_cid'] != '') - || (isset($obj['allow_gid']) && $obj['allow_gid'] != '') - || (isset($obj['deny_cid']) && $obj['deny_cid'] != '') - || (isset($obj['deny_gid']) && $obj['deny_gid'] != '')) { - return true; - } +function has_permissions($obj) +{ + if ( + (isset($ob['allow_cid']) && $obj['allow_cid'] != '') + || (isset($obj['allow_gid']) && $obj['allow_gid'] != '') + || (isset($obj['deny_cid']) && $obj['deny_cid'] != '') + || (isset($obj['deny_gid']) && $obj['deny_gid'] != '') + ) { + return true; + } - return false; + return false; } -function compare_permissions($obj1,$obj2) { - // first part is easy. Check that these are exactly the same. - if (($obj1['allow_cid'] == $obj2['allow_cid']) - && ($obj1['allow_gid'] == $obj2['allow_gid']) - && ($obj1['deny_cid'] == $obj2['deny_cid']) - && ($obj1['deny_gid'] == $obj2['deny_gid'])) { - return true; - } +function compare_permissions($obj1, $obj2) +{ + // first part is easy. Check that these are exactly the same. + if ( + ($obj1['allow_cid'] == $obj2['allow_cid']) + && ($obj1['allow_gid'] == $obj2['allow_gid']) + && ($obj1['deny_cid'] == $obj2['deny_cid']) + && ($obj1['deny_gid'] == $obj2['deny_gid']) + ) { + return true; + } - // This is harder. Parse all the permissions and compare the resulting set. + // This is harder. Parse all the permissions and compare the resulting set. - $recipients1 = enumerate_permissions($obj1); - $recipients2 = enumerate_permissions($obj2); - sort($recipients1); - sort($recipients2); - if ($recipients1 == $recipients2) { - return true; - } - return false; + $recipients1 = enumerate_permissions($obj1); + $recipients2 = enumerate_permissions($obj2); + sort($recipients1); + sort($recipients2); + if ($recipients1 == $recipients2) { + return true; + } + return false; } /** @@ -3543,105 +3683,109 @@ function compare_permissions($obj1,$obj2) { * @param object $obj * @return array */ -function enumerate_permissions($obj) { +function enumerate_permissions($obj) +{ - $allow_people = expand_acl($obj['allow_cid']); - $allow_groups = AccessList::expand(expand_acl($obj['allow_gid'])); - $deny_people = expand_acl($obj['deny_cid']); - $deny_groups = AccessList::expand(expand_acl($obj['deny_gid'])); - $recipients = array_unique(array_merge($allow_people,$allow_groups)); - $deny = array_unique(array_merge($deny_people,$deny_groups)); - $recipients = array_diff($recipients,$deny); + $allow_people = expand_acl($obj['allow_cid']); + $allow_groups = AccessList::expand(expand_acl($obj['allow_gid'])); + $deny_people = expand_acl($obj['deny_cid']); + $deny_groups = AccessList::expand(expand_acl($obj['deny_gid'])); + $recipients = array_unique(array_merge($allow_people, $allow_groups)); + $deny = array_unique(array_merge($deny_people, $deny_groups)); + $recipients = array_diff($recipients, $deny); - return $recipients; + return $recipients; } -function item_getfeedtags($item) { +function item_getfeedtags($item) +{ - $ret = []; - if (! (isset($item['term']) && is_array($item['term']))) { - return $ret; - } - - $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_COMMUNITYTAG)); + $ret = []; + if (! (isset($item['term']) && is_array($item['term']))) { + return $ret; + } - if (count($terms)) { - foreach ($terms as $term) { - if (($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) { - $ret[] = array('#',$term['url'],$term['term']); - } - else { - $ret[] = array('@',$term['url'],$term['term']); - } - } - } + $terms = get_terms_oftype($item['term'], array(TERM_HASHTAG,TERM_MENTION,TERM_COMMUNITYTAG)); - return $ret; + if (count($terms)) { + foreach ($terms as $term) { + if (($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) { + $ret[] = array('#',$term['url'],$term['term']); + } else { + $ret[] = array('@',$term['url'],$term['term']); + } + } + } + + return $ret; } // generates an Atom feed representation of any attachmments to this item -function item_getfeedattach($item) { +function item_getfeedattach($item) +{ - $ret = EMPTY_STR; + $ret = EMPTY_STR; - if (! isset($item['attach'])) { - return $ret; - } - $arr = explode(',',$item['attach']); - if ($arr && count($arr)) { - foreach ($arr as $r) { - $matches = false; - $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches); - if ($cnt) { - $ret .= ' set deleted flag on the item and perform intial notifications // $stage = 2 => perform low level delete at a later stage -function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = false) { +function drop_item($id, $interactive = true, $stage = DROPITEM_NORMAL, $force = false) +{ - // These resource types have linked items that should only be removed at the same time - // as the linked resource; if we encounter one set it to item_hidden rather than item_deleted. + // These resource types have linked items that should only be removed at the same time + // as the linked resource; if we encounter one set it to item_hidden rather than item_deleted. - $linked_resource_types = [ 'photo' ]; + $linked_resource_types = [ 'photo' ]; - // locate item to be deleted + // locate item to be deleted - $r = q("SELECT * FROM item WHERE id = %d LIMIT 1", - intval($id) - ); + $r = q( + "SELECT * FROM item WHERE id = %d LIMIT 1", + intval($id) + ); - if ((! $r) || (intval($r[0]['item_deleted']) && ($stage === DROPITEM_NORMAL))) { - if (! $interactive) { - return 0; - } - notice( t('Item not found.') . EOL); - goaway(z_root() . '/' . $_SESSION['return_url']); - } + if ((! $r) || (intval($r[0]['item_deleted']) && ($stage === DROPITEM_NORMAL))) { + if (! $interactive) { + return 0; + } + notice(t('Item not found.') . EOL); + goaway(z_root() . '/' . $_SESSION['return_url']); + } - $item = $r[0]; + $item = $r[0]; - // logger('dropped_item: ' . print_r($item,true),LOGGER_ALL); + // logger('dropped_item: ' . print_r($item,true),LOGGER_ALL); - $ok_to_delete = false; + $ok_to_delete = false; - // system deletion - if (! $interactive) { - $ok_to_delete = true; - } + // system deletion + if (! $interactive) { + $ok_to_delete = true; + } - // admin deletion - - if (is_site_admin()) { - $ok_to_delete = true; - } + // admin deletion - // owner deletion - if (local_channel() && local_channel() == $item['uid']) { - $ok_to_delete = true; - } + if (is_site_admin()) { + $ok_to_delete = true; + } + + // owner deletion + if (local_channel() && local_channel() == $item['uid']) { + $ok_to_delete = true; + } - // author deletion - $observer = App::get_observer(); - if ($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['author_xchan'])) { - $ok_to_delete = true; - } + // author deletion + $observer = App::get_observer(); + if ($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['author_xchan'])) { + $ok_to_delete = true; + } - if ($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['owner_xchan'])) { - $ok_to_delete = true; - } + if ($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['owner_xchan'])) { + $ok_to_delete = true; + } - if ($ok_to_delete) { - - $r = q("UPDATE item SET item_deleted = 1 WHERE id = %d", - intval($item['id']) - ); + if ($ok_to_delete) { + $r = q( + "UPDATE item SET item_deleted = 1 WHERE id = %d", + intval($item['id']) + ); - if ($item['resource_type'] === 'event' ) { - q("delete from event where event_hash = '%s' and uid = %d", - dbesc($item['resource_id']), - intval($item['uid']) - ); - } + if ($item['resource_type'] === 'event') { + q( + "delete from event where event_hash = '%s' and uid = %d", + dbesc($item['resource_id']), + intval($item['uid']) + ); + } - if ($item['resource_type'] === 'photo' ) { - attach_delete($item['uid'],$item['resource_id'],true); - } + if ($item['resource_type'] === 'photo') { + attach_delete($item['uid'], $item['resource_id'], true); + } - $arr = [ - 'item' => $item, - 'interactive' => $interactive, - 'stage' => $stage - ]; - /** - * @hooks drop_item - * Called when an 'item' is removed. - */ - call_hooks('drop_item', $arr); + $arr = [ + 'item' => $item, + 'interactive' => $interactive, + 'stage' => $stage + ]; + /** + * @hooks drop_item + * Called when an 'item' is removed. + */ + call_hooks('drop_item', $arr); - $notify_id = intval($item['id']); + $notify_id = intval($item['id']); - $items = q("select * from item where parent = %d and uid = %d", - intval($item['id']), - intval($item['uid']) - ); - if ($items) { - foreach ($items as $i) { - delete_item_lowlevel($i,$stage,$force); - } - } - else { - delete_item_lowlevel($item,$stage,$force); - } + $items = q( + "select * from item where parent = %d and uid = %d", + intval($item['id']), + intval($item['uid']) + ); + if ($items) { + foreach ($items as $i) { + delete_item_lowlevel($i, $stage, $force); + } + } else { + delete_item_lowlevel($item, $stage, $force); + } - if (! $interactive) { - return 1; - } + if (! $interactive) { + return 1; + } - // send the notification upstream/downstream as the case may be - // only send notifications to others if this is the owner's wall item. + // send the notification upstream/downstream as the case may be + // only send notifications to others if this is the owner's wall item. - // This isn't optimal. We somehow need to pass to this function whether or not - // to call the notifier, or we need to call the notifier from the calling function. - // We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only - // set if we know we're going to send delete notifications out to others. + // This isn't optimal. We somehow need to pass to this function whether or not + // to call the notifier, or we need to call the notifier from the calling function. + // We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only + // set if we know we're going to send delete notifications out to others. - if ((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) { - Run::Summon([ 'Notifier','drop',$notify_id ]); - } + if ((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) { + Run::Summon([ 'Notifier','drop',$notify_id ]); + } - goaway(z_root() . '/' . $_SESSION['return_url']); - } - else { - if (! $interactive) { - return 0; - } - notice( t('Permission denied.') . EOL); - goaway(z_root() . '/' . $_SESSION['return_url']); - } + goaway(z_root() . '/' . $_SESSION['return_url']); + } else { + if (! $interactive) { + return 0; + } + notice(t('Permission denied.') . EOL); + goaway(z_root() . '/' . $_SESSION['return_url']); + } } /** @@ -3863,83 +4010,93 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal * @param bool $force * @return bool */ -function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { +function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) +{ - logger('item: ' . $item['id'] . ' stage: ' . $stage . ' force: ' . $force, LOGGER_DATA); + logger('item: ' . $item['id'] . ' stage: ' . $stage . ' force: ' . $force, LOGGER_DATA); - switch($stage) { - case DROPITEM_PHASE2: - $r = q("UPDATE item SET item_pending_remove = 1, body = '', title = '', + switch ($stage) { + case DROPITEM_PHASE2: + $r = q( + "UPDATE item SET item_pending_remove = 1, body = '', title = '', changed = '%s', edited = '%s' WHERE id = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item['id']) - ); - break; + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); + break; - case DROPITEM_PHASE1: - $r = q("UPDATE item set item_deleted = 1, changed = '%s', edited = '%s' where id = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item['id']) - ); + case DROPITEM_PHASE1: + $r = q( + "UPDATE item set item_deleted = 1, changed = '%s', edited = '%s' where id = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); - break; + break; - case DROPITEM_NORMAL: - default: - $r = q("DELETE FROM item WHERE id = %d", - intval($item['id']) - ); - break; - } + case DROPITEM_NORMAL: + default: + $r = q( + "DELETE FROM item WHERE id = %d", + intval($item['id']) + ); + break; + } - // immediately remove any undesired profile likes. + // immediately remove any undesired profile likes. - q("delete from likes where iid = %d and channel_id = %d", - intval($item['id']), - intval($item['uid']) - ); + q( + "delete from likes where iid = %d and channel_id = %d", + intval($item['id']), + intval($item['uid']) + ); - // remove delivery reports + // remove delivery reports - $c = q("select channel_hash from channel where channel_id = %d limit 1", - intval($item['uid']) - ); - if ($c) { - q("delete from dreport where dreport_xchan = '%s' and dreport_mid = '%s'", - dbesc($c[0]['channel_hash']), - dbesc($item['mid']) - ); - } + $c = q( + "select channel_hash from channel where channel_id = %d limit 1", + intval($item['uid']) + ); + if ($c) { + q( + "delete from dreport where dreport_xchan = '%s' and dreport_mid = '%s'", + dbesc($c[0]['channel_hash']), + dbesc($item['mid']) + ); + } - // network deletion request. Keep the message structure so that we can deliver delete notifications. - // Come back after several days (or perhaps a month) to do the lowlevel delete (DROPITEM_PHASE2). + // network deletion request. Keep the message structure so that we can deliver delete notifications. + // Come back after several days (or perhaps a month) to do the lowlevel delete (DROPITEM_PHASE2). - if ($stage == DROPITEM_PHASE1) { - return true; - } + if ($stage == DROPITEM_PHASE1) { + return true; + } - $r = q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_POST), - intval($item['id']) - ); + $r = q( + "delete from term where otype = %d and oid = %d", + intval(TERM_OBJ_POST), + intval($item['id']) + ); - q("delete from iconfig where iid = %d", - intval($item['id']) - ); + q( + "delete from iconfig where iid = %d", + intval($item['id']) + ); - q("delete from term where oid = %d and otype = %d", - intval($item['id']), - intval(TERM_OBJ_POST) - ); + q( + "delete from term where oid = %d and otype = %d", + intval($item['id']), + intval(TERM_OBJ_POST) + ); - ThreadListener::delete_by_target($item['mid']); + ThreadListener::delete_by_target($item['mid']); - /** @FIXME remove notifications for this item */ + /** @FIXME remove notifications for this item */ - return true; + return true; } /** @@ -3949,35 +4106,37 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { * @param bool $wall (optional) no longer used * @return string|bool date string, otherwise false */ -function first_post_date($uid, $wall = false) { +function first_post_date($uid, $wall = false) +{ - $sql_extra = ''; + $sql_extra = ''; - switch (App::$module) { - case 'articles': - $sql_extra .= " and item_type = 7 "; - $item_normal = " and item.item_hidden = 0 and item.item_type = 7 and item.item_deleted = 0 + switch (App::$module) { + case 'articles': + $sql_extra .= " and item_type = 7 "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 7 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 "; - break; - case 'channel': - $sql_extra = " and item_wall = 1 "; - default: - $item_normal = item_normal(); - break; - } + break; + case 'channel': + $sql_extra = " and item_wall = 1 "; + default: + $item_normal = item_normal(); + break; + } - $r = q("select id, created from item + $r = q( + "select id, created from item where uid = %d and id = parent $item_normal $sql_extra order by created asc limit 1", - intval($uid) - ); + intval($uid) + ); - if ($r) { - return datetime_convert('UTC',date_default_timezone_get(),$r[0]['created'], 'Y-m-d'); - } + if ($r) { + return datetime_convert('UTC', date_default_timezone_get(), $r[0]['created'], 'Y-m-d'); + } - return false; + return false; } /** @@ -3990,88 +4149,89 @@ function first_post_date($uid, $wall = false) { * @param string $mindate * @return array */ -function list_post_dates($uid, $wall, $mindate) { +function list_post_dates($uid, $wall, $mindate) +{ - $ret = []; + $ret = []; - $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d'); + $dnow = datetime_convert('', date_default_timezone_get(), 'now', 'Y-m-d'); - if ($mindate) { - $dthen = datetime_convert('',date_default_timezone_get(), $mindate); - } - else { - $dthen = first_post_date($uid, $wall); - } - if (! $dthen) { - return []; - } + if ($mindate) { + $dthen = datetime_convert('', date_default_timezone_get(), $mindate); + } else { + $dthen = first_post_date($uid, $wall); + } + if (! $dthen) { + return []; + } - // If it's near the end of a long month, backup to the 28th so that in - // consecutive loops we'll always get a whole month difference. + // If it's near the end of a long month, backup to the 28th so that in + // consecutive loops we'll always get a whole month difference. - if (intval(substr($dnow,8)) > 28) { - $dnow = substr($dnow,0,8) . '28'; - } - if (intval(substr($dthen,8)) > 28) { - $dthen = substr($dthen,0,8) . '28'; - } + if (intval(substr($dnow, 8)) > 28) { + $dnow = substr($dnow, 0, 8) . '28'; + } + if (intval(substr($dthen, 8)) > 28) { + $dthen = substr($dthen, 0, 8) . '28'; + } - // Starting with the current month, get the first and last days of every - // month down to and including the month of the first post + // Starting with the current month, get the first and last days of every + // month down to and including the month of the first post - while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) { - $dyear = intval(substr($dnow,0,4)); - $dstart = substr($dnow,0,8) . '01'; - $dend = substr($dnow,0,8) . get_dim(intval($dnow),intval(substr($dnow,5))); - $start_month = datetime_convert('','',$dstart,'Y-m-d'); - $end_month = datetime_convert('','',$dend,'Y-m-d'); - $str = day_translate(datetime_convert('','',$dnow,'F')); - if (! $ret[$dyear]) { - $ret[$dyear] = []; - } - $ret[$dyear][] = [ $str, $end_month, $start_month ]; - $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); - } + while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) { + $dyear = intval(substr($dnow, 0, 4)); + $dstart = substr($dnow, 0, 8) . '01'; + $dend = substr($dnow, 0, 8) . get_dim(intval($dnow), intval(substr($dnow, 5))); + $start_month = datetime_convert('', '', $dstart, 'Y-m-d'); + $end_month = datetime_convert('', '', $dend, 'Y-m-d'); + $str = day_translate(datetime_convert('', '', $dnow, 'F')); + if (! $ret[$dyear]) { + $ret[$dyear] = []; + } + $ret[$dyear][] = [ $str, $end_month, $start_month ]; + $dnow = datetime_convert('', '', $dnow . ' -1 month', 'Y-m-d'); + } - return $ret; + return $ret; } -function posted_dates($uid,$wall) { +function posted_dates($uid, $wall) +{ - $dnow = datetime_convert('UTC',date_default_timezone_get(),'now','Y-m-d'); + $dnow = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d'); - $dthen = first_post_date($uid,$wall); - - if (! $dthen) { - return []; - } + $dthen = first_post_date($uid, $wall); - // If it's near the end of a long month, backup to the 28th so that in - // consecutive loops we'll always get a whole month difference. + if (! $dthen) { + return []; + } - if (intval(substr($dnow,8)) > 28) { - $dnow = substr($dnow,0,8) . '28'; - } - if (intval(substr($dthen,8)) > 28) { - $dthen = substr($dthen,0,8) . '28'; - } + // If it's near the end of a long month, backup to the 28th so that in + // consecutive loops we'll always get a whole month difference. - $ret = []; + if (intval(substr($dnow, 8)) > 28) { + $dnow = substr($dnow, 0, 8) . '28'; + } + if (intval(substr($dthen, 8)) > 28) { + $dthen = substr($dthen, 0, 8) . '28'; + } - // Starting with the current month, get the first and last days of every - // month down to and including the month of the first post + $ret = []; - while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) { - $dstart = substr($dnow,0,8) . '01'; - $dend = substr($dnow,0,8) . get_dim(intval($dnow),intval(substr($dnow,5))); - $start_month = datetime_convert('','',$dstart,'Y-m-d'); - $end_month = datetime_convert('','',$dend,'Y-m-d'); - $str = day_translate(datetime_convert('','',$dnow,'F Y')); - $ret[] = array($str,$end_month,$start_month); - $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); - } - return $ret; + // Starting with the current month, get the first and last days of every + // month down to and including the month of the first post + + while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) { + $dstart = substr($dnow, 0, 8) . '01'; + $dend = substr($dnow, 0, 8) . get_dim(intval($dnow), intval(substr($dnow, 5))); + $start_month = datetime_convert('', '', $dstart, 'Y-m-d'); + $end_month = datetime_convert('', '', $dend, 'Y-m-d'); + $str = day_translate(datetime_convert('', '', $dnow, 'F Y')); + $ret[] = array($str,$end_month,$start_month); + $dnow = datetime_convert('', '', $dnow . ' -1 month', 'Y-m-d'); + } + return $ret; } /** @@ -4081,84 +4241,84 @@ function posted_dates($uid,$wall) { * @param bool $link (optional) default false * @return array Return the provided $items array after extended the posts with tags */ -function fetch_post_tags($items, $link = false) { +function fetch_post_tags($items, $link = false) +{ - $tag_finder = []; - if ($items) { - foreach ($items as $item) { - if (is_array($item)) { - if (array_key_exists('item_id',$item)) { - if (! in_array($item['item_id'],$tag_finder)) { - $tag_finder[] = $item['item_id']; - } - } - else { - if (! in_array($item['id'],$tag_finder)) { - $tag_finder[] = $item['id']; - } - } - } - } - } - - $tag_finder_str = implode(', ', $tag_finder); + $tag_finder = []; + if ($items) { + foreach ($items as $item) { + if (is_array($item)) { + if (array_key_exists('item_id', $item)) { + if (! in_array($item['item_id'], $tag_finder)) { + $tag_finder[] = $item['item_id']; + } + } else { + if (! in_array($item['id'], $tag_finder)) { + $tag_finder[] = $item['id']; + } + } + } + } + } - if (strlen($tag_finder_str)) { - $tags = q("select * from term where oid in ( %s ) and otype = %d", - dbesc($tag_finder_str), - intval(TERM_OBJ_POST) - ); - $imeta = q("select * from iconfig where iid in ( %s )", - dbesc($tag_finder_str) - ); - } + $tag_finder_str = implode(', ', $tag_finder); - for ($x = 0; $x < count($items); $x ++) { - if ($tags) { - foreach ($tags as $t) { - if (array_key_exists('item_id',$items[$x])) { - if ($t['oid'] == $items[$x]['item_id']) { - if (! (isset($items[$x]['term']) && is_array($items[$x]['term']))) { - $items[$x]['term'] = []; - } - $items[$x]['term'][] = $t; - } - } - else { - if ($t['oid'] == $items[$x]['id']) { - if (! is_array($items[$x]['term'])) { - $items[$x]['term'] = []; - } - $items[$x]['term'][] = $t; - } - } - } - } - if ($imeta) { - foreach ($imeta as $i) { - if (array_key_exists('item_id',$items[$x])) { - if ($i['iid'] == $items[$x]['item_id']) { - if (! (isset($items[$x]['iconfig']) && is_array($items[$x]['iconfig']))) { - $items[$x]['iconfig'] = []; - } - $i['v'] = unserialise($i['v']); - $items[$x]['iconfig'][] = $i; - } - } - else { - if ($i['iid'] == $items[$x]['id']) { - if (! (isset($items[$x]['iconfig']) && is_array($items[$x]['iconfig']))) { - $items[$x]['iconfig'] = []; - } - $i['v'] = unserialise($i['v']); - $items[$x]['iconfig'][] = $i; - } - } - } - } - } + if (strlen($tag_finder_str)) { + $tags = q( + "select * from term where oid in ( %s ) and otype = %d", + dbesc($tag_finder_str), + intval(TERM_OBJ_POST) + ); + $imeta = q( + "select * from iconfig where iid in ( %s )", + dbesc($tag_finder_str) + ); + } - return $items; + for ($x = 0; $x < count($items); $x++) { + if ($tags) { + foreach ($tags as $t) { + if (array_key_exists('item_id', $items[$x])) { + if ($t['oid'] == $items[$x]['item_id']) { + if (! (isset($items[$x]['term']) && is_array($items[$x]['term']))) { + $items[$x]['term'] = []; + } + $items[$x]['term'][] = $t; + } + } else { + if ($t['oid'] == $items[$x]['id']) { + if (! is_array($items[$x]['term'])) { + $items[$x]['term'] = []; + } + $items[$x]['term'][] = $t; + } + } + } + } + if ($imeta) { + foreach ($imeta as $i) { + if (array_key_exists('item_id', $items[$x])) { + if ($i['iid'] == $items[$x]['item_id']) { + if (! (isset($items[$x]['iconfig']) && is_array($items[$x]['iconfig']))) { + $items[$x]['iconfig'] = []; + } + $i['v'] = unserialise($i['v']); + $items[$x]['iconfig'][] = $i; + } + } else { + if ($i['iid'] == $items[$x]['id']) { + if (! (isset($items[$x]['iconfig']) && is_array($items[$x]['iconfig']))) { + $items[$x]['iconfig'] = []; + } + $i['v'] = unserialise($i['v']); + $items[$x]['iconfig'][] = $i; + } + } + } + } + } + + return $items; } @@ -4170,475 +4330,469 @@ function fetch_post_tags($items, $link = false) { * @param array $arr * @return array */ -function zot_feed($uid, $observer_hash, $arr) { +function zot_feed($uid, $observer_hash, $arr) +{ - $result = []; - $mindate = null; - $message_id = null; - $wall = true; + $result = []; + $mindate = null; + $message_id = null; + $wall = true; - require_once('include/security.php'); + require_once('include/security.php'); - $encoding = ((array_key_exists('encoding',$arr)) ? $arr['encoding'] : 'zot'); - - if(array_key_exists('mindate',$arr)) { - $mindate = datetime_convert('UTC','UTC',$arr['mindate']); - } + $encoding = ((array_key_exists('encoding', $arr)) ? $arr['encoding'] : 'zot'); - if(array_key_exists('message_id',$arr)) { - $message_id = $arr['message_id']; - } + if (array_key_exists('mindate', $arr)) { + $mindate = datetime_convert('UTC', 'UTC', $arr['mindate']); + } - if(array_key_exists('wall',$arr)) { - $wall = intval($arr['wall']); - } + if (array_key_exists('message_id', $arr)) { + $message_id = $arr['message_id']; + } - if(! $mindate) - $mindate = NULL_DATE; + if (array_key_exists('wall', $arr)) { + $wall = intval($arr['wall']); + } - $mindate = dbesc($mindate); + if (! $mindate) { + $mindate = NULL_DATE; + } - logger('zot_feed: requested for uid ' . $uid . ' from observer ' . $observer_hash, LOGGER_DEBUG); - if($message_id) - logger('message_id: ' . $message_id,LOGGER_DEBUG); + $mindate = dbesc($mindate); - if(! perm_is_allowed($uid,$observer_hash,'view_stream')) { - logger('zot_feed: permission denied.'); - return $result; - } + logger('zot_feed: requested for uid ' . $uid . ' from observer ' . $observer_hash, LOGGER_DEBUG); + if ($message_id) { + logger('message_id: ' . $message_id, LOGGER_DEBUG); + } - if(! is_sys_channel($uid)) - $sql_extra = item_permissions_sql($uid,$observer_hash); + if (! perm_is_allowed($uid, $observer_hash, 'view_stream')) { + logger('zot_feed: permission denied.'); + return $result; + } - $limit = " LIMIT 5000 "; + if (! is_sys_channel($uid)) { + $sql_extra = item_permissions_sql($uid, $observer_hash); + } - if($mindate > NULL_DATE) { - $sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) "; - } + $limit = " LIMIT 5000 "; - if($message_id) { - $sql_extra .= " and mid = '" . dbesc($message_id) . "' "; - $limit = ''; - } + if ($mindate > NULL_DATE) { + $sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) "; + } - if($wall) { - $sql_extra .= " and item_wall = 1 "; - } + if ($message_id) { + $sql_extra .= " and mid = '" . dbesc($message_id) . "' "; + $limit = ''; + } + + if ($wall) { + $sql_extra .= " and item_wall = 1 "; + } - $items = []; + $items = []; - $item_normal = item_normal(); + $item_normal = item_normal(); - if(is_sys_channel($uid)) { + if (is_sys_channel($uid)) { + $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); + $nonsys_uids_str = ids_to_querystr($nonsys_uids, 'channel_id'); - $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); - $nonsys_uids_str = ids_to_querystr($nonsys_uids,'channel_id'); - - $r = q("SELECT parent FROM item + $r = q( + "SELECT parent FROM item WHERE uid IN ( %s ) AND item_private = 0 $item_normal $sql_extra ORDER BY created ASC $limit", - intval($nonsys_uids_str) - ); - } - else { - $r = q("SELECT parent FROM item + intval($nonsys_uids_str) + ); + } else { + $r = q( + "SELECT parent FROM item WHERE uid = %d $item_normal $sql_extra ORDER BY created ASC $limit", - intval($uid) - ); - } + intval($uid) + ); + } - $parents = []; + $parents = []; - if($r) { - foreach($r as $rv) { - if(array_key_exists($rv['parent'],$parents)) - continue; - $parents[$rv['parent']] = $rv; - if(count($parents) > 200) - break; - } + if ($r) { + foreach ($r as $rv) { + if (array_key_exists($rv['parent'], $parents)) { + continue; + } + $parents[$rv['parent']] = $rv; + if (count($parents) > 200) { + break; + } + } - $parents_str = ids_to_querystr($parents,'parent'); - $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); - $item_normal = item_normal(); + $parents_str = ids_to_querystr($parents, 'parent'); + $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); + $item_normal = item_normal(); - $items = q("SELECT item.*, item.id AS item_id FROM item + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal $sys_query ", - dbesc($parents_str) - ); - } + dbesc($parents_str) + ); + } - if($items) { - xchan_query($items); - $items = fetch_post_tags($items); - require_once('include/conversation.php'); - $items = conv_sort($items,'ascending'); - } - else - $items = []; + if ($items) { + xchan_query($items); + $items = fetch_post_tags($items); + require_once('include/conversation.php'); + $items = conv_sort($items, 'ascending'); + } else { + $items = []; + } - logger('zot_feed: number items: ' . count($items),LOGGER_DEBUG); + logger('zot_feed: number items: ' . count($items), LOGGER_DEBUG); - foreach($items as $item) { - if($encoding === 'zot') - $result[] = encode_item($item); - elseif(encoding === 'activitystreams') - $result[] = Activity::encode_activity($item); - } + foreach ($items as $item) { + if ($encoding === 'zot') { + $result[] = encode_item($item); + } elseif (encoding === 'activitystreams') { + $result[] = Activity::encode_activity($item); + } + } - return $result; + return $result; } -function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = CLIENT_MODE_NORMAL,$module = 'stream') { +function items_fetch($arr, $channel = null, $observer_hash = null, $client_mode = CLIENT_MODE_NORMAL, $module = 'stream') +{ - $result = [ 'success' => false ]; + $result = [ 'success' => false ]; - $uid = 0; - $sql_extra = ''; - $sql_nets = ''; - $sql_options = ''; - $sql_extra2 = ''; - $sql_extra3 = ''; - $def_acl = ''; + $uid = 0; + $sql_extra = ''; + $sql_nets = ''; + $sql_options = ''; + $sql_extra2 = ''; + $sql_extra3 = ''; + $def_acl = ''; - $item_uids = ' true '; - $item_normal = item_normal(); + $item_uids = ' true '; + $item_normal = item_normal(); - if (isset($arr['uid']) && $arr['uid']) { - $uid = $arr['uid']; - } + if (isset($arr['uid']) && $arr['uid']) { + $uid = $arr['uid']; + } - if ($channel) { - $uid = $channel['channel_id']; - $uidhash = $channel['channel_hash']; - $item_uids = " item.uid = " . intval($uid) . " "; - } + if ($channel) { + $uid = $channel['channel_id']; + $uidhash = $channel['channel_hash']; + $item_uids = " item.uid = " . intval($uid) . " "; + } - if (! (isset($arr['include_follow']) && intval($arr['include_follow']))) { - $item_normal .= " and not verb in ( 'Follow' , 'Ignore' ) "; - } + if (! (isset($arr['include_follow']) && intval($arr['include_follow']))) { + $item_normal .= " and not verb in ( 'Follow' , 'Ignore' ) "; + } - if (isset($arr['star']) && $arr['star']) { - $sql_options .= " and item_starred = 1 "; - } + if (isset($arr['star']) && $arr['star']) { + $sql_options .= " and item_starred = 1 "; + } - if (isset($arr['wall']) && $arr['wall']) { - $sql_options .= " and item_wall = 1 "; - } + if (isset($arr['wall']) && $arr['wall']) { + $sql_options .= " and item_wall = 1 "; + } - if (isset($arr['item_id']) && $arr['item_id']) { - $sql_options .= " and parent = " . intval($arr['item_id']) . " "; - } + if (isset($arr['item_id']) && $arr['item_id']) { + $sql_options .= " and parent = " . intval($arr['item_id']) . " "; + } - if (isset($arr['mid']) && $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 $item_normal ) "; + if (isset($arr['mid']) && $arr['mid']) { + $sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' "; + } - if(isset($arr['since_id']) && $arr['since_id']) { - $sql_extra .= " and item.id > " . $since_id . " "; - } - - if (isset($arr['cat']) && $arr['cat']) { - $sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY)); - } - - if (isset($arr['gid']) && $arr['gid'] && $uid) { - $r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1", - intval($arr['group']), - intval($uid) - ); - if (! $r) { - $result['message'] = t('Access list not found.'); - return $result; - } + $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) "; - $contact_str = ''; + if (isset($arr['since_id']) && $arr['since_id']) { + $sql_extra .= " and item.id > " . $since_id . " "; + } - $contacts = AccessList::members($uid,$r[0]['id']); - if ($contacts) { - foreach ($contacts as $c) { - if ($contact_str) { - $contact_str .= ','; - } - $contact_str .= "'" . $c['xchan'] . "'"; - } - } - else { - $contact_str = ' 0 '; - $result['message'] = t('Privacy group is empty.'); - return $result; - } + if (isset($arr['cat']) && $arr['cat']) { + $sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY)); + } - $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent $item_normal ) "; + if (isset($arr['gid']) && $arr['gid'] && $uid) { + $r = q( + "SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1", + intval($arr['group']), + intval($uid) + ); + if (! $r) { + $result['message'] = t('Access list not found.'); + return $result; + } - $x = AccessList::rec_byhash($uid,$r[0]['hash']); - $result['headline'] = sprintf( t('Access list: %s'),$x['gname']); - } - elseif (isset($arr['cid']) && $arr['cid'] && $uid) { + $contact_str = ''; - $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1", - intval($arr['cid']), - intval(local_channel()) - ); - if ($r) { - $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) "; - $result['headline'] = sprintf( t('Connection: %s'),$r[0]['xchan_name']); - } - else { - $result['message'] = t('Channel not found.'); - return $result; - } - } + $contacts = AccessList::members($uid, $r[0]['id']); + if ($contacts) { + foreach ($contacts as $c) { + if ($contact_str) { + $contact_str .= ','; + } + $contact_str .= "'" . $c['xchan'] . "'"; + } + } else { + $contact_str = ' 0 '; + $result['message'] = t('Privacy group is empty.'); + return $result; + } - if ($channel && intval($arr['compat']) === 1) { - $sql_extra = " AND author_xchan = '" . $channel['channel_hash'] . "' and item_private = 0 $item_normal "; - } + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent $item_normal ) "; - if ($arr['datequery']) { - $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert('UTC','UTC',$arr['datequery'])))); - } - if ($arr['datequery2']) { - $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert('UTC','UTC',$arr['datequery2'])))); - } + $x = AccessList::rec_byhash($uid, $r[0]['hash']); + $result['headline'] = sprintf(t('Access list: %s'), $x['gname']); + } elseif (isset($arr['cid']) && $arr['cid'] && $uid) { + $r = q( + "SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1", + intval($arr['cid']), + intval(local_channel()) + ); + if ($r) { + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) "; + $result['headline'] = sprintf(t('Connection: %s'), $r[0]['xchan_name']); + } else { + $result['message'] = t('Channel not found.'); + return $result; + } + } - if ($arr['search']) { - if (strpos($arr['search'],'#') === 0) { - $sql_extra .= term_query('item',substr($arr['search'],1),TERM_HASHTAG,TERM_COMMUNITYTAG); + if ($channel && intval($arr['compat']) === 1) { + $sql_extra = " AND author_xchan = '" . $channel['channel_hash'] . "' and item_private = 0 $item_normal "; + } - } - else { - $sql_extra .= sprintf(" AND item.body like '%s' ", - dbesc(protect_sprintf('%' . $arr['search'] . '%')) - ); - } - } + if ($arr['datequery']) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert('UTC', 'UTC', $arr['datequery'])))); + } + if ($arr['datequery2']) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert('UTC', 'UTC', $arr['datequery2'])))); + } - if (isset($arr['file']) && strlen($arr['file'])) { - $sql_extra .= term_query('item',$arr['file'],TERM_FILE); - } + if ($arr['search']) { + if (strpos($arr['search'], '#') === 0) { + $sql_extra .= term_query('item', substr($arr['search'], 1), TERM_HASHTAG, TERM_COMMUNITYTAG); + } else { + $sql_extra .= sprintf( + " AND item.body like '%s' ", + dbesc(protect_sprintf('%' . $arr['search'] . '%')) + ); + } + } - if (isset($arr['conv']) && $arr['conv'] && $channel) { - $sql_extra .= sprintf(" AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ", - dbesc(protect_sprintf($uidhash)) - ); - } + if (isset($arr['file']) && strlen($arr['file'])) { + $sql_extra .= term_query('item', $arr['file'], TERM_FILE); + } - if (($client_mode & CLIENT_MODE_UPDATE) && (! ($client_mode & CLIENT_MODE_LOAD))) { - // only setup pagination on initial page view - $pager_sql = ''; - } - else { - if (! (isset($arr['total']) && $arr['total'])) { - $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 20); - App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); - } - } + if (isset($arr['conv']) && $arr['conv'] && $channel) { + $sql_extra .= sprintf( + " AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ", + dbesc(protect_sprintf($uidhash)) + ); + } - if (isset($arr['start']) && isset($arr['records'])) { - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($arr['records']), intval($arr['start'])); - } + if (($client_mode & CLIENT_MODE_UPDATE) && (! ($client_mode & CLIENT_MODE_LOAD))) { + // only setup pagination on initial page view + $pager_sql = ''; + } else { + if (! (isset($arr['total']) && $arr['total'])) { + $itemspage = (($channel) ? get_pconfig($uid, 'system', 'itemspage') : 20); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + } + } - if (array_key_exists('cmin',$arr) || array_key_exists('cmax',$arr)) { - if (($arr['cmin'] != 0) || ($arr['cmax'] != 99)) { + if (isset($arr['start']) && isset($arr['records'])) { + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($arr['records']), intval($arr['start'])); + } - // Not everybody who shows up in the stream will be in your address book. - // By default those that aren't are assumed to have closeness = 99; but this isn't - // recorded anywhere. So if cmax is 99, we'll open the search up to anybody in - // the stream with a NULL address book entry. + if (array_key_exists('cmin', $arr) || array_key_exists('cmax', $arr)) { + if (($arr['cmin'] != 0) || ($arr['cmax'] != 99)) { + // Not everybody who shows up in the stream will be in your address book. + // By default those that aren't are assumed to have closeness = 99; but this isn't + // recorded anywhere. So if cmax is 99, we'll open the search up to anybody in + // the stream with a NULL address book entry. - $sql_nets .= " AND "; + $sql_nets .= " AND "; - if ($arr['cmax'] == 99) - $sql_nets .= " ( "; + if ($arr['cmax'] == 99) { + $sql_nets .= " ( "; + } - $sql_nets .= "( abook.abook_closeness >= " . intval($arr['cmin']) . " "; - $sql_nets .= " AND abook.abook_closeness <= " . intval($arr['cmax']) . " ) "; + $sql_nets .= "( abook.abook_closeness >= " . intval($arr['cmin']) . " "; + $sql_nets .= " AND abook.abook_closeness <= " . intval($arr['cmax']) . " ) "; - if ($arr['cmax'] == 99) - $sql_nets .= " OR abook.abook_closeness IS NULL ) "; - } - } + if ($arr['cmax'] == 99) { + $sql_nets .= " OR abook.abook_closeness IS NULL ) "; + } + } + } - $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and item.item_unseen = 1 " : ''); - if ($client_mode & CLIENT_MODE_LOAD) { - $simple_update = ''; - } + $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and item.item_unseen = 1 " : ''); + if ($client_mode & CLIENT_MODE_LOAD) { + $simple_update = ''; + } - $sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash); + $sql_extra .= item_permissions_sql($channel['channel_id'], $observer_hash); - if (isset($arr['pages']) && $arr['pages']) { - $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " "; - } - else { - $item_restrict = " AND item_type = 0 "; - } + if (isset($arr['pages']) && $arr['pages']) { + $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " "; + } else { + $item_restrict = " AND item_type = 0 "; + } - if (isset($arr['item_type']) && $arr['item_type'] === '*') { - $item_restrict = ''; - } + if (isset($arr['item_type']) && $arr['item_type'] === '*') { + $item_restrict = ''; + } - if (((isset($arr['compat']) && $arr['compat']) || ((isset($arr['nouveau']) && $arr['nouveau']) && ($client_mode & CLIENT_MODE_LOAD))) && $channel) { + if (((isset($arr['compat']) && $arr['compat']) || ((isset($arr['nouveau']) && $arr['nouveau']) && ($client_mode & CLIENT_MODE_LOAD))) && $channel) { + // "New Item View" - show all items unthreaded in reverse created date order - // "New Item View" - show all items unthreaded in reverse created date order - - if (isset($arr['total']) && $arr['total']) { - $items = q("SELECT count(item.id) AS total FROM item + if (isset($arr['total']) && $arr['total']) { + $items = q("SELECT count(item.id) AS total FROM item WHERE $item_uids $item_restrict $simple_update - $sql_extra $sql_nets $sql_extra3" - ); - if ($items) { - return intval($items[0]['total']); - } - return 0; - } - - $items = q("SELECT item.*, item.id AS item_id FROM item + $sql_extra $sql_nets $sql_extra3"); + if ($items) { + return intval($items[0]['total']); + } + return 0; + } + + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE $item_uids $item_restrict $simple_update $sql_extra $sql_nets $sql_extra3 - ORDER BY item.received DESC $pager_sql" - ); + ORDER BY item.received DESC $pager_sql"); - xchan_query($items); - $items = fetch_post_tags($items,true); + xchan_query($items); + $items = fetch_post_tags($items, true); + } else { + // Normal conversation view - } - else { + if (isset($arr['order']) && $arr['order'] === 'post') { + $ordering = "created"; + } else { + $ordering = "commented"; + } - // Normal conversation view + if (($client_mode & CLIENT_MODE_LOAD) || ($client_mode == CLIENT_MODE_NORMAL)) { + // Fetch a page full of parent items for this page - if (isset($arr['order']) && $arr['order'] === 'post') { - $ordering = "created"; - } - else { - $ordering = "commented"; - } - - if (($client_mode & CLIENT_MODE_LOAD) || ($client_mode == CLIENT_MODE_NORMAL)) { - - // Fetch a page full of parent items for this page - - $r = q("SELECT distinct item.id AS item_id, item.$ordering FROM item + $r = q("SELECT distinct item.id AS item_id, item.$ordering FROM item left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict AND item.parent = item.id and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra3 $sql_extra $sql_nets - ORDER BY item.$ordering DESC $pager_sql " - ); - } - else { - // update - $r = q("SELECT item.parent AS item_id FROM item + ORDER BY item.$ordering DESC $pager_sql "); + } else { + // update + $r = q("SELECT item.parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict $simple_update and (abook.abook_blocked = 0 or abook.abook_flags is null) - $sql_extra3 $sql_extra $sql_nets " - ); - } + $sql_extra3 $sql_extra $sql_nets "); + } - // Then fetch all the children of the parents that are on this page + // Then fetch all the children of the parents that are on this page - if(isset($r) && $r) { + if (isset($r) && $r) { + $parents_str = ids_to_querystr($r, 'item_id'); - $parents_str = ids_to_querystr($r,'item_id'); - - if (isset($arr['top']) && $arr['top']) { - $sql_extra = ' and id = parent ' . $sql_extra; - } - $items = q("SELECT item.*, item.id AS item_id FROM item + if (isset($arr['top']) && $arr['top']) { + $sql_extra = ' and id = parent ' . $sql_extra; + } + $items = q( + "SELECT item.*, item.id AS item_id FROM item WHERE $item_uids $item_restrict AND item.parent IN ( %s ) $sql_extra ", - dbesc($parents_str) - ); + dbesc($parents_str) + ); - xchan_query($items); - $items = fetch_post_tags($items,false); + xchan_query($items); + $items = fetch_post_tags($items, false); - require_once('include/conversation.php'); - $items = conv_sort($items,$ordering); + require_once('include/conversation.php'); + $items = conv_sort($items, $ordering); + } else { + $items = []; + } - } - else { - $items = []; - } + if (isset($parents_str) && $parents_str && isset($arr['mark_seen']) && $arr['mark_seen']) { + $update_unseen = ' AND parent IN ( ' . dbesc($parents_str) . ' )'; + /** @FIXME finish mark unseen sql */ + } + } - if (isset($parents_str) && $parents_str && isset($arr['mark_seen']) && $arr['mark_seen']) { - $update_unseen = ' AND parent IN ( ' . dbesc($parents_str) . ' )'; - /** @FIXME finish mark unseen sql */ - } - } - - return $items; + return $items; } -function webpage_to_namespace($webpage) { +function webpage_to_namespace($webpage) +{ - if ($webpage == ITEM_TYPE_WEBPAGE) - $page_type = 'WEBPAGE'; - elseif ($webpage == ITEM_TYPE_BLOCK) - $page_type = 'BUILDBLOCK'; - elseif ($webpage == ITEM_TYPE_PDL) - $page_type = 'PDL'; - elseif ($webpage == ITEM_TYPE_CARD) - $page_type = 'CARD'; - elseif ($webpage == ITEM_TYPE_ARTICLE) - $page_type = 'ARTICLE'; - elseif ($webpage == ITEM_TYPE_DOC) - $page_type = 'docfile'; - else - $page_type = 'unknown'; + if ($webpage == ITEM_TYPE_WEBPAGE) { + $page_type = 'WEBPAGE'; + } elseif ($webpage == ITEM_TYPE_BLOCK) { + $page_type = 'BUILDBLOCK'; + } elseif ($webpage == ITEM_TYPE_PDL) { + $page_type = 'PDL'; + } elseif ($webpage == ITEM_TYPE_CARD) { + $page_type = 'CARD'; + } elseif ($webpage == ITEM_TYPE_ARTICLE) { + $page_type = 'ARTICLE'; + } elseif ($webpage == ITEM_TYPE_DOC) { + $page_type = 'docfile'; + } else { + $page_type = 'unknown'; + } - return $page_type; + return $page_type; } -function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid) { +function update_remote_id($channel, $post_id, $webpage, $pagetitle, $namespace, $remote_id, $mid) +{ - if (! $post_id) { - return; - } + if (! $post_id) { + return; + } - $page_type = webpage_to_namespace($webpage); + $page_type = webpage_to_namespace($webpage); - if ($page_type == 'unknown' && $namespace && $remote_id) { - $page_type = $namespace; - $pagetitle = $remote_id; - } - else { - $page_type = ''; - } + if ($page_type == 'unknown' && $namespace && $remote_id) { + $page_type = $namespace; + $pagetitle = $remote_id; + } else { + $page_type = ''; + } - if ($page_type) { + if ($page_type) { + // store page info as an alternate message_id so we can access it via + // https://sitename/page/$channelname/$pagetitle + // if no pagetitle was given or it couldn't be transliterated into a url, use the first + // sixteen bytes of the mid - which makes the link portable and not quite as daunting + // as the entire mid. If it were the post_id the link would be less portable. - // store page info as an alternate message_id so we can access it via - // https://sitename/page/$channelname/$pagetitle - // if no pagetitle was given or it couldn't be transliterated into a url, use the first - // sixteen bytes of the mid - which makes the link portable and not quite as daunting - // as the entire mid. If it were the post_id the link would be less portable. - - IConfig::Set( - intval($post_id), - 'system', - $page_type, - ($pagetitle) ? $pagetitle : substr($mid,0,16), - false - ); - } + IConfig::Set( + intval($post_id), + 'system', + $page_type, + ($pagetitle) ? $pagetitle : substr($mid, 0, 16), + false + ); + } } @@ -4649,68 +4803,73 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo * @param string $mid * @param int $uid */ -function item_add_cid($xchan_hash, $mid, $uid) { - $r = q("select id from item where mid = '%s' and uid = %d and allow_cid like '%s'", - dbesc($mid), - intval($uid), - dbesc('<' . $xchan_hash . '>') - ); - if (! $r) { - $r = q("update item set allow_cid = concat(allow_cid,'%s') where mid = '%s' and uid = %d", - dbesc('<' . $xchan_hash . '>'), - dbesc($mid), - intval($uid) - ); - } +function item_add_cid($xchan_hash, $mid, $uid) +{ + $r = q( + "select id from item where mid = '%s' and uid = %d and allow_cid like '%s'", + dbesc($mid), + intval($uid), + dbesc('<' . $xchan_hash . '>') + ); + if (! $r) { + $r = q( + "update item set allow_cid = concat(allow_cid,'%s') where mid = '%s' and uid = %d", + dbesc('<' . $xchan_hash . '>'), + dbesc($mid), + intval($uid) + ); + } } -function item_remove_cid($xchan_hash,$mid,$uid) { - $r = q("select allow_cid from item where mid = '%s' and uid = %d and allow_cid like '%s'", - dbesc($mid), - intval($uid), - dbesc('<' . $xchan_hash . '>') - ); - if ($r) { - $x = q("update item set allow_cid = '%s' where mid = '%s' and uid = %d", - dbesc(str_replace('<' . $xchan_hash . '>','',$r[0]['allow_cid'])), - dbesc($mid), - intval($uid) - ); - } +function item_remove_cid($xchan_hash, $mid, $uid) +{ + $r = q( + "select allow_cid from item where mid = '%s' and uid = %d and allow_cid like '%s'", + dbesc($mid), + intval($uid), + dbesc('<' . $xchan_hash . '>') + ); + if ($r) { + $x = q( + "update item set allow_cid = '%s' where mid = '%s' and uid = %d", + dbesc(str_replace('<' . $xchan_hash . '>', '', $r[0]['allow_cid'])), + dbesc($mid), + intval($uid) + ); + } } // Set item permissions based on results obtained from linkify_tags() -function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, $profile_uid, $parent_item = false, &$private) { - $first_access_tag = true; +function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, $profile_uid, $parent_item = false, &$private) +{ + $first_access_tag = true; - foreach($linkified as $x) { - $access_tag = $x['success']['access_tag']; - if(($access_tag) && (! $parent_item)) { - logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DATA); - if ($first_access_tag && (! get_pconfig($profile_uid,'system','no_private_mention_acl_override'))) { + foreach ($linkified as $x) { + $access_tag = $x['success']['access_tag']; + if (($access_tag) && (! $parent_item)) { + logger('access_tag: ' . $tag . ' ' . print_r($access_tag, true), LOGGER_DATA); + if ($first_access_tag && (! get_pconfig($profile_uid, 'system', 'no_private_mention_acl_override'))) { + // This is a tough call, hence configurable. The issue is that one can type in a @!privacy mention + // and also have a default ACL (perhaps from viewing a collection) and could be suprised that the + // privacy mention wasn't the only recipient. So the default is to wipe out the existing ACL if a + // private mention is found. This can be over-ridden if you wish private mentions to be in + // addition to the current ACL settings. - // This is a tough call, hence configurable. The issue is that one can type in a @!privacy mention - // and also have a default ACL (perhaps from viewing a collection) and could be suprised that the - // privacy mention wasn't the only recipient. So the default is to wipe out the existing ACL if a - // private mention is found. This can be over-ridden if you wish private mentions to be in - // addition to the current ACL settings. - - $str_contact_allow = ''; - $str_group_allow = ''; - $first_access_tag = false; - } - if(strpos($access_tag,'cid:') === 0) { - $str_contact_allow .= '<' . substr($access_tag,4) . '>'; - $access_tag = ''; - $private = 2; - } - elseif(strpos($access_tag,'gid:') === 0) { - $str_group_allow .= '<' . substr($access_tag,4) . '>'; - $access_tag = ''; - $private = 2; - } - } - } + $str_contact_allow = ''; + $str_group_allow = ''; + $first_access_tag = false; + } + if (strpos($access_tag, 'cid:') === 0) { + $str_contact_allow .= '<' . substr($access_tag, 4) . '>'; + $access_tag = ''; + $private = 2; + } elseif (strpos($access_tag, 'gid:') === 0) { + $str_group_allow .= '<' . substr($access_tag, 4) . '>'; + $access_tag = ''; + $private = 2; + } + } + } } /** @@ -4722,290 +4881,306 @@ function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, * @param array $item * @return bool */ -function comment_local_origin($item) { - if(stripos($item['mid'], App::get_hostname()) && ($item['parent'] != $item['id'])) - return true; +function comment_local_origin($item) +{ + if (stripos($item['mid'], App::get_hostname()) && ($item['parent'] != $item['id'])) { + return true; + } - return false; + return false; } -function send_profile_photo_activity($channel,$photo,$profile) { +function send_profile_photo_activity($channel, $photo, $profile) +{ - // for now only create activities for the default profile + // for now only create activities for the default profile - if (! (isset($profile) && isset($profile['is_default']) && intval($profile['is_default']))) { - return; - } + if (! (isset($profile) && isset($profile['is_default']) && intval($profile['is_default']))) { + return; + } - $arr = []; - $arr['item_thread_top'] = 1; - $arr['item_origin'] = 1; - $arr['item_wall'] = 1; - $arr['obj_type'] = ACTIVITY_OBJ_NOTE; - $arr['verb'] = ACTIVITY_CREATE; - $arr['uuid'] = new_uuid(); - $arr['mid'] = z_root() . '/item/' . $arr['uuid']; + $arr = []; + $arr['item_thread_top'] = 1; + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; + $arr['obj_type'] = ACTIVITY_OBJ_NOTE; + $arr['verb'] = ACTIVITY_CREATE; + $arr['uuid'] = new_uuid(); + $arr['mid'] = z_root() . '/item/' . $arr['uuid']; - if(stripos($profile['gender'],t('female')) !== false) - $t = t('%1$s updated her %2$s'); - elseif(stripos($profile['gender'],t('male')) !== false) - $t = t('%1$s updated his %2$s'); - else - $t = t('%1$s updated their %2$s'); + if (stripos($profile['gender'], t('female')) !== false) { + $t = t('%1$s updated her %2$s'); + } elseif (stripos($profile['gender'], t('male')) !== false) { + $t = t('%1$s updated his %2$s'); + } else { + $t = t('%1$s updated their %2$s'); + } - $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]'; + $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]'; - $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]'; + $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]'; - $arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext; + $arr['body'] = sprintf($t, $channel['channel_name'], $ptext) . "\n\n" . $ltext; - $arr['obj'] = [ - 'type' => ACTIVITY_OBJ_NOTE, - 'published' => datetime_convert('UTC','UTC',$photo['created'],ATOM_TIME), - 'updated' => datetime_convert('UTC','UTC',$photo['edited'],ATOM_TIME), - 'id' => $arr['mid'], - 'url' => [ 'type' => 'Link', 'mediaType' => $photo['mimetype'], 'href' => z_root() . '/photo/profile/l/' . $channel['channel_id'] ], - 'source' => [ 'content' => $arr['body'], 'mediaType' => 'text/bbcode' ], - 'content' => bbcode($arr['body']), - 'actor' => Activity::encode_person($channel,false), - ]; + $arr['obj'] = [ + 'type' => ACTIVITY_OBJ_NOTE, + 'published' => datetime_convert('UTC', 'UTC', $photo['created'], ATOM_TIME), + 'updated' => datetime_convert('UTC', 'UTC', $photo['edited'], ATOM_TIME), + 'id' => $arr['mid'], + 'url' => [ 'type' => 'Link', 'mediaType' => $photo['mimetype'], 'href' => z_root() . '/photo/profile/l/' . $channel['channel_id'] ], + 'source' => [ 'content' => $arr['body'], 'mediaType' => 'text/bbcode' ], + 'content' => bbcode($arr['body']), + 'actor' => Activity::encode_person($channel, false), + ]; - $acl = new AccessControl($channel); - $x = $acl->get(); - $arr['allow_cid'] = $x['allow_cid']; + $acl = new AccessControl($channel); + $x = $acl->get(); + $arr['allow_cid'] = $x['allow_cid']; - $arr['allow_gid'] = $x['allow_gid']; - $arr['deny_cid'] = $x['deny_cid']; - $arr['deny_gid'] = $x['deny_gid']; + $arr['allow_gid'] = $x['allow_gid']; + $arr['deny_cid'] = $x['deny_cid']; + $arr['deny_gid'] = $x['deny_gid']; - $arr['uid'] = $channel['channel_id']; - $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['aid'] = $channel['channel_account_id']; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $channel['channel_hash']; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; - post_activity_item($arr); + post_activity_item($arr); } -function sync_an_item($channel_id,$item_id) { +function sync_an_item($channel_id, $item_id) +{ - $r = q("select * from item where id = %d", - intval($item_id) - ); - if($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel_d,array('item' => array(encode_item($sync_item[0],true)))); - } + $r = q( + "select * from item where id = %d", + intval($item_id) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($channel_d, array('item' => array(encode_item($sync_item[0], true)))); + } } -function list_attached_local_files($body) { +function list_attached_local_files($body) +{ - $files = []; - $match = []; - - // match img and zmg image links - if (preg_match_all("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/",$body,$match)) { - $images = $match[2]; - if ($images) { - foreach ($images as $image) { - if (! stristr($image,z_root() . '/photo/')) { - continue; - } - $image_uri = substr($image,strrpos($image,'/') + 1); - if (strpos($image_uri,'-') !== false) { - $image_uri = substr($image_uri,0, strrpos($image_uri,'-')); - } - if (strpos($image_uri,'.') !== false) { - $image_uri = substr($image_uri,0, strpos($image_uri,'.')); - } - if ($image_uri) { - $files[] = $image_uri; - } - } - } - } - if (preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",$body,$match)) { - $attaches = $match[1]; - if ($attaches) { - foreach ($attaches as $attach) { - $hash = substr($attach,0,strpos($attach,',')); - if ($hash) { - $files[] = $hash; - } - } - } - } + $files = []; + $match = []; - return $files; + // match img and zmg image links + if (preg_match_all("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/", $body, $match)) { + $images = $match[2]; + if ($images) { + foreach ($images as $image) { + if (! stristr($image, z_root() . '/photo/')) { + continue; + } + $image_uri = substr($image, strrpos($image, '/') + 1); + if (strpos($image_uri, '-') !== false) { + $image_uri = substr($image_uri, 0, strrpos($image_uri, '-')); + } + if (strpos($image_uri, '.') !== false) { + $image_uri = substr($image_uri, 0, strpos($image_uri, '.')); + } + if ($image_uri) { + $files[] = $image_uri; + } + } + } + } + if (preg_match_all("/\[attachment\](.*?)\[\/attachment\]/", $body, $match)) { + $attaches = $match[1]; + if ($attaches) { + foreach ($attaches as $attach) { + $hash = substr($attach, 0, strpos($attach, ',')); + if ($hash) { + $files[] = $hash; + } + } + } + } + + return $files; } -function fix_attached_permissions($uid,$body,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny,$token = EMPTY_STR) { +function fix_attached_permissions($uid, $body, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $token = EMPTY_STR) +{ - $files = list_attached_local_files($body); - if (! $files) { - return; - } + $files = list_attached_local_files($body); + if (! $files) { + return; + } - foreach ($files as $file) { - $attach_q = q("select id, hash, flags, is_photo, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d", - dbesc($file), - intval($uid) - ); + foreach ($files as $file) { + $attach_q = q( + "select id, hash, flags, is_photo, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d", + dbesc($file), + intval($uid) + ); - if (! $attach_q) { - continue; - } - - $attach = array_shift($attach_q); + if (! $attach_q) { + continue; + } - $match = null; - $existing_public = false; - $new_public = (($str_contact_allow||$str_group_allow||$str_contact_deny||$str_group_deny) ? false : true); - $existing_public = (($attach['allow_cid']||$attach['allow_gid']||$attach['deny_cid']||$attach['deny_gid']) ? false : true); + $attach = array_shift($attach_q); - if ($existing_public) { - // permissions have already been fixed and they are public. There's nothing for us to do. - continue; - } - - // if flags & 1, the attachment was uploaded directly into a post and needs to have permissions corrected - // or - if it is a private file and a new token was generated, we'll need to add the token to the ACL. + $match = null; + $existing_public = false; + $new_public = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? false : true); + $existing_public = (($attach['allow_cid'] || $attach['allow_gid'] || $attach['deny_cid'] || $attach['deny_gid']) ? false : true); - if (((intval($attach['flags']) & 1) !== 1) && (! $token)) { - continue; - } + if ($existing_public) { + // permissions have already been fixed and they are public. There's nothing for us to do. + continue; + } - $item_private = 0; + // if flags & 1, the attachment was uploaded directly into a post and needs to have permissions corrected + // or - if it is a private file and a new token was generated, we'll need to add the token to the ACL. - if ($new_public === false) { - - $item_private = (($str_group_allow) ? 1 : 2); + if (((intval($attach['flags']) & 1) !== 1) && (! $token)) { + continue; + } - // preserve any existing tokens that may have been set for this file - $token_matches = null; - if (preg_match_all('/\/',$attach['allow_cid'],$token_matches, PREG_SET_ORDER)) { - foreach ($token_matches as $m) { - $tok = ''; - if (strpos($str_contact_allow,$tok) === false) { - $str_contact_allow .= $tok; - } - } - } - if ($token) { - $str_contact_allow .= ''; - } - } + $item_private = 0; - q("update attach SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', flags = 0 + if ($new_public === false) { + $item_private = (($str_group_allow) ? 1 : 2); + + // preserve any existing tokens that may have been set for this file + $token_matches = null; + if (preg_match_all('/\/', $attach['allow_cid'], $token_matches, PREG_SET_ORDER)) { + foreach ($token_matches as $m) { + $tok = ''; + if (strpos($str_contact_allow, $tok) === false) { + $str_contact_allow .= $tok; + } + } + } + if ($token) { + $str_contact_allow .= ''; + } + } + + q( + "update attach SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', flags = 0 WHERE id = %d AND uid = %d", - dbesc($str_contact_allow), - dbesc($str_group_allow), - dbesc($str_contact_deny), - dbesc($str_group_deny), - intval($attach['id']), - intval($uid) - ); + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + intval($attach['id']), + intval($uid) + ); - if ($attach['is_photo']) { - $r = q("UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' + if ($attach['is_photo']) { + $r = q( + "UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' WHERE resource_id = '%s' AND uid = %d ", - dbesc($str_contact_allow), - dbesc($str_group_allow), - dbesc($str_contact_deny), - dbesc($str_group_deny), - dbesc($file), - intval($uid) - ); + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + dbesc($file), + intval($uid) + ); - $r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d + $r = q( + "UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d WHERE resource_id = '%s' AND 'resource_type' = 'photo' AND uid = %d", - dbesc($str_contact_allow), - dbesc($str_group_allow), - dbesc($str_contact_deny), - dbesc($str_group_deny), - intval($item_private), - dbesc($file), - intval($uid) - ); - } - } + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + intval($item_private), + dbesc($file), + intval($uid) + ); + } + } } -function item_create_edit_activity($post) { - // obsolete and not maintained, left in case it is ever needed again - if((! $post) || (! $post['item']) || ($post['item']['item_type'] != ITEM_TYPE_POST)) - return; +function item_create_edit_activity($post) +{ + // obsolete and not maintained, left in case it is ever needed again + if ((! $post) || (! $post['item']) || ($post['item']['item_type'] != ITEM_TYPE_POST)) { + return; + } - $update_item = $post['item']; + $update_item = $post['item']; - $new_item = $update_item; + $new_item = $update_item; - $author = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($new_item['author_xchan']) - ); - if($author) - $item_author = $author[0]; + $author = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($new_item['author_xchan']) + ); + if ($author) { + $item_author = $author[0]; + } - $new_item['id'] = 0; - $new_item['parent'] = 0; - $new_item['uuid'] = new_uuid(); - $new_item['mid'] = z_root() . '/item/' . $new_item['uuid']; + $new_item['id'] = 0; + $new_item['parent'] = 0; + $new_item['uuid'] = new_uuid(); + $new_item['mid'] = z_root() . '/item/' . $new_item['uuid']; - $new_item['body'] = sprintf( t('[Edited %s]'), (($update_item['item_thread_top']) ? t('Post','edit_activity') : t('Comment','edit_activity'))); + $new_item['body'] = sprintf(t('[Edited %s]'), (($update_item['item_thread_top']) ? t('Post', 'edit_activity') : t('Comment', 'edit_activity'))); - $new_item['body'] .= "\n\n"; - $new_item['body'] .= $update_item['body']; + $new_item['body'] .= "\n\n"; + $new_item['body'] .= $update_item['body']; - $new_item['sig'] = ''; + $new_item['sig'] = ''; - $new_item['verb'] = ACTIVITY_UPDATE; - $new_item['item_thread_top'] = 0; - $new_item['created'] = $new_item['edited'] = datetime_convert(); - $new_item['obj_type'] = (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT); - $new_item['obj'] = json_encode(array( - 'type' => $new_item['obj_type'], - 'id' => $update_item['mid'], - 'parent' => $update_item['parent_mid'], - 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $update_item['plink'])), - 'title' => $update_item['title'], - 'content' => $update_item['body'], - 'created' => $update_item['created'], - 'edited' => $update_item['edited'], - 'author' => array( - 'name' => $item_author['xchan_name'], - 'address' => $item_author['xchan_addr'], - 'guid' => $item_author['xchan_guid'], - 'guid_sig' => $item_author['xchan_guid_sig'], - 'link' => array( - array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']), - array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])), - ), - ),JSON_UNESCAPED_SLASHES); + $new_item['verb'] = ACTIVITY_UPDATE; + $new_item['item_thread_top'] = 0; + $new_item['created'] = $new_item['edited'] = datetime_convert(); + $new_item['obj_type'] = (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT); + $new_item['obj'] = json_encode(array( + 'type' => $new_item['obj_type'], + 'id' => $update_item['mid'], + 'parent' => $update_item['parent_mid'], + 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $update_item['plink'])), + 'title' => $update_item['title'], + 'content' => $update_item['body'], + 'created' => $update_item['created'], + 'edited' => $update_item['edited'], + 'author' => array( + 'name' => $item_author['xchan_name'], + 'address' => $item_author['xchan_addr'], + 'guid' => $item_author['xchan_guid'], + 'guid_sig' => $item_author['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']), + array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])), + ), + ), JSON_UNESCAPED_SLASHES); - $x = post_activity_item($new_item); + $x = post_activity_item($new_item); - $post_id = $x['id']; - if($post_id) { - $r = q("select * from item where id = %d", - intval($post_id) - ); - if($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($new_item['uid'],array('item' => array(encode_item($sync_item[0],true)))); - } - } + $post_id = $x['id']; + if ($post_id) { + $r = q( + "select * from item where id = %d", + intval($post_id) + ); + if ($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + Libsync::build_sync_packet($new_item['uid'], array('item' => array(encode_item($sync_item[0], true)))); + } + } - Run::Summon([ 'Notifier', 'edit_activity', $post_id ]); + Run::Summon([ 'Notifier', 'edit_activity', $post_id ]); } /** @@ -5015,68 +5190,71 @@ function item_create_edit_activity($post) { -function copy_of_pubitem($channel,$mid) { +function copy_of_pubitem($channel, $mid) +{ - $result = null; - $syschan = get_sys_channel(); + $result = null; + $syschan = get_sys_channel(); - logger('copy_of_pubitem: ' . $channel['channel_id'] . ' mid: ' . $mid); + logger('copy_of_pubitem: ' . $channel['channel_id'] . ' mid: ' . $mid); - $r = q("select * from item where mid = '%s' and uid = %d limit 1", - dbesc($mid), - intval($channel['channel_id']) - ); + $r = q( + "select * from item where mid = '%s' and uid = %d limit 1", + dbesc($mid), + intval($channel['channel_id']) + ); - if ($r) { - logger('exists'); - $item = fetch_post_tags($r,true); - return $item[0]; - } + if ($r) { + logger('exists'); + $item = fetch_post_tags($r, true); + return $item[0]; + } - // this query is used for the global public stream - $r = q("select * from item where parent_mid = ( select parent_mid from item where mid = '%s' and uid = %d ) order by id ", - dbesc($mid), - intval($syschan['channel_id']) - ); + // this query is used for the global public stream + $r = q( + "select * from item where parent_mid = ( select parent_mid from item where mid = '%s' and uid = %d ) order by id ", + dbesc($mid), + intval($syschan['channel_id']) + ); - // if that failed, try to find entries that would have been posted in the local public stream - if (! $r) { - $r = q("select * from item where parent_mid = ( select distinct (parent_mid) from item where mid = '%s' and item_wall = 1 and item_private = 0 ) order by id ", - dbesc($mid), - intval($syschan['channel_id']) - ); - } + // if that failed, try to find entries that would have been posted in the local public stream + if (! $r) { + $r = q( + "select * from item where parent_mid = ( select distinct (parent_mid) from item where mid = '%s' and item_wall = 1 and item_private = 0 ) order by id ", + dbesc($mid), + intval($syschan['channel_id']) + ); + } - - if ($r) { - $items = fetch_post_tags($r,true); - foreach ($items as $rv) { - $d = q("select id from item where mid = '%s' and uid = %d limit 1", - dbesc($rv['mid']), - intval($channel['channel_id']) - ); - if ($d) { - logger('mid: ' . $rv['mid'] . ' already copied. Continuing.'); - continue; - } - unset($rv['id']); - unset($rv['parent']); - $rv['aid'] = $channel['channel_account_id']; - $rv['uid'] = $channel['channel_id']; - $rv['item_wall'] = 0; - $rv['item_origin'] = 0; + if ($r) { + $items = fetch_post_tags($r, true); + foreach ($items as $rv) { + $d = q( + "select id from item where mid = '%s' and uid = %d limit 1", + dbesc($rv['mid']), + intval($channel['channel_id']) + ); + if ($d) { + logger('mid: ' . $rv['mid'] . ' already copied. Continuing.'); + continue; + } - $x = item_store($rv); - if ($x['item_id'] && $x['item']['mid'] === $mid) { - $result = $x['item']; - } + unset($rv['id']); + unset($rv['parent']); + $rv['aid'] = $channel['channel_account_id']; + $rv['uid'] = $channel['channel_id']; + $rv['item_wall'] = 0; + $rv['item_origin'] = 0; - } - } - else { - logger('copy query failed.'); - } - return $result; + $x = item_store($rv); + if ($x['item_id'] && $x['item']['mid'] === $mid) { + $result = $x['item']; + } + } + } else { + logger('copy query failed.'); + } + return $result; } diff --git a/include/js_strings.php b/include/js_strings.php index 4b9485a89..b59832dde 100644 --- a/include/js_strings.php +++ b/include/js_strings.php @@ -1,117 +1,120 @@ - '/images/' . PLATFORM_NAME . '-64.png', - '$delitem' => t('Delete this item?'), - '$comment' => t('Comment'), - '$showmore' => sprintf( t('%s show all'), ''), - '$showfewer' => sprintf( t('%s show less'), ''), - '$divgrowmore' => sprintf( t('%s expand'), ''), - '$divgrowless' => sprintf( t('%s collapse'),''), - '$pwshort' => t("Password too short"), - '$pwnomatch' => t("Passwords do not match"), - '$everybody' => t('everybody'), - '$passphrase' => t('Secret Passphrase'), - '$passhint' => t('Passphrase hint'), - '$permschange' => t('Notice: Permissions have changed but have not yet been submitted.'), - '$closeAll' => t('close all'), - '$nothingnew' => t('Nothing new here'), - '$rating_desc' => t('Rate This Channel (this is public)'), - '$rating_val' => t('Rating'), - '$rating_text' => t('Describe (optional)'), - '$submit' => t('Submit'), - '$linkurl' => t('Please enter a link URL'), - '$leavethispage' => t('Unsaved changes. Are you sure you wish to leave this page?'), - '$location' => t('Location'), - '$lovely' => t('lovely'), - '$wonderful' => t('wonderful'), - '$fantastic' => t('fantastic'), - '$great' => t('great'), - '$nick_invld1' => t('Your chosen nickname was either already taken or not valid. Please use our suggestion ('), - '$nick_invld2' => t(') or enter a new one.'), - '$nick_valid' => t('Thank you, this nickname is valid.'), - '$name_empty' => t('A channel name is required.'), - '$name_ok1' => t('This is a '), - '$name_ok2' => t(' channel name'), - '$pinned' => t('Pinned'), - '$pin_item' => t('Pin this post'), - '$unpin_item' => t('Unpin this post'), - '$tos' => t('Please accept terms to continue'), - - // translatable prefix and suffix strings for jquery.timeago - - // using the defaults set below if left untranslated, empty strings if - // translated to "NONE" and the corresponding language strings - // if translated to anything else - '$t01' => ((t('timeago.prefixAgo') == 'timeago.prefixAgo') ? '' : ((t('timeago.prefixAgo') == 'NONE') ? '' : t('timeago.prefixAgo'))), - '$t02' => ((t('timeago.prefixFromNow') == 'timeago.prefixFromNow') ? '' : ((t('timeago.prefixFromNow') == 'NONE') ? '' : t('timeago.prefixFromNow'))), - '$t03' => ((t('timeago.suffixAgo') == 'timeago.suffixAgo') ? 'ago' : ((t('timeago.suffixAgo') == 'NONE') ? '' : t('timeago.suffixAgo'))), - '$t04' => ((t('timeago.suffixFromNow') == 'timeago.suffixFromNow') ? 'from now' : ((t('timeago.suffixFromNow') == 'NONE') ? '' : t('timeago.suffixFromNow'))), +/** @file */ - // translatable main strings for jquery.timeago - '$t05' => t('less than a minute'), - '$t06' => t('about a minute'), - '$t07' => t('%d minutes'), - '$t08' => t('about an hour'), - '$t09' => t('about %d hours'), - '$t10' => t('a day'), - '$t11' => t('%d days'), - '$t12' => t('about a month'), - '$t13' => t('%d months'), - '$t14' => t('about a year'), - '$t15' => t('%d years'), - '$t16' => t(' '), // wordSeparator - '$t17' => ((t('timeago.numbers') != 'timeago.numbers') ? t('timeago.numbers') : '[]'), +function js_strings() +{ + return replace_macros(get_markup_template('js_strings.tpl'), array( + '$icon' => '/images/' . PLATFORM_NAME . '-64.png', + '$delitem' => t('Delete this item?'), + '$comment' => t('Comment'), + '$showmore' => sprintf(t('%s show all'), ''), + '$showfewer' => sprintf(t('%s show less'), ''), + '$divgrowmore' => sprintf(t('%s expand'), ''), + '$divgrowless' => sprintf(t('%s collapse'), ''), + '$pwshort' => t("Password too short"), + '$pwnomatch' => t("Passwords do not match"), + '$everybody' => t('everybody'), + '$passphrase' => t('Secret Passphrase'), + '$passhint' => t('Passphrase hint'), + '$permschange' => t('Notice: Permissions have changed but have not yet been submitted.'), + '$closeAll' => t('close all'), + '$nothingnew' => t('Nothing new here'), + '$rating_desc' => t('Rate This Channel (this is public)'), + '$rating_val' => t('Rating'), + '$rating_text' => t('Describe (optional)'), + '$submit' => t('Submit'), + '$linkurl' => t('Please enter a link URL'), + '$leavethispage' => t('Unsaved changes. Are you sure you wish to leave this page?'), + '$location' => t('Location'), + '$lovely' => t('lovely'), + '$wonderful' => t('wonderful'), + '$fantastic' => t('fantastic'), + '$great' => t('great'), + '$nick_invld1' => t('Your chosen nickname was either already taken or not valid. Please use our suggestion ('), + '$nick_invld2' => t(') or enter a new one.'), + '$nick_valid' => t('Thank you, this nickname is valid.'), + '$name_empty' => t('A channel name is required.'), + '$name_ok1' => t('This is a '), + '$name_ok2' => t(' channel name'), + '$pinned' => t('Pinned'), + '$pin_item' => t('Pin this post'), + '$unpin_item' => t('Unpin this post'), + '$tos' => t('Please accept terms to continue'), - '$January' => t('January'), - '$February' => t('February'), - '$March' => t('March'), - '$April' => t('April'), - '$May' => t('May','long'), - '$June' => t('June'), - '$July' => t('July'), - '$August' => t('August'), - '$September' => t('September'), - '$October' => t('October'), - '$November' => t('November'), - '$December' => t('December'), - '$Jan' => t('Jan'), - '$Feb' => t('Feb'), - '$Mar' => t('Mar'), - '$Apr' => t('Apr'), - '$MayShort' => t('May','short'), - '$Jun' => t('Jun'), - '$Jul' => t('Jul'), - '$Aug' => t('Aug'), - '$Sep' => t('Sep'), - '$Oct' => t('Oct'), - '$Nov' => t('Nov'), - '$Dec' => t('Dec'), - '$Sunday' => t('Sunday'), - '$Monday' => t('Monday'), - '$Tuesday' => t('Tuesday'), - '$Wednesday' => t('Wednesday'), - '$Thursday' => t('Thursday'), - '$Friday' => t('Friday'), - '$Saturday' => t('Saturday'), - '$Sun' => t('Sun'), - '$Mon' => t('Mon'), - '$Tue' => t('Tue'), - '$Wed' => t('Wed'), - '$Thu' => t('Thu'), - '$Fri' => t('Fri'), - '$Sat' => t('Sat'), - '$today' => t('today','calendar'), - '$month' => t('month','calendar'), - '$week' => t('week','calendar'), - '$day' => t('day','calendar'), - '$allday' => t('All day','calendar'), - '$channel_social' => t('A social networking profile that is public by default and private if desired'), - '$channel_social_restricted' => t('A social networking profile where content is private to your [Friends] Access List by default but can be made public if desired'), - '$channel_forum' => t('A public group where members are allowed to upload media by default'), - '$channel_forum_restricted' => t('A private group with no upload permission'), - '$channel_forum_moderated' => t('A public group where posts are moderated by the owner. The [moderated] permission may be removed from any group member once trust is established'), - '$channel_collection' =>t('A sub-channel of your main channel - often devoted to a specific language or topic. Replies are sent back to your main channel'), - '$channel_collection_restricted' =>t('A private sub-channel of your main channel - often devoted to a specific language or topic. Replies are sent back to your main channel'), - )); + // translatable prefix and suffix strings for jquery.timeago - + // using the defaults set below if left untranslated, empty strings if + // translated to "NONE" and the corresponding language strings + // if translated to anything else + '$t01' => ((t('timeago.prefixAgo') == 'timeago.prefixAgo') ? '' : ((t('timeago.prefixAgo') == 'NONE') ? '' : t('timeago.prefixAgo'))), + '$t02' => ((t('timeago.prefixFromNow') == 'timeago.prefixFromNow') ? '' : ((t('timeago.prefixFromNow') == 'NONE') ? '' : t('timeago.prefixFromNow'))), + '$t03' => ((t('timeago.suffixAgo') == 'timeago.suffixAgo') ? 'ago' : ((t('timeago.suffixAgo') == 'NONE') ? '' : t('timeago.suffixAgo'))), + '$t04' => ((t('timeago.suffixFromNow') == 'timeago.suffixFromNow') ? 'from now' : ((t('timeago.suffixFromNow') == 'NONE') ? '' : t('timeago.suffixFromNow'))), + + // translatable main strings for jquery.timeago + '$t05' => t('less than a minute'), + '$t06' => t('about a minute'), + '$t07' => t('%d minutes'), + '$t08' => t('about an hour'), + '$t09' => t('about %d hours'), + '$t10' => t('a day'), + '$t11' => t('%d days'), + '$t12' => t('about a month'), + '$t13' => t('%d months'), + '$t14' => t('about a year'), + '$t15' => t('%d years'), + '$t16' => t(' '), // wordSeparator + '$t17' => ((t('timeago.numbers') != 'timeago.numbers') ? t('timeago.numbers') : '[]'), + + '$January' => t('January'), + '$February' => t('February'), + '$March' => t('March'), + '$April' => t('April'), + '$May' => t('May', 'long'), + '$June' => t('June'), + '$July' => t('July'), + '$August' => t('August'), + '$September' => t('September'), + '$October' => t('October'), + '$November' => t('November'), + '$December' => t('December'), + '$Jan' => t('Jan'), + '$Feb' => t('Feb'), + '$Mar' => t('Mar'), + '$Apr' => t('Apr'), + '$MayShort' => t('May', 'short'), + '$Jun' => t('Jun'), + '$Jul' => t('Jul'), + '$Aug' => t('Aug'), + '$Sep' => t('Sep'), + '$Oct' => t('Oct'), + '$Nov' => t('Nov'), + '$Dec' => t('Dec'), + '$Sunday' => t('Sunday'), + '$Monday' => t('Monday'), + '$Tuesday' => t('Tuesday'), + '$Wednesday' => t('Wednesday'), + '$Thursday' => t('Thursday'), + '$Friday' => t('Friday'), + '$Saturday' => t('Saturday'), + '$Sun' => t('Sun'), + '$Mon' => t('Mon'), + '$Tue' => t('Tue'), + '$Wed' => t('Wed'), + '$Thu' => t('Thu'), + '$Fri' => t('Fri'), + '$Sat' => t('Sat'), + '$today' => t('today', 'calendar'), + '$month' => t('month', 'calendar'), + '$week' => t('week', 'calendar'), + '$day' => t('day', 'calendar'), + '$allday' => t('All day', 'calendar'), + '$channel_social' => t('A social networking profile that is public by default and private if desired'), + '$channel_social_restricted' => t('A social networking profile where content is private to your [Friends] Access List by default but can be made public if desired'), + '$channel_forum' => t('A public group where members are allowed to upload media by default'), + '$channel_forum_restricted' => t('A private group with no upload permission'), + '$channel_forum_moderated' => t('A public group where posts are moderated by the owner. The [moderated] permission may be removed from any group member once trust is established'), + '$channel_collection' => t('A sub-channel of your main channel - often devoted to a specific language or topic. Replies are sent back to your main channel'), + '$channel_collection_restricted' => t('A private sub-channel of your main channel - often devoted to a specific language or topic. Replies are sent back to your main channel'), + )); } diff --git a/include/language.php b/include/language.php index c40189e2b..7e6cf90b3 100644 --- a/include/language.php +++ b/include/language.php @@ -1,4 +1,5 @@ 0.8 - $langs = array_combine($lang_parse[1], $lang_parse[4]); + if (count($lang_parse[1])) { + // create a list like "en" => 0.8 + $langs = array_combine($lang_parse[1], $lang_parse[4]); - // set default to 1 for any without q factor - foreach ($langs as $lang => $val) { - if ($val === '') $langs[$lang] = 1; - } + // set default to 1 for any without q factor + foreach ($langs as $lang => $val) { + if ($val === '') { + $langs[$lang] = 1; + } + } - // sort list based on value - arsort($langs, SORT_NUMERIC); - } - } + // sort list based on value + arsort($langs, SORT_NUMERIC); + } + } - return $langs; + return $langs; } /** @@ -61,57 +68,58 @@ function get_browser_language() { * * @return Language code in 2-letter ISO 639-1 (en). */ -function get_best_language() { - $langs = get_browser_language(); +function get_best_language() +{ + $langs = get_browser_language(); - if(isset($langs) && count($langs)) { - foreach ($langs as $lang => $v) { - $lang = strtolower($lang); - if(is_dir("view/$lang")) { - $preferred = $lang; - break; - } - } - } + if (isset($langs) && count($langs)) { + foreach ($langs as $lang => $v) { + $lang = strtolower($lang); + if (is_dir("view/$lang")) { + $preferred = $lang; + break; + } + } + } - if(! isset($preferred)) { + if (! isset($preferred)) { + /* + * We could find no perfect match for any of the preferred languages. + * For cases where the preference is fr-fr and we have fr but *not* fr-fr + * run the test again and only look for the language base + * which should provide an interface they can sort of understand + */ - /* - * We could find no perfect match for any of the preferred languages. - * For cases where the preference is fr-fr and we have fr but *not* fr-fr - * run the test again and only look for the language base - * which should provide an interface they can sort of understand - */ + if (isset($langs) && count($langs)) { + foreach ($langs as $lang => $v) { + if (strlen($lang) === 2) { + /* we have already checked this language */ + continue; + } + /* Check the base */ + $lang = strtolower(substr($lang, 0, 2)); + if (is_dir("view/$lang")) { + $preferred = $lang; + break; + } + } + } + } - if(isset($langs) && count($langs)) { - foreach ($langs as $lang => $v) { - if(strlen($lang) === 2) { - /* we have already checked this language */ - continue; - } - /* Check the base */ - $lang = strtolower(substr($lang,0,2)); - if(is_dir("view/$lang")) { - $preferred = $lang; - break; - } - } - } - } + if (! isset($preferred)) { + $preferred = 'unset'; + } - if(! isset($preferred)) { - $preferred = 'unset'; - } + $arr = array('langs' => $langs, 'preferred' => $preferred); - $arr = array('langs' => $langs, 'preferred' => $preferred); + call_hooks('get_best_language', $arr); - call_hooks('get_best_language',$arr); + if ($arr['preferred'] !== 'unset') { + return $arr['preferred']; + } - if($arr['preferred'] !== 'unset') - return $arr['preferred']; - - return ((isset(App::$config['system']['language'])) ? App::$config['system']['language'] : 'en'); + return ((isset(App::$config['system']['language'])) ? App::$config['system']['language'] : 'en'); } /* @@ -121,32 +129,37 @@ function get_best_language() { */ -function push_lang($language) { +function push_lang($language) +{ - App::$langsave = App::$language; + App::$langsave = App::$language; - if($language === App::$language) - return; + if ($language === App::$language) { + return; + } - if(isset(App::$strings) && count(App::$strings)) { - App::$stringsave = App::$strings; - } - App::$strings = []; - load_translation_table($language); - App::$language = $language; + if (isset(App::$strings) && count(App::$strings)) { + App::$stringsave = App::$strings; + } + App::$strings = []; + load_translation_table($language); + App::$language = $language; } -function pop_lang() { +function pop_lang() +{ - if(App::$language === App::$langsave) - return; + if (App::$language === App::$langsave) { + return; + } - if(isset(App::$stringsave) && is_array(App::$stringsave)) - App::$strings = App::$stringsave; - else - App::$strings = []; + if (isset(App::$stringsave) && is_array(App::$stringsave)) { + App::$strings = App::$stringsave; + } else { + App::$strings = []; + } - App::$language = App::$langsave; + App::$language = App::$langsave; } /** @@ -155,32 +168,33 @@ function pop_lang() { * @param string $lang language code in 2-letter ISO 639-1 (en, de, fr) format * @param bool $install (optional) default false */ -function load_translation_table($lang, $install = false) { +function load_translation_table($lang, $install = false) +{ - App::$strings = []; + App::$strings = []; - if(file_exists("view/$lang/strings.php")) { - include("view/$lang/strings.php"); - } + if (file_exists("view/$lang/strings.php")) { + include("view/$lang/strings.php"); + } - if(! $install) { - $plugins = q("SELECT aname FROM addon WHERE installed=1;"); - if ($plugins !== false) { - foreach($plugins as $p) { - $name = $p['aname']; - if(file_exists("addon/$name/lang/$lang/strings.php")) { - include("addon/$name/lang/$lang/strings.php"); - } - } - } - } + if (! $install) { + $plugins = q("SELECT aname FROM addon WHERE installed=1;"); + if ($plugins !== false) { + foreach ($plugins as $p) { + $name = $p['aname']; + if (file_exists("addon/$name/lang/$lang/strings.php")) { + include("addon/$name/lang/$lang/strings.php"); + } + } + } + } - // Allow individual strings to be over-ridden on this site - // Either for the default language or for all languages + // Allow individual strings to be over-ridden on this site + // Either for the default language or for all languages - if(file_exists("view/local-$lang/strings.php")) { - include("view/local-$lang/strings.php"); - } + if (file_exists("view/local-$lang/strings.php")) { + include("view/local-$lang/strings.php"); + } } /** @@ -191,16 +205,17 @@ function load_translation_table($lang, $install = false) { * @return translated string if exists, otherwise return $s * */ -function t($s, $ctx = '') { +function t($s, $ctx = '') +{ - $cs = $ctx ? '__ctx:' . $ctx . '__ ' . $s : $s; - if (x(App::$strings, $cs)) { - $t = App::$strings[$cs]; + $cs = $ctx ? '__ctx:' . $ctx . '__ ' . $s : $s; + if (x(App::$strings, $cs)) { + $t = App::$strings[$cs]; - return ((is_array($t)) ? translate_projectname($t[0]) : translate_projectname($t)); - } + return ((is_array($t)) ? translate_projectname($t[0]) : translate_projectname($t)); + } - return translate_projectname($s); + return translate_projectname($s); } /** @@ -208,11 +223,12 @@ function t($s, $ctx = '') { * Merging strings from different project names is problematic so we'll do that with a string replacement */ -function translate_projectname($s) { - if (strpos($s,'rojectname') !== false) { - return str_replace( [ '$projectname','$Projectname' ], [ System::get_platform_name(), ucfirst(System::get_platform_name()) ],$s); - } - return $s; +function translate_projectname($s) +{ + if (strpos($s, 'rojectname') !== false) { + return str_replace([ '$projectname','$Projectname' ], [ System::get_platform_name(), ucfirst(System::get_platform_name()) ], $s); + } + return $s; } @@ -225,25 +241,27 @@ function translate_projectname($s) { * @param string $ctx * @return string */ -function tt($singular, $plural, $count, $ctx = ''){ +function tt($singular, $plural, $count, $ctx = '') +{ - $cs = $ctx ? "__ctx:" . $ctx . "__ " . $singular : $singular; - if (x(App::$strings,$cs)) { - $t = App::$strings[$cs]; - $f = 'string_plural_select_' . str_replace('-', '_', App::$language); - if (! function_exists($f)) - $f = 'string_plural_select_default'; + $cs = $ctx ? "__ctx:" . $ctx . "__ " . $singular : $singular; + if (x(App::$strings, $cs)) { + $t = App::$strings[$cs]; + $f = 'string_plural_select_' . str_replace('-', '_', App::$language); + if (! function_exists($f)) { + $f = 'string_plural_select_default'; + } - $k = $f(intval($count)); + $k = $f(intval($count)); - return is_array($t) ? $t[$k] : $t; - } + return is_array($t) ? $t[$k] : $t; + } - if ($count != 1) { - return $plural; - } else { - return $singular; - } + if ($count != 1) { + return $plural; + } else { + return $singular; + } } /** @@ -253,8 +271,9 @@ function tt($singular, $plural, $count, $ctx = ''){ * @param int $n * @return bool */ -function string_plural_select_default($n) { - return ($n != 1); +function string_plural_select_default($n) +{ + return ($n != 1); } /** @@ -275,47 +294,50 @@ function string_plural_select_default($n) { * This project: https://github.com/patrickschur/language-detection *may* be useful as a replacement. * */ -function detect_language($s) { +function detect_language($s) +{ - require_once('library/text_languagedetect/Text/LanguageDetect.php'); + require_once('library/text_languagedetect/Text/LanguageDetect.php'); - $min_length = get_config('system', 'language_detect_min_length'); - if ($min_length === false) - $min_length = LANGUAGE_DETECT_MIN_LENGTH; + $min_length = get_config('system', 'language_detect_min_length'); + if ($min_length === false) { + $min_length = LANGUAGE_DETECT_MIN_LENGTH; + } - $min_confidence = get_config('system', 'language_detect_min_confidence'); - if ($min_confidence === false) - $min_confidence = LANGUAGE_DETECT_MIN_CONFIDENCE; + $min_confidence = get_config('system', 'language_detect_min_confidence'); + if ($min_confidence === false) { + $min_confidence = LANGUAGE_DETECT_MIN_CONFIDENCE; + } - // embedded apps have long base64 strings which will trip up the detector. - $naked_body = preg_replace('/\[app\](.*?)\[\/app\]/', '', $s); - // strip off bbcode - $naked_body = preg_replace('/\[(.+?)\]/', '', $naked_body); - if (mb_strlen($naked_body) < intval($min_length)) { - logger('string length less than ' . intval($min_length), LOGGER_DATA); - return ''; - } + // embedded apps have long base64 strings which will trip up the detector. + $naked_body = preg_replace('/\[app\](.*?)\[\/app\]/', '', $s); + // strip off bbcode + $naked_body = preg_replace('/\[(.+?)\]/', '', $naked_body); + if (mb_strlen($naked_body) < intval($min_length)) { + logger('string length less than ' . intval($min_length), LOGGER_DATA); + return ''; + } - $l = new Text_LanguageDetect(); - try { - // return 2-letter ISO 639-1 (en) language code - $l->setNameMode(2); - $lng = $l->detectConfidence($naked_body); - logger('detect language: ' . print_r($lng, true) . $naked_body, LOGGER_DATA); - } catch (Text_LanguageDetect_Exception $e) { - logger('detect language exception: ' . $e->getMessage(), LOGGER_DATA); - } + $l = new Text_LanguageDetect(); + try { + // return 2-letter ISO 639-1 (en) language code + $l->setNameMode(2); + $lng = $l->detectConfidence($naked_body); + logger('detect language: ' . print_r($lng, true) . $naked_body, LOGGER_DATA); + } catch (Text_LanguageDetect_Exception $e) { + logger('detect language exception: ' . $e->getMessage(), LOGGER_DATA); + } - if ((! $lng) || (! (x($lng,'language')))) { - return ''; - } + if ((! $lng) || (! (x($lng, 'language')))) { + return ''; + } - if ($lng['confidence'] < (float) $min_confidence) { - logger('detect language: confidence less than ' . (float) $min_confidence, LOGGER_DATA); - return ''; - } + if ($lng['confidence'] < (float) $min_confidence) { + logger('detect language: confidence less than ' . (float) $min_confidence, LOGGER_DATA); + return ''; + } - return($lng['language']); + return($lng['language']); } /** @@ -332,85 +354,95 @@ function detect_language($s) { * @param string $l (optional) In which language to return the name * @return string with the language name, or $s if unrecognized */ -function get_language_name($s, $l = null) { - // get() expects the second part to be in upper case - if (strpos($s, '-') !== false) $s = substr($s, 0, 2) . strtoupper(substr($s, 2)); - if ($l !== null && strpos($l, '-') !== false) $l = substr($l, 0, 2) . strtoupper(substr($l, 2)); +function get_language_name($s, $l = null) +{ + // get() expects the second part to be in upper case + if (strpos($s, '-') !== false) { + $s = substr($s, 0, 2) . strtoupper(substr($s, 2)); + } + if ($l !== null && strpos($l, '-') !== false) { + $l = substr($l, 0, 2) . strtoupper(substr($l, 2)); + } - $languageRepository = new LanguageRepository(); + $languageRepository = new LanguageRepository(); - // Sometimes intl doesn't like the second part at all ... - try { - $language = $languageRepository->get($s, $l); - } catch(CommerceGuys\Intl\Exception\UnknownLanguageException $e) { - $s = substr($s, 0, 2); - if($l !== null) $l = substr($s, 0, 2); - try { - $language = $languageRepository->get($s, $l); - } catch (CommerceGuys\Intl\Exception\UnknownLanguageException $e) { - return $s; // Give up - } catch (CommerceGuys\Intl\Exception\UnknownLocaleException $e) { - return $s; // Give up - } - } + // Sometimes intl doesn't like the second part at all ... + try { + $language = $languageRepository->get($s, $l); + } catch (CommerceGuys\Intl\Exception\UnknownLanguageException $e) { + $s = substr($s, 0, 2); + if ($l !== null) { + $l = substr($s, 0, 2); + } + try { + $language = $languageRepository->get($s, $l); + } catch (CommerceGuys\Intl\Exception\UnknownLanguageException $e) { + return $s; // Give up + } catch (CommerceGuys\Intl\Exception\UnknownLocaleException $e) { + return $s; // Give up + } + } - return $language->getName(); + return $language->getName(); } -function language_list() { +function language_list() +{ - $langs = glob('view/*/strings.php'); + $langs = glob('view/*/strings.php'); - $lang_options = []; - $selected = ""; + $lang_options = []; + $selected = ""; - if(is_array($langs) && count($langs)) { - if(! in_array('view/en/strings.php',$langs)) - $langs[] = 'view/en/'; - asort($langs); - foreach($langs as $l) { - $ll = substr($l,5); - $ll = substr($ll,0,strrpos($ll,'/')); - $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)"; - } - } - return $lang_options; + if (is_array($langs) && count($langs)) { + if (! in_array('view/en/strings.php', $langs)) { + $langs[] = 'view/en/'; + } + asort($langs); + foreach ($langs as $l) { + $ll = substr($l, 5); + $ll = substr($ll, 0, strrpos($ll, '/')); + $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)"; + } + } + return $lang_options; } -function lang_selector() { +function lang_selector() +{ - $langs = glob('view/*/strings.php'); + $langs = glob('view/*/strings.php'); - $lang_options = []; - $selected = ""; + $lang_options = []; + $selected = ""; - if(is_array($langs) && count($langs)) { - $langs[] = ''; - if(! in_array('view/en/strings.php',$langs)) - $langs[] = 'view/en/'; - asort($langs); - foreach($langs as $l) { - if($l == '') { - $lang_options[""] = t('default'); - continue; - } - $ll = substr($l,5); - $ll = substr($ll,0,strrpos($ll,'/')); - $selected = (($ll === App::$language && (x($_SESSION, 'language'))) ? $ll : $selected); - $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)"; - } - } + if (is_array($langs) && count($langs)) { + $langs[] = ''; + if (! in_array('view/en/strings.php', $langs)) { + $langs[] = 'view/en/'; + } + asort($langs); + foreach ($langs as $l) { + if ($l == '') { + $lang_options[""] = t('default'); + continue; + } + $ll = substr($l, 5); + $ll = substr($ll, 0, strrpos($ll, '/')); + $selected = (($ll === App::$language && (x($_SESSION, 'language'))) ? $ll : $selected); + $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)"; + } + } - $tpl = get_markup_template('lang_selector.tpl'); + $tpl = get_markup_template('lang_selector.tpl'); - $o = replace_macros($tpl, array( - '$title' => t('Select an alternate language'), - '$langs' => array($lang_options, $selected), + $o = replace_macros($tpl, array( + '$title' => t('Select an alternate language'), + '$langs' => array($lang_options, $selected), - )); + )); - return $o; + return $o; } - diff --git a/include/menu.php b/include/menu.php index ac9674446..0ac4f9a78 100644 --- a/include/menu.php +++ b/include/menu.php @@ -1,5 +1,6 @@ - $r[0], 'items' => $x ); - } + intval($r[0]['menu_id']), + intval($uid) + ); + return array('menu' => $r[0], 'items' => $x ); + } - return null; + return null; } - -function menu_element($channel,$menu) { - $arr = []; - $arr['type'] = 'menu'; - $arr['pagetitle'] = $menu['menu']['menu_name']; - $arr['desc'] = $menu['menu']['menu_desc']; - $arr['created'] = $menu['menu']['menu_created']; - $arr['edited'] = $menu['menu']['menu_edited']; +function menu_element($channel, $menu) +{ - $arr['baseurl'] = z_root(); - if($menu['menu']['menu_flags']) { - $arr['flags'] = []; - if($menu['menu']['menu_flags'] & MENU_BOOKMARK) - $arr['flags'][] = 'bookmark'; - if($menu['menu']['menu_flags'] & MENU_SYSTEM) - $arr['flags'][] = 'system'; - } - if($menu['items']) { - $arr['items'] = []; - foreach($menu['items'] as $it) { - $entry = []; + $arr = []; + $arr['type'] = 'menu'; + $arr['pagetitle'] = $menu['menu']['menu_name']; + $arr['desc'] = $menu['menu']['menu_desc']; + $arr['created'] = $menu['menu']['menu_created']; + $arr['edited'] = $menu['menu']['menu_edited']; - $entry['link'] = str_replace(z_root() . '/channel/' . $channel['channel_address'],'[channelurl]',$it['mitem_link']); - $entry['link'] = str_replace(z_root() . '/page/' . $channel['channel_address'],'[pageurl]',$it['mitem_link']); - $entry['link'] = str_replace(z_root() . '/cloud/' . $channel['channel_address'],'[cloudurl]',$it['mitem_link']); - $entry['link'] = str_replace(z_root(),'[baseurl]',$it['mitem_link']); + $arr['baseurl'] = z_root(); + if ($menu['menu']['menu_flags']) { + $arr['flags'] = []; + if ($menu['menu']['menu_flags'] & MENU_BOOKMARK) { + $arr['flags'][] = 'bookmark'; + } + if ($menu['menu']['menu_flags'] & MENU_SYSTEM) { + $arr['flags'][] = 'system'; + } + } + if ($menu['items']) { + $arr['items'] = []; + foreach ($menu['items'] as $it) { + $entry = []; - $entry['desc'] = $it['mitem_desc']; - $entry['order'] = $it['mitem_order']; - if($it['mitem_flags']) { - $entry['flags'] = []; - if($it['mitem_flags'] & MENU_ITEM_ZID) - $entry['flags'][] = 'zid'; - if($it['mitem_flags'] & MENU_ITEM_NEWWIN) - $entry['flags'][] = 'new-window'; - if($it['mitem_flags'] & MENU_ITEM_CHATROOM) - $entry['flags'][] = 'chatroom'; - } - $arr['items'][] = $entry; - } - } + $entry['link'] = str_replace(z_root() . '/channel/' . $channel['channel_address'], '[channelurl]', $it['mitem_link']); + $entry['link'] = str_replace(z_root() . '/page/' . $channel['channel_address'], '[pageurl]', $it['mitem_link']); + $entry['link'] = str_replace(z_root() . '/cloud/' . $channel['channel_address'], '[cloudurl]', $it['mitem_link']); + $entry['link'] = str_replace(z_root(), '[baseurl]', $it['mitem_link']); - return $arr; + $entry['desc'] = $it['mitem_desc']; + $entry['order'] = $it['mitem_order']; + if ($it['mitem_flags']) { + $entry['flags'] = []; + if ($it['mitem_flags'] & MENU_ITEM_ZID) { + $entry['flags'][] = 'zid'; + } + if ($it['mitem_flags'] & MENU_ITEM_NEWWIN) { + $entry['flags'][] = 'new-window'; + } + if ($it['mitem_flags'] & MENU_ITEM_CHATROOM) { + $entry['flags'][] = 'chatroom'; + } + } + $arr['items'][] = $entry; + } + } + + return $arr; } -function menu_render($menu, $class='', $edit = false, $var = []) { +function menu_render($menu, $class = '', $edit = false, $var = []) +{ - if(! $menu) - return ''; + if (! $menu) { + return ''; + } - $channel_id = ((is_array(App::$profile)) ? App::$profile['profile_uid'] : 0); - if ((! $channel_id) && (local_channel())) - $channel_id = local_channel(); + $channel_id = ((is_array(App::$profile)) ? App::$profile['profile_uid'] : 0); + if ((! $channel_id) && (local_channel())) { + $channel_id = local_channel(); + } - $chan = channelx_by_n($channel_id); - if(! $chan) - return ''; + $chan = channelx_by_n($channel_id); + if (! $chan) { + return ''; + } - $menu_list = menu_list($channel_id); - $menu_names = []; + $menu_list = menu_list($channel_id); + $menu_names = []; - foreach($menu_list as $menus) { - if($menus['menu_name'] != $menu['menu']['menu_name']) - $menu_names[] = $menus['menu_name']; - } + foreach ($menu_list as $menus) { + if ($menus['menu_name'] != $menu['menu']['menu_name']) { + $menu_names[] = $menus['menu_name']; + } + } - for($x = 0; $x < count($menu['items']); $x ++) { - if(in_array($menu['items'][$x]['mitem_link'], $menu_names)) { - $m = menu_fetch($menu['items'][$x]['mitem_link'], $channel_id, get_observer_hash()); - $submenu = menu_render($m, 'dropdown-menu', $edit = false, array('wrap' => 'none')); - $menu['items'][$x]['submenu'] = $submenu; - } + for ($x = 0; $x < count($menu['items']); $x++) { + if (in_array($menu['items'][$x]['mitem_link'], $menu_names)) { + $m = menu_fetch($menu['items'][$x]['mitem_link'], $channel_id, get_observer_hash()); + $submenu = menu_render($m, 'dropdown-menu', $edit = false, array('wrap' => 'none')); + $menu['items'][$x]['submenu'] = $submenu; + } - if($menu['items'][$x]['mitem_flags'] & MENU_ITEM_ZID) - $menu['items'][$x]['mitem_link'] = zid($menu['items'][$x]['mitem_link']); + if ($menu['items'][$x]['mitem_flags'] & MENU_ITEM_ZID) { + $menu['items'][$x]['mitem_link'] = zid($menu['items'][$x]['mitem_link']); + } - if($menu['items'][$x]['mitem_flags'] & MENU_ITEM_NEWWIN) - $menu['items'][$x]['newwin'] = '1'; + if ($menu['items'][$x]['mitem_flags'] & MENU_ITEM_NEWWIN) { + $menu['items'][$x]['newwin'] = '1'; + } - $menu['items'][$x]['mitem_desc'] = zidify_links(smilies(bbcode($menu['items'][$x]['mitem_desc']))); - } + $menu['items'][$x]['mitem_desc'] = zidify_links(smilies(bbcode($menu['items'][$x]['mitem_desc']))); + } - $wrap = (($var['wrap'] === 'none') ? false : true); + $wrap = (($var['wrap'] === 'none') ? false : true); - $ret = replace_macros(get_markup_template('usermenu.tpl'),array( - '$menu' => $menu['menu'], - '$class' => $class, - '$nick' => $chan['channel_address'], - '$edit' => (($edit) ? t("Edit") : ''), - '$id' => $menu['menu']['menu_id'], - '$items' => $menu['items'], - '$wrap' => $wrap - )); + $ret = replace_macros(get_markup_template('usermenu.tpl'), array( + '$menu' => $menu['menu'], + '$class' => $class, + '$nick' => $chan['channel_address'], + '$edit' => (($edit) ? t("Edit") : ''), + '$id' => $menu['menu']['menu_id'], + '$items' => $menu['items'], + '$wrap' => $wrap + )); - return $ret; + return $ret; } -function menu_fetch_id($menu_id,$channel_id) { +function menu_fetch_id($menu_id, $channel_id) +{ - $r = q("select * from menu where menu_id = %d and menu_channel_id = %d limit 1", - intval($menu_id), - intval($channel_id) - ); + $r = q( + "select * from menu where menu_id = %d and menu_channel_id = %d limit 1", + intval($menu_id), + intval($channel_id) + ); - return (($r) ? $r[0] : false); + return (($r) ? $r[0] : false); } -function menu_create($arr) { - $menu_name = trim(escape_tags($arr['menu_name'])); - $menu_desc = trim(escape_tags($arr['menu_desc'])); - $menu_flags = intval($arr['menu_flags']); +function menu_create($arr) +{ + $menu_name = trim(escape_tags($arr['menu_name'])); + $menu_desc = trim(escape_tags($arr['menu_desc'])); + $menu_flags = intval($arr['menu_flags']); - //allow menu_desc (title) to be empty - //if(! $menu_desc) - // $menu_desc = $menu_name; + //allow menu_desc (title) to be empty + //if(! $menu_desc) + // $menu_desc = $menu_name; - if(! $menu_name) - return false; + if (! $menu_name) { + return false; + } - if(! $menu_flags) - $menu_flags = 0; + if (! $menu_flags) { + $menu_flags = 0; + } - $menu_channel_id = intval($arr['menu_channel_id']); + $menu_channel_id = intval($arr['menu_channel_id']); - $r = q("select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1", - dbesc($menu_name), - intval($menu_channel_id) - ); + $r = q( + "select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1", + dbesc($menu_name), + intval($menu_channel_id) + ); - if($r) - return false; + if ($r) { + return false; + } - $t = datetime_convert(); + $t = datetime_convert(); - $r = q("insert into menu ( menu_name, menu_desc, menu_flags, menu_channel_id, menu_created, menu_edited ) + $r = q( + "insert into menu ( menu_name, menu_desc, menu_flags, menu_channel_id, menu_created, menu_edited ) values( '%s', '%s', %d, %d, '%s', '%s' )", - dbesc($menu_name), - dbesc($menu_desc), - intval($menu_flags), - intval($menu_channel_id), - dbesc(datetime_convert('UTC','UTC',(($arr['menu_created']) ? $arr['menu_created'] : $t))), - dbesc(datetime_convert('UTC','UTC',(($arr['menu_edited']) ? $arr['menu_edited'] : $t))) - ); - if(! $r) - return false; - - $r = q("select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", - dbesc($menu_name), - intval($menu_channel_id) - ); - if($r) - return $r[0]['menu_id']; - return false; + dbesc($menu_name), + dbesc($menu_desc), + intval($menu_flags), + intval($menu_channel_id), + dbesc(datetime_convert('UTC', 'UTC', (($arr['menu_created']) ? $arr['menu_created'] : $t))), + dbesc(datetime_convert('UTC', 'UTC', (($arr['menu_edited']) ? $arr['menu_edited'] : $t))) + ); + if (! $r) { + return false; + } + $r = q( + "select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", + dbesc($menu_name), + intval($menu_channel_id) + ); + if ($r) { + return $r[0]['menu_id']; + } + return false; } /** @@ -197,218 +224,245 @@ function menu_create($arr) { * bits set. We will use this to find system generated bookmarks. */ -function menu_list($channel_id, $name = '', $flags = 0) { +function menu_list($channel_id, $name = '', $flags = 0) +{ - $sel_options = ''; - $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : ''); - $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : ''); + $sel_options = ''; + $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : ''); + $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : ''); - $r = q("select * from menu where menu_channel_id = %d $sel_options order by menu_desc", - intval($channel_id) - ); - return $r; + $r = q( + "select * from menu where menu_channel_id = %d $sel_options order by menu_desc", + intval($channel_id) + ); + return $r; } -function menu_list_count($channel_id, $name = '', $flags = 0) { +function menu_list_count($channel_id, $name = '', $flags = 0) +{ - $sel_options = ''; - $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : ''); - $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : ''); + $sel_options = ''; + $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : ''); + $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : ''); - $r = q("select count(*) as total from menu where menu_channel_id = %d $sel_options", - intval($channel_id) - ); - return $r[0]['total']; + $r = q( + "select count(*) as total from menu where menu_channel_id = %d $sel_options", + intval($channel_id) + ); + return $r[0]['total']; } -function menu_edit($arr) { +function menu_edit($arr) +{ - $menu_id = intval($arr['menu_id']); + $menu_id = intval($arr['menu_id']); - $menu_name = trim(escape_tags($arr['menu_name'])); - $menu_desc = trim(escape_tags($arr['menu_desc'])); - $menu_flags = intval($arr['menu_flags']); + $menu_name = trim(escape_tags($arr['menu_name'])); + $menu_desc = trim(escape_tags($arr['menu_desc'])); + $menu_flags = intval($arr['menu_flags']); - //allow menu_desc (title) to be empty - //if(! $menu_desc) - // $menu_desc = $menu_name; + //allow menu_desc (title) to be empty + //if(! $menu_desc) + // $menu_desc = $menu_name; - if(! $menu_name) - return false; + if (! $menu_name) { + return false; + } - if(! $menu_flags) - $menu_flags = 0; + if (! $menu_flags) { + $menu_flags = 0; + } - $menu_channel_id = intval($arr['menu_channel_id']); + $menu_channel_id = intval($arr['menu_channel_id']); - $r = q("select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", - dbesc($menu_name), - intval($menu_channel_id) - ); - if(($r) && ($r[0]['menu_id'] != $menu_id)) { - logger('menu_edit: duplicate menu name for channel ' . $menu_channel_id); - return false; - } + $r = q( + "select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", + dbesc($menu_name), + intval($menu_channel_id) + ); + if (($r) && ($r[0]['menu_id'] != $menu_id)) { + logger('menu_edit: duplicate menu name for channel ' . $menu_channel_id); + 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) - ); - if(! $r) { - logger('menu_edit: not found: ' . print_r($arr,true)); - 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) + ); + if (! $r) { + logger('menu_edit: not found: ' . print_r($arr, true)); + return false; + } - return q("update menu set menu_name = '%s', menu_desc = '%s', menu_flags = %d, menu_edited = '%s' - where menu_id = %d and menu_channel_id = %d", - dbesc($menu_name), - dbesc($menu_desc), - intval($menu_flags), - dbesc(datetime_convert()), - intval($menu_id), - intval($menu_channel_id) - ); + return q( + "update menu set menu_name = '%s', menu_desc = '%s', menu_flags = %d, menu_edited = '%s' + where menu_id = %d and menu_channel_id = %d", + dbesc($menu_name), + dbesc($menu_desc), + intval($menu_flags), + dbesc(datetime_convert()), + intval($menu_id), + intval($menu_channel_id) + ); } -function menu_delete($menu_name, $uid) { - $r = q("select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", - dbesc($menu_name), - intval($uid) - ); +function menu_delete($menu_name, $uid) +{ + $r = q( + "select menu_id from menu where menu_name = '%s' and menu_channel_id = %d limit 1", + dbesc($menu_name), + intval($uid) + ); - if($r) - return menu_delete_id($r[0]['menu_id'],$uid); - return false; + if ($r) { + return menu_delete_id($r[0]['menu_id'], $uid); + } + return false; } -function menu_delete_id($menu_id, $uid) { - $r = q("select menu_id from menu where menu_id = %d and menu_channel_id = %d limit 1", - intval($menu_id), - intval($uid) - ); - if($r) { - $x = q("delete from menu_item where mitem_menu_id = %d and mitem_channel_id = %d", - intval($menu_id), - intval($uid) - ); - return q("delete from menu where menu_id = %d and menu_channel_id = %d", - intval($menu_id), - intval($uid) - ); - } - return false; +function menu_delete_id($menu_id, $uid) +{ + $r = q( + "select menu_id from menu where menu_id = %d and menu_channel_id = %d limit 1", + intval($menu_id), + intval($uid) + ); + if ($r) { + $x = q( + "delete from menu_item where mitem_menu_id = %d and mitem_channel_id = %d", + intval($menu_id), + intval($uid) + ); + return q( + "delete from menu where menu_id = %d and menu_channel_id = %d", + intval($menu_id), + intval($uid) + ); + } + return false; } -function menu_add_item($menu_id, $uid, $arr) { +function menu_add_item($menu_id, $uid, $arr) +{ - $mitem_link = escape_tags($arr['mitem_link']); - $mitem_desc = escape_tags($arr['mitem_desc']); - $mitem_order = intval($arr['mitem_order']); - $mitem_flags = intval($arr['mitem_flags']); + $mitem_link = escape_tags($arr['mitem_link']); + $mitem_desc = escape_tags($arr['mitem_desc']); + $mitem_order = intval($arr['mitem_order']); + $mitem_flags = intval($arr['mitem_flags']); - if(local_channel() == $uid) { - $channel = App::get_channel(); - } + if (local_channel() == $uid) { + $channel = App::get_channel(); + } - $acl = new Zotlabs\Access\AccessControl($channel); - $acl->set_from_array($arr); - $p = $acl->get(); + $acl = new Zotlabs\Access\AccessControl($channel); + $acl->set_from_array($arr); + $p = $acl->get(); - $r = q("insert into menu_item ( mitem_link, mitem_desc, mitem_flags, allow_cid, allow_gid, deny_cid, deny_gid, mitem_channel_id, mitem_menu_id, mitem_order ) values ( '%s', '%s', %d, '%s', '%s', '%s', '%s', %d, %d, %d ) ", - dbesc($mitem_link), - dbesc($mitem_desc), - intval($mitem_flags), - dbesc($p['allow_cid']), - dbesc($p['allow_gid']), - dbesc($p['deny_cid']), - dbesc($p['deny_gid']), - intval($uid), - intval($menu_id), - intval($mitem_order) - ); + $r = q( + "insert into menu_item ( mitem_link, mitem_desc, mitem_flags, allow_cid, allow_gid, deny_cid, deny_gid, mitem_channel_id, mitem_menu_id, mitem_order ) values ( '%s', '%s', %d, '%s', '%s', '%s', '%s', %d, %d, %d ) ", + dbesc($mitem_link), + dbesc($mitem_desc), + intval($mitem_flags), + dbesc($p['allow_cid']), + dbesc($p['allow_gid']), + dbesc($p['deny_cid']), + dbesc($p['deny_gid']), + intval($uid), + intval($menu_id), + intval($mitem_order) + ); - $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", - dbesc(datetime_convert()), - intval($menu_id), - intval($uid) - ); - - return $r; + $x = q( + "update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", + dbesc(datetime_convert()), + intval($menu_id), + intval($uid) + ); + return $r; } -function menu_edit_item($menu_id, $uid, $arr) { +function menu_edit_item($menu_id, $uid, $arr) +{ - $mitem_id = intval($arr['mitem_id']); - $mitem_link = escape_tags($arr['mitem_link']); - $mitem_desc = escape_tags($arr['mitem_desc']); - $mitem_order = intval($arr['mitem_order']); - $mitem_flags = intval($arr['mitem_flags']); + $mitem_id = intval($arr['mitem_id']); + $mitem_link = escape_tags($arr['mitem_link']); + $mitem_desc = escape_tags($arr['mitem_desc']); + $mitem_order = intval($arr['mitem_order']); + $mitem_flags = intval($arr['mitem_flags']); - if(local_channel() == $uid) { - $channel = App::get_channel(); - } + if (local_channel() == $uid) { + $channel = App::get_channel(); + } - $acl = new Zotlabs\Access\AccessControl($channel); - $acl->set_from_array($arr); - $p = $acl->get(); + $acl = new Zotlabs\Access\AccessControl($channel); + $acl->set_from_array($arr); + $p = $acl->get(); - $r = q("update menu_item set mitem_link = '%s', mitem_desc = '%s', mitem_flags = %d, allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', mitem_order = %d where mitem_channel_id = %d and mitem_menu_id = %d and mitem_id = %d", - dbesc($mitem_link), - dbesc($mitem_desc), - intval($mitem_flags), - dbesc($p['allow_cid']), - dbesc($p['allow_gid']), - dbesc($p['deny_cid']), - dbesc($p['deny_gid']), - intval($mitem_order), - intval($uid), - intval($menu_id), - intval($mitem_id) - ); + $r = q( + "update menu_item set mitem_link = '%s', mitem_desc = '%s', mitem_flags = %d, allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', mitem_order = %d where mitem_channel_id = %d and mitem_menu_id = %d and mitem_id = %d", + dbesc($mitem_link), + dbesc($mitem_desc), + intval($mitem_flags), + dbesc($p['allow_cid']), + dbesc($p['allow_gid']), + dbesc($p['deny_cid']), + dbesc($p['deny_gid']), + intval($mitem_order), + intval($uid), + intval($menu_id), + intval($mitem_id) + ); - $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", - dbesc(datetime_convert()), - intval($menu_id), - intval($uid) - ); + $x = q( + "update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", + dbesc(datetime_convert()), + intval($menu_id), + intval($uid) + ); - return $r; + return $r; } -function menu_del_item($menu_id,$uid,$item_id) { - $r = q("delete from menu_item where mitem_menu_id = %d and mitem_channel_id = %d and mitem_id = %d", - intval($menu_id), - intval($uid), - intval($item_id) - ); +function menu_del_item($menu_id, $uid, $item_id) +{ + $r = q( + "delete from menu_item where mitem_menu_id = %d and mitem_channel_id = %d and mitem_id = %d", + intval($menu_id), + intval($uid), + intval($item_id) + ); - $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", - dbesc(datetime_convert()), - intval($menu_id), - intval($uid) - ); + $x = q( + "update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", + dbesc(datetime_convert()), + intval($menu_id), + intval($uid) + ); - return $r; + return $r; } -function menu_sync_packet($uid,$observer_hash,$menu_id,$delete = false) { - $r = menu_fetch_id($menu_id,$uid); - $c = channelx_by_n($uid); - if($r) { - $m = menu_fetch($r['menu_name'],$uid,$observer_hash); - if($m) { - if($delete) - $m['menu_delete'] = 1; - Libsync::build_sync_packet($uid,array('menu' => array(menu_element($c,$m)))); - } - } +function menu_sync_packet($uid, $observer_hash, $menu_id, $delete = false) +{ + $r = menu_fetch_id($menu_id, $uid); + $c = channelx_by_n($uid); + if ($r) { + $m = menu_fetch($r['menu_name'], $uid, $observer_hash); + if ($m) { + if ($delete) { + $m['menu_delete'] = 1; + } + Libsync::build_sync_packet($uid, array('menu' => array(menu_element($c, $m)))); + } + } } diff --git a/include/nav.php b/include/nav.php index ca3e08adc..d3cc8e381 100644 --- a/include/nav.php +++ b/include/nav.php @@ -1,534 +1,536 @@ -$(document).ready(function() { $("#nav-search-text").search_autocomplete(\'' . z_root() . '/acl' . '\');});'; - - $is_owner = (((local_channel()) && ((App::$profile_uid == local_channel()) || (App::$profile_uid == 0))) ? true : false); - - if(local_channel()) { - $channel = App::get_channel(); - $observer = App::get_observer(); - $prof = q("select id from profile where uid = %d and is_default = 1", - intval($channel['channel_id']) - ); - - if(! (isset($_SESSION['delegate']) && $_SESSION['delegate'])) { - $chans = q("select channel_name, channel_id from channel left join pconfig on channel_id = pconfig.uid where channel_account_id = %d and channel_removed = 0 and pconfig.cat = 'system' and pconfig.k = 'include_in_menu' and pconfig.v = '1' order by channel_name ", - intval(get_account_id()) - ); - $q = get_sys_channel(); - if (is_site_admin() && intval(get_pconfig($q['channel_id'],'system','include_in_menu'))) { - $chans = array_merge([$q],$chans); - } - } - - $sitelocation = (($is_owner) ? '' : App::$profile['reddress']); - } - elseif(remote_channel()) { - $observer = App::get_observer(); - $sitelocation = ((App::$profile['reddress']) ? App::$profile['reddress'] : '@' . App::get_hostname()); - } - - require_once('include/conversation.php'); - - - $channel_apps[] = ((isset(App::$profile)) ? channel_apps($is_owner, App::$profile['channel_address']) : []); - - $site_icon = System::get_site_icon(); - - $banner = System::get_site_name(); - if (! isset(App::$page['header'])) { - App::$page['header'] = EMPTY_STR; - } - App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array( - //we could additionally use this to display important system notifications e.g. for updates - )); - - - // nav links: array of array('href', 'text', 'extra css classes', 'title') - $nav = []; - - if(can_view_public_stream()) - $nav['pubs'] = true; - - /** - * Display login or logout - */ - - $nav['usermenu'] = []; - $userinfo = null; - $nav['loginmenu'] = []; - - if($observer) { - $userinfo = [ - 'icon' => $observer['xchan_photo_m'].'?rev='.strtotime($observer['xchan_photo_date']), - 'name' => $observer['xchan_addr'], - ]; - } - - elseif(! $_SESSION['authenticated']) { - $nav['remote_login'] = remote_login(); - $nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn'); - } - - if(local_channel()) { - - if(! (isset($_SESSION['delegate']) && $_SESSION['delegate'])) { - $nav['manage'] = array('manage', t('Channels'), "", t('Manage your channels'),'manage_nav_btn'); - } - - $nav['group'] = array('lists', t('Lists'),"", t('Manage your access lists'),'group_nav_btn'); - - $nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn'); - - $nav['safe'] = array('safe', t('Safe Mode'), ((get_safemode()) ? t('(is on)') : t('(is off)')) , t('Content filtering'),'safe_nav_btn'); - - - if ($chans && count($chans) > 0) { - $nav['channels'] = $chans; - } - - $nav['logout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; - - // user menu - $nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), ((App::$nav_sel['raw_name'] == 'Profile') ? 'active' : ''), t('Your profile page'),'profile_nav_btn']; - - if(feature_enabled(local_channel(),'multi_profiles')) - $nav['usermenu'][] = ['profiles', t('Edit Profiles'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : '') , t('Manage/Edit profiles'),'profiles_nav_btn']; - else - $nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : ''), t('Edit your profile'),'profiles_nav_btn']; - - } - else { - if(! get_account_id()) { - if(App::$module === 'channel') { - $nav['login'] = login(true,'navbar-login',false,false); - $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'']; - } - else { - $nav['login'] = login(true,'navbar-login',false,false); - $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'login_nav_btn']; - App::$page['content'] .= replace_macros(get_markup_template('nav_login.tpl'), - [ - '$nav' => $nav, - 'userinfo' => $userinfo - ] - ); - } - } - else - $nav['alogout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; - - - } - - $my_url = get_my_url(); - if(! $my_url) { - $observer = App::get_observer(); - $my_url = (($observer) ? $observer['xchan_url'] : ''); - } - - $homelink_arr = parse_url($my_url); - $homelink = $homelink_arr['scheme'] . '://' . $homelink_arr['host']; - - if(! $is_owner) { - $nav['rusermenu'] = array( - $homelink, - t('Take me home'), - 'logout', - ((local_channel()) ? t('Logout') : t('Log me out of this site')) - ); - } - - if(((get_config('system','register_policy') == REGISTER_OPEN) || (get_config('system','register_policy') == REGISTER_APPROVE)) && (! $_SESSION['authenticated'])) - $nav['register'] = ['register',t('Register'), "", t('Create an account'),'register_nav_btn']; - - if(! get_config('system','hide_help',true)) { - $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; - $context_help = ''; - $enable_context_help = ((intval(get_config('system','enable_context_help')) === 1 || get_config('system','enable_context_help') === false) ? true : false); - if($enable_context_help === true) { - require_once('include/help.php'); - $context_help = load_context_help(); - //point directly to /help if $context_help is empty - this can be removed once we have context help for all modules - $enable_context_help = (($context_help) ? true : false); - } - $nav['help'] = [$help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help]; - } - - - $search_form_action = 'search'; - - - $nav['search'] = ['search', t('Search'), "", t('Search site @name, #tag, ?doc, content'), $search_form_action]; - - /** - * Admin page - */ - if (is_site_admin()) { - $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration'),'admin_nav_btn'); - } - - $x = array('nav' => $nav, 'usermenu' => $userinfo ); - - call_hooks('nav', $x); - - // Not sure the best place to put this on the page. So I'm implementing it but leaving it - // turned off until somebody discovers this and figures out a good location for it. - $powered_by = ''; - - if(App::$profile_uid && App::$nav_sel['raw_name']) { - $active_app = q("SELECT app_url FROM app WHERE app_channel = %d AND app_name = '%s' LIMIT 1", - intval(App::$profile_uid), - dbesc(App::$nav_sel['raw_name']) - ); - - if($active_app) { - $url = $active_app[0]['app_url']; - } - } - - $pinned_list = []; - $syslist = []; - - //app bin - if($is_owner) { - if(get_pconfig(local_channel(), 'system','import_system_apps') !== datetime_convert('UTC','UTC','now','Y-m-d')) { - Apps::import_system_apps(); - set_pconfig(local_channel(), 'system','import_system_apps', datetime_convert('UTC','UTC','now','Y-m-d')); - } - - $list = Apps::app_list(local_channel(), false, [ 'nav_pinned_app' ]); - if($list) { - foreach($list as $li) { - $pinned_list[] = Apps::app_encode($li); - } - } - Apps::translate_system_apps($pinned_list); - - usort($pinned_list,'Zotlabs\\Lib\\Apps::app_name_compare'); - - $pinned_list = Apps::app_order(local_channel(),$pinned_list, 'nav_pinned_app'); - - - $syslist = []; - $list = Apps::app_list(local_channel(), false, [ 'nav_featured_app' ]); - - if($list) { - foreach($list as $li) { - $syslist[] = Apps::app_encode($li); - } - } - Apps::translate_system_apps($syslist); - - - } - else { - $syslist = Apps::get_system_apps(true); - } - - usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare'); - - $syslist = Apps::app_order(local_channel(),$syslist, 'nav_featured_app'); - - - if($pinned_list) { - foreach($pinned_list as $app) { - if(App::$nav_sel['name'] == $app['name']) - $app['active'] = true; - - if($is_owner) { - $navbar_apps[] = Apps::app_render($app,'navbar'); - } - elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) { - $navbar_apps[] = Apps::app_render($app,'navbar'); - } - } - } - - if($syslist) { - foreach($syslist as $app) { - if(App::$nav_sel['name'] == $app['name']) - $app['active'] = true; - - if($is_owner) { - $nav_apps[] = Apps::app_render($app,'nav'); - } - elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) { - $nav_apps[] = Apps::app_render($app,'nav'); - } - } - } - - $c = theme_include('navbar_' . purify_filename($template) . '.css'); - $tpl = get_markup_template('navbar_' . purify_filename($template) . '.tpl'); - - if($c && $tpl) { - head_add_css('navbar_' . $template . '.css'); - } - - if(! $tpl) { - $tpl = get_markup_template('navbar_default.tpl'); - } - - App::$page['nav'] .= replace_macros($tpl, array( - '$baseurl' => z_root(), - '$project_icon' => $site_icon, - '$project_title' => t('Powered by $Projectname'), - '$fulldocs' => t('Help'), - '$sitelocation' => $sitelocation, - '$nav' => $x['nav'], - '$banner' => $banner, - '$emptynotifications' => t('Loading'), - '$userinfo' => $x['usermenu'], - '$localuser' => local_channel(), - '$is_owner' => $is_owner, - '$sel' => App::$nav_sel, - '$powered_by' => $powered_by, - '$help' => t('@name, #tag, ?doc, content'), - '$pleasewait' => t('Please wait...'), - '$nav_apps' => ((isset($nav_apps)) ? $nav_apps : []), - '$navbar_apps' => ((isset($navbar_apps)) ? $navbar_apps : []), - '$channel_menu' => get_pconfig(App::$profile_uid,'system','channel_menu',get_config('system','channel_menu')), - '$channel_thumb' => ((App::$profile) ? App::$profile['thumb'] : ''), - '$channel_apps' => ((isset($channel_apps)) ? $channel_apps : []), - '$manageapps' => t('Installed Apps'), - '$addapps' => t('Available Apps'), - '$orderapps' => t('Arrange Apps'), - '$sysapps_toggle' => t('Toggle System Apps'), - '$url' => ((isset($url) && $url) ? $url : App::$cmd) - )); - - if(x($_SESSION, 'reload_avatar') && $observer) { - // The avatar has been changed on the server but the browser doesn't know that, - // force the browser to reload the image from the server instead of its cache. - $tpl = get_markup_template('force_image_reload.tpl'); - - App::$page['nav'] .= replace_macros($tpl, array( - '$imgUrl' => $observer['xchan_photo_m'] - )); - unset($_SESSION['reload_avatar']); - } - - call_hooks('page_header', App::$page['nav']); + if (! isset(App::$page['nav'])) { + App::$page['nav'] = EMPTY_STR; + } + if (! isset(App::$page['htmlhead'])) { + App::$page['htmlhead'] = EMPTY_STR; + } + + App::$page['htmlhead'] .= ''; + + $is_owner = (((local_channel()) && ((App::$profile_uid == local_channel()) || (App::$profile_uid == 0))) ? true : false); + + if (local_channel()) { + $channel = App::get_channel(); + $observer = App::get_observer(); + $prof = q( + "select id from profile where uid = %d and is_default = 1", + intval($channel['channel_id']) + ); + + if (! (isset($_SESSION['delegate']) && $_SESSION['delegate'])) { + $chans = q( + "select channel_name, channel_id from channel left join pconfig on channel_id = pconfig.uid where channel_account_id = %d and channel_removed = 0 and pconfig.cat = 'system' and pconfig.k = 'include_in_menu' and pconfig.v = '1' order by channel_name ", + intval(get_account_id()) + ); + $q = get_sys_channel(); + if (is_site_admin() && intval(get_pconfig($q['channel_id'], 'system', 'include_in_menu'))) { + $chans = array_merge([$q], $chans); + } + } + + $sitelocation = (($is_owner) ? '' : App::$profile['reddress']); + } elseif (remote_channel()) { + $observer = App::get_observer(); + $sitelocation = ((App::$profile['reddress']) ? App::$profile['reddress'] : '@' . App::get_hostname()); + } + + require_once('include/conversation.php'); + + + $channel_apps[] = ((isset(App::$profile)) ? channel_apps($is_owner, App::$profile['channel_address']) : []); + + $site_icon = System::get_site_icon(); + + $banner = System::get_site_name(); + if (! isset(App::$page['header'])) { + App::$page['header'] = EMPTY_STR; + } + App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array( + //we could additionally use this to display important system notifications e.g. for updates + )); + + + // nav links: array of array('href', 'text', 'extra css classes', 'title') + $nav = []; + + if (can_view_public_stream()) { + $nav['pubs'] = true; + } + + /** + * Display login or logout + */ + + $nav['usermenu'] = []; + $userinfo = null; + $nav['loginmenu'] = []; + + if ($observer) { + $userinfo = [ + 'icon' => $observer['xchan_photo_m'] . '?rev=' . strtotime($observer['xchan_photo_date']), + 'name' => $observer['xchan_addr'], + ]; + } elseif (! $_SESSION['authenticated']) { + $nav['remote_login'] = remote_login(); + $nav['loginmenu'][] = array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn'); + } + + if (local_channel()) { + if (! (isset($_SESSION['delegate']) && $_SESSION['delegate'])) { + $nav['manage'] = array('manage', t('Channels'), "", t('Manage your channels'),'manage_nav_btn'); + } + + $nav['group'] = array('lists', t('Lists'),"", t('Manage your access lists'),'group_nav_btn'); + + $nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn'); + + $nav['safe'] = array('safe', t('Safe Mode'), ((get_safemode()) ? t('(is on)') : t('(is off)')) , t('Content filtering'),'safe_nav_btn'); + + + if ($chans && count($chans) > 0) { + $nav['channels'] = $chans; + } + + $nav['logout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; + + // user menu + $nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), ((App::$nav_sel['raw_name'] == 'Profile') ? 'active' : ''), t('Your profile page'),'profile_nav_btn']; + + if (feature_enabled(local_channel(), 'multi_profiles')) { + $nav['usermenu'][] = ['profiles', t('Edit Profiles'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : '') , t('Manage/Edit profiles'),'profiles_nav_btn']; + } else { + $nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : ''), t('Edit your profile'),'profiles_nav_btn']; + } + } else { + if (! get_account_id()) { + if (App::$module === 'channel') { + $nav['login'] = login(true, 'navbar-login', false, false); + $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'']; + } else { + $nav['login'] = login(true, 'navbar-login', false, false); + $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'login_nav_btn']; + App::$page['content'] .= replace_macros( + get_markup_template('nav_login.tpl'), + [ + '$nav' => $nav, + 'userinfo' => $userinfo + ] + ); + } + } else { + $nav['alogout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; + } + } + + $my_url = get_my_url(); + if (! $my_url) { + $observer = App::get_observer(); + $my_url = (($observer) ? $observer['xchan_url'] : ''); + } + + $homelink_arr = parse_url($my_url); + $homelink = $homelink_arr['scheme'] . '://' . $homelink_arr['host']; + + if (! $is_owner) { + $nav['rusermenu'] = array( + $homelink, + t('Take me home'), + 'logout', + ((local_channel()) ? t('Logout') : t('Log me out of this site')) + ); + } + + if (((get_config('system', 'register_policy') == REGISTER_OPEN) || (get_config('system', 'register_policy') == REGISTER_APPROVE)) && (! $_SESSION['authenticated'])) { + $nav['register'] = ['register',t('Register'), "", t('Create an account'),'register_nav_btn']; + } + + if (! get_config('system', 'hide_help', true)) { + $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; + $context_help = ''; + $enable_context_help = ((intval(get_config('system', 'enable_context_help')) === 1 || get_config('system', 'enable_context_help') === false) ? true : false); + if ($enable_context_help === true) { + require_once('include/help.php'); + $context_help = load_context_help(); + //point directly to /help if $context_help is empty - this can be removed once we have context help for all modules + $enable_context_help = (($context_help) ? true : false); + } + $nav['help'] = [$help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help]; + } + + + $search_form_action = 'search'; + + + $nav['search'] = ['search', t('Search'), "", t('Search site @name, #tag, ?doc, content'), $search_form_action]; + + /** + * Admin page + */ + if (is_site_admin()) { + $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration'),'admin_nav_btn'); + } + + $x = array('nav' => $nav, 'usermenu' => $userinfo ); + + call_hooks('nav', $x); + + // Not sure the best place to put this on the page. So I'm implementing it but leaving it + // turned off until somebody discovers this and figures out a good location for it. + $powered_by = ''; + + if (App::$profile_uid && App::$nav_sel['raw_name']) { + $active_app = q( + "SELECT app_url FROM app WHERE app_channel = %d AND app_name = '%s' LIMIT 1", + intval(App::$profile_uid), + dbesc(App::$nav_sel['raw_name']) + ); + + if ($active_app) { + $url = $active_app[0]['app_url']; + } + } + + $pinned_list = []; + $syslist = []; + + //app bin + if ($is_owner) { + if (get_pconfig(local_channel(), 'system', 'import_system_apps') !== datetime_convert('UTC', 'UTC', 'now', 'Y-m-d')) { + Apps::import_system_apps(); + set_pconfig(local_channel(), 'system', 'import_system_apps', datetime_convert('UTC', 'UTC', 'now', 'Y-m-d')); + } + + $list = Apps::app_list(local_channel(), false, [ 'nav_pinned_app' ]); + if ($list) { + foreach ($list as $li) { + $pinned_list[] = Apps::app_encode($li); + } + } + Apps::translate_system_apps($pinned_list); + + usort($pinned_list, 'Zotlabs\\Lib\\Apps::app_name_compare'); + + $pinned_list = Apps::app_order(local_channel(), $pinned_list, 'nav_pinned_app'); + + + $syslist = []; + $list = Apps::app_list(local_channel(), false, [ 'nav_featured_app' ]); + + if ($list) { + foreach ($list as $li) { + $syslist[] = Apps::app_encode($li); + } + } + Apps::translate_system_apps($syslist); + } else { + $syslist = Apps::get_system_apps(true); + } + + usort($syslist, 'Zotlabs\\Lib\\Apps::app_name_compare'); + + $syslist = Apps::app_order(local_channel(), $syslist, 'nav_featured_app'); + + + if ($pinned_list) { + foreach ($pinned_list as $app) { + if (App::$nav_sel['name'] == $app['name']) { + $app['active'] = true; + } + + if ($is_owner) { + $navbar_apps[] = Apps::app_render($app, 'navbar'); + } elseif (! $is_owner && strpos($app['requires'], 'local_channel') === false) { + $navbar_apps[] = Apps::app_render($app, 'navbar'); + } + } + } + + if ($syslist) { + foreach ($syslist as $app) { + if (App::$nav_sel['name'] == $app['name']) { + $app['active'] = true; + } + + if ($is_owner) { + $nav_apps[] = Apps::app_render($app, 'nav'); + } elseif (! $is_owner && strpos($app['requires'], 'local_channel') === false) { + $nav_apps[] = Apps::app_render($app, 'nav'); + } + } + } + + $c = theme_include('navbar_' . purify_filename($template) . '.css'); + $tpl = get_markup_template('navbar_' . purify_filename($template) . '.tpl'); + + if ($c && $tpl) { + head_add_css('navbar_' . $template . '.css'); + } + + if (! $tpl) { + $tpl = get_markup_template('navbar_default.tpl'); + } + + App::$page['nav'] .= replace_macros($tpl, array( + '$baseurl' => z_root(), + '$project_icon' => $site_icon, + '$project_title' => t('Powered by $Projectname'), + '$fulldocs' => t('Help'), + '$sitelocation' => $sitelocation, + '$nav' => $x['nav'], + '$banner' => $banner, + '$emptynotifications' => t('Loading'), + '$userinfo' => $x['usermenu'], + '$localuser' => local_channel(), + '$is_owner' => $is_owner, + '$sel' => App::$nav_sel, + '$powered_by' => $powered_by, + '$help' => t('@name, #tag, ?doc, content'), + '$pleasewait' => t('Please wait...'), + '$nav_apps' => ((isset($nav_apps)) ? $nav_apps : []), + '$navbar_apps' => ((isset($navbar_apps)) ? $navbar_apps : []), + '$channel_menu' => get_pconfig(App::$profile_uid, 'system', 'channel_menu', get_config('system', 'channel_menu')), + '$channel_thumb' => ((App::$profile) ? App::$profile['thumb'] : ''), + '$channel_apps' => ((isset($channel_apps)) ? $channel_apps : []), + '$manageapps' => t('Installed Apps'), + '$addapps' => t('Available Apps'), + '$orderapps' => t('Arrange Apps'), + '$sysapps_toggle' => t('Toggle System Apps'), + '$url' => ((isset($url) && $url) ? $url : App::$cmd) + )); + + if (x($_SESSION, 'reload_avatar') && $observer) { + // The avatar has been changed on the server but the browser doesn't know that, + // force the browser to reload the image from the server instead of its cache. + $tpl = get_markup_template('force_image_reload.tpl'); + + App::$page['nav'] .= replace_macros($tpl, array( + '$imgUrl' => $observer['xchan_photo_m'] + )); + unset($_SESSION['reload_avatar']); + } + + call_hooks('page_header', App::$page['nav']); } /* * Set a menu item in navbar as selected - * + * */ -function nav_set_selected($item){ - App::$nav_sel['raw_name'] = $item; - $item = ['name' => $item]; - Apps::translate_system_apps($item); - App::$nav_sel['name'] = $item['name']; +function nav_set_selected($item) +{ + App::$nav_sel['raw_name'] = $item; + $item = ['name' => $item]; + Apps::translate_system_apps($item); + App::$nav_sel['name'] = $item['name']; } -function channel_apps($is_owner = false, $nickname = null) { +function channel_apps($is_owner = false, $nickname = null) +{ - // Don't provide any channel apps if we're running as the sys channel + // Don't provide any channel apps if we're running as the sys channel - if(App::$is_sys) - return ''; + if (App::$is_sys) { + return ''; + } - $channel = App::get_channel(); + $channel = App::get_channel(); - if($channel && is_null($nickname)) - $nickname = $channel['channel_address']; + if ($channel && is_null($nickname)) { + $nickname = $channel['channel_address']; + } - $uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel()); - $account_id = ((App::$profile['profile_uid']) ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']); + $uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel()); + $account_id = ((App::$profile['profile_uid']) ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']); - if (! get_pconfig($uid, 'system', 'channelapps','1')) { - return ''; - } + if (! get_pconfig($uid, 'system', 'channelapps', '1')) { + return ''; + } - if($uid == local_channel()) { - return; - } - else { - $cal_link = '/cal/' . $nickname; - } + if ($uid == local_channel()) { + return; + } else { + $cal_link = '/cal/' . $nickname; + } - $sql_options = item_permissions_sql($uid); + $sql_options = item_permissions_sql($uid); - $r = q("select item.* from item left join iconfig on item.id = iconfig.iid + $r = q( + "select item.* from item left join iconfig on item.id = iconfig.iid where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0 and item.item_deleted = 0 and ( iconfig.k = 'WEBPAGE' and item_type = %d ) $sql_options limit 1", - intval($uid), - dbesc('home'), - intval(ITEM_TYPE_WEBPAGE) - ); + intval($uid), + dbesc('home'), + intval(ITEM_TYPE_WEBPAGE) + ); - $has_webpages = (($r) ? true : false); + $has_webpages = (($r) ? true : false); - if(x($_GET, 'tab')) - $tab = notags(trim($_GET['tab'])); + if (x($_GET, 'tab')) { + $tab = notags(trim($_GET['tab'])); + } - $url = z_root() . '/channel/' . $nickname; - $pr = z_root() . '/profile/' . $nickname; + $url = z_root() . '/channel/' . $nickname; + $pr = z_root() . '/profile/' . $nickname; - $tabs = [ - [ - 'label' => t('Channel'), - 'url' => $url, - 'sel' => ((argv(0) == 'channel') ? 'active' : ''), - 'title' => t('Status Messages and Posts'), - 'id' => 'status-tab', - 'icon' => 'home' - ], - ]; + $tabs = [ + [ + 'label' => t('Channel'), + 'url' => $url, + 'sel' => ((argv(0) == 'channel') ? 'active' : ''), + 'title' => t('Status Messages and Posts'), + 'id' => 'status-tab', + 'icon' => 'home' + ], + ]; - $p = get_all_perms($uid,get_observer_hash()); + $p = get_all_perms($uid, get_observer_hash()); - if ($p['view_profile']) { - $tabs[] = [ - 'label' => t('About'), - 'url' => $pr, - 'sel' => ((argv(0) == 'profile') ? 'active' : ''), - 'title' => t('Profile Details'), - 'id' => 'profile-tab', - 'icon' => 'user' - ]; - } - if ($p['view_storage']) { - $tabs[] = [ - 'label' => t('Photos'), - 'url' => z_root() . '/photos/' . $nickname, - 'sel' => ((argv(0) == 'photos') ? 'active' : ''), - 'title' => t('Photo Albums'), - 'id' => 'photo-tab', - 'icon' => 'photo' - ]; - $tabs[] = [ - 'label' => t('Files'), - 'url' => z_root() . '/cloud/' . $nickname, - 'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''), - 'title' => t('Files and Storage'), - 'id' => 'files-tab', - 'icon' => 'folder-open' - ]; - } + if ($p['view_profile']) { + $tabs[] = [ + 'label' => t('About'), + 'url' => $pr, + 'sel' => ((argv(0) == 'profile') ? 'active' : ''), + 'title' => t('Profile Details'), + 'id' => 'profile-tab', + 'icon' => 'user' + ]; + } + if ($p['view_storage']) { + $tabs[] = [ + 'label' => t('Photos'), + 'url' => z_root() . '/photos/' . $nickname, + 'sel' => ((argv(0) == 'photos') ? 'active' : ''), + 'title' => t('Photo Albums'), + 'id' => 'photo-tab', + 'icon' => 'photo' + ]; + $tabs[] = [ + 'label' => t('Files'), + 'url' => z_root() . '/cloud/' . $nickname, + 'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''), + 'title' => t('Files and Storage'), + 'id' => 'files-tab', + 'icon' => 'folder-open' + ]; + } - if($p['view_stream'] && $cal_link) { - $tabs[] = [ - 'label' => t('Calendar'), - 'url' => z_root() . $cal_link, - 'sel' => ((argv(0) == 'cal') ? 'active' : ''), - 'title' => t('Calendar'), - 'id' => 'event-tab', - 'icon' => 'calendar' - ]; - } + if ($p['view_stream'] && $cal_link) { + $tabs[] = [ + 'label' => t('Calendar'), + 'url' => z_root() . $cal_link, + 'sel' => ((argv(0) == 'cal') ? 'active' : ''), + 'title' => t('Calendar'), + 'id' => 'event-tab', + 'icon' => 'calendar' + ]; + } - if ($p['chat'] && Apps::system_app_installed($uid,'Chatrooms')) { - $has_chats = Chatroom::list_count($uid); - if ($has_chats) { - $tabs[] = [ - 'label' => t('Chatrooms'), - 'url' => z_root() . '/chat/' . $nickname, - 'sel' => ((argv(0) == 'chat') ? 'active' : '' ), - 'title' => t('Chatrooms'), - 'id' => 'chat-tab', - 'icon' => 'comments-o' - ]; - } - } + if ($p['chat'] && Apps::system_app_installed($uid, 'Chatrooms')) { + $has_chats = Chatroom::list_count($uid); + if ($has_chats) { + $tabs[] = [ + 'label' => t('Chatrooms'), + 'url' => z_root() . '/chat/' . $nickname, + 'sel' => ((argv(0) == 'chat') ? 'active' : '' ), + 'title' => t('Chatrooms'), + 'id' => 'chat-tab', + 'icon' => 'comments-o' + ]; + } + } - $has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK); - if ($is_owner && $has_bookmarks) { - $tabs[] = [ - 'label' => t('Bookmarks'), - 'url' => z_root() . '/bookmarks', - 'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''), - 'title' => t('Saved Bookmarks'), - 'id' => 'bookmarks-tab', - 'icon' => 'bookmark' - ]; - } + $has_bookmarks = menu_list_count(local_channel(), '', MENU_BOOKMARK) + menu_list_count(local_channel(), '', MENU_SYSTEM | MENU_BOOKMARK); + if ($is_owner && $has_bookmarks) { + $tabs[] = [ + 'label' => t('Bookmarks'), + 'url' => z_root() . '/bookmarks', + 'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''), + 'title' => t('Saved Bookmarks'), + 'id' => 'bookmarks-tab', + 'icon' => 'bookmark' + ]; + } - if($p['view_pages'] && Apps::system_app_installed($uid, 'Cards')) { - $tabs[] = [ - 'label' => t('Cards'), - 'url' => z_root() . '/cards/' . $nickname , - 'sel' => ((argv(0) == 'cards') ? 'active' : ''), - 'title' => t('View Cards'), - 'id' => 'cards-tab', - 'icon' => 'list' - ]; - } + if ($p['view_pages'] && Apps::system_app_installed($uid, 'Cards')) { + $tabs[] = [ + 'label' => t('Cards'), + 'url' => z_root() . '/cards/' . $nickname , + 'sel' => ((argv(0) == 'cards') ? 'active' : ''), + 'title' => t('View Cards'), + 'id' => 'cards-tab', + 'icon' => 'list' + ]; + } - if($p['view_pages'] && Apps::system_app_installed($uid, 'Articles')) { - $tabs[] = [ - 'label' => t('Articles'), - 'url' => z_root() . '/articles/' . $nickname , - 'sel' => ((argv(0) == 'articles') ? 'active' : ''), - 'title' => t('View Articles'), - 'id' => 'articles-tab', - 'icon' => 'file-text-o' - ]; - } + if ($p['view_pages'] && Apps::system_app_installed($uid, 'Articles')) { + $tabs[] = [ + 'label' => t('Articles'), + 'url' => z_root() . '/articles/' . $nickname , + 'sel' => ((argv(0) == 'articles') ? 'active' : ''), + 'title' => t('View Articles'), + 'id' => 'articles-tab', + 'icon' => 'file-text-o' + ]; + } - if($has_webpages && Apps::system_app_installed($uid, 'Webpages')) { - $tabs[] = [ - 'label' => t('Webpages'), - 'url' => z_root() . '/page/' . $nickname . '/home', - 'sel' => ((argv(0) == 'webpages') ? 'active' : ''), - 'title' => t('View Webpages'), - 'id' => 'webpages-tab', - 'icon' => 'newspaper-o' - ]; - } - + if ($has_webpages && Apps::system_app_installed($uid, 'Webpages')) { + $tabs[] = [ + 'label' => t('Webpages'), + 'url' => z_root() . '/page/' . $nickname . '/home', + 'sel' => ((argv(0) == 'webpages') ? 'active' : ''), + 'title' => t('View Webpages'), + 'id' => 'webpages-tab', + 'icon' => 'newspaper-o' + ]; + } - if ($p['view_wiki'] && Apps::system_app_installed($uid, 'Wiki')) { - $tabs[] = [ - 'label' => t('Wikis'), - 'url' => z_root() . '/wiki/' . $nickname, - 'sel' => ((argv(0) == 'wiki') ? 'active' : ''), - 'title' => t('Wiki'), - 'id' => 'wiki-tab', - 'icon' => 'pencil-square-o' - ]; - } + if ($p['view_wiki'] && Apps::system_app_installed($uid, 'Wiki')) { + $tabs[] = [ + 'label' => t('Wikis'), + 'url' => z_root() . '/wiki/' . $nickname, + 'sel' => ((argv(0) == 'wiki') ? 'active' : ''), + 'title' => t('Wiki'), + 'id' => 'wiki-tab', + 'icon' => 'pencil-square-o' + ]; + } - $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); + $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); - call_hooks('channel_apps', $arr); + call_hooks('channel_apps', $arr); - return replace_macros(get_markup_template('profile_tabs.tpl'), - [ - '$tabs' => $arr['tabs'], - '$name' => App::$profile['channel_name'], - '$thumb' => App::$profile['thumb'], - ] - ); + return replace_macros( + get_markup_template('profile_tabs.tpl'), + [ + '$tabs' => $arr['tabs'], + '$name' => App::$profile['channel_name'], + '$thumb' => App::$profile['thumb'], + ] + ); } diff --git a/include/network.php b/include/network.php index 6e0c1a252..02eb138c1 100644 --- a/include/network.php +++ b/include/network.php @@ -13,7 +13,6 @@ use Zotlabs\Lib\LDSignatures; use Zotlabs\Web\HTTPSig; use Zotlabs\Daemon\Run; - /** * @file include/network.php * @brief Network related functions. @@ -24,8 +23,9 @@ use Zotlabs\Daemon\Run; * * @return string */ -function get_capath() { - return appdirpath() . '/library/cacert.pem'; +function get_capath() +{ + return appdirpath() . '/library/cacert.pem'; } /** @@ -55,201 +55,218 @@ function get_capath() { * * \e string \b header => HTTP headers * * \e string \b body => fetched content */ -function z_fetch_url($url, $binary = false, $redirects = 0, $opts = []) { +function z_fetch_url($url, $binary = false, $redirects = 0, $opts = []) +{ - $ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => ""); - $passthru = false; + $ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => ""); + $passthru = false; - $ch = @curl_init($url); - if(($redirects > 8) || (! $ch)) - return $ret; + $ch = @curl_init($url); + if (($redirects > 8) || (! $ch)) { + return $ret; + } - if(! array_key_exists('request_target',$opts)) { - $opts['request_target'] = 'get ' . get_request_string($url); - } + if (! array_key_exists('request_target', $opts)) { + $opts['request_target'] = 'get ' . get_request_string($url); + } - @curl_setopt($ch, CURLOPT_HEADER, true); - @curl_setopt($ch, CURLINFO_HEADER_OUT, true); - @curl_setopt($ch, CURLOPT_CAINFO, get_capath()); - @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); - @curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); - @curl_setopt($ch, CURLOPT_ENCODING, ''); - - $ciphers = @get_config('system','curl_ssl_ciphers'); - if($ciphers) - @curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, $ciphers); + @curl_setopt($ch, CURLOPT_HEADER, true); + @curl_setopt($ch, CURLINFO_HEADER_OUT, true); + @curl_setopt($ch, CURLOPT_CAINFO, get_capath()); + @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($ch, CURLOPT_ENCODING, ''); - if(x($opts,'filep')) { - @curl_setopt($ch, CURLOPT_FILE, $opts['filep']); - @curl_setopt($ch, CURLOPT_HEADER, false); - @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - $passthru = true; - } + $ciphers = @get_config('system', 'curl_ssl_ciphers'); + if ($ciphers) { + @curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, $ciphers); + } - if (x($opts,'useragent')) { - @curl_setopt($ch, CURLOPT_USERAGENT, $opts['useragent']); - } - else { - @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)"); - } + if (x($opts, 'filep')) { + @curl_setopt($ch, CURLOPT_FILE, $opts['filep']); + @curl_setopt($ch, CURLOPT_HEADER, false); + @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + $passthru = true; + } - if(x($opts,'upload')) - @curl_setopt($ch, CURLOPT_UPLOAD, $opts['upload']); + if (x($opts, 'useragent')) { + @curl_setopt($ch, CURLOPT_USERAGENT, $opts['useragent']); + } else { + @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)"); + } - if(x($opts,'infile')) - @curl_setopt($ch, CURLOPT_INFILE, $opts['infile']); + if (x($opts, 'upload')) { + @curl_setopt($ch, CURLOPT_UPLOAD, $opts['upload']); + } - if(x($opts,'infilesize')) - @curl_setopt($ch, CURLOPT_INFILESIZE, $opts['infilesize']); + if (x($opts, 'infile')) { + @curl_setopt($ch, CURLOPT_INFILE, $opts['infile']); + } - if(x($opts,'readfunc')) - @curl_setopt($ch, CURLOPT_READFUNCTION, $opts['readfunc']); + if (x($opts, 'infilesize')) { + @curl_setopt($ch, CURLOPT_INFILESIZE, $opts['infilesize']); + } - // When using the session option and fetching from our own site, - // append the PHPSESSID cookie to any existing headers. - // Don't add to $opts['headers'] so that the cookie does not get - // sent to other sites via redirects + if (x($opts, 'readfunc')) { + @curl_setopt($ch, CURLOPT_READFUNCTION, $opts['readfunc']); + } - $instance_headers = ((array_key_exists('headers',$opts) && is_array($opts['headers'])) ? $opts['headers'] : []); + // When using the session option and fetching from our own site, + // append the PHPSESSID cookie to any existing headers. + // Don't add to $opts['headers'] so that the cookie does not get + // sent to other sites via redirects - if(x($opts,'session')) { - if(strpos($url,z_root()) === 0) { - $instance_headers[] = 'Cookie: PHPSESSID=' . session_id(); - } - } - if($instance_headers) - @curl_setopt($ch, CURLOPT_HTTPHEADER, $instance_headers); + $instance_headers = ((array_key_exists('headers', $opts) && is_array($opts['headers'])) ? $opts['headers'] : []); + + if (x($opts, 'session')) { + if (strpos($url, z_root()) === 0) { + $instance_headers[] = 'Cookie: PHPSESSID=' . session_id(); + } + } + if ($instance_headers) { + @curl_setopt($ch, CURLOPT_HTTPHEADER, $instance_headers); + } - if(x($opts,'nobody')) - @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); + if (x($opts, 'nobody')) { + @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); + } - if(x($opts,'custom')) - @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $opts['custom']); + if (x($opts, 'custom')) { + @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $opts['custom']); + } - if(x($opts,'timeout') && intval($opts['timeout'])) { - @curl_setopt($ch, CURLOPT_TIMEOUT, intval($opts['timeout'])); - } - else { - $curl_time = intval(get_config('system','curl_timeout',60)); - @curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time); - } + if (x($opts, 'timeout') && intval($opts['timeout'])) { + @curl_setopt($ch, CURLOPT_TIMEOUT, intval($opts['timeout'])); + } else { + $curl_time = intval(get_config('system', 'curl_timeout', 60)); + @curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time); + } - if(x($opts,'connecttimeout') && intval($opts['connecttimeout'])) { - @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($opts['connecttimeout'])); - } - else { - $curl_contime = intval(@get_config('system','curl_connecttimeout',60)); - @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_contime); - } + if (x($opts, 'connecttimeout') && intval($opts['connecttimeout'])) { + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($opts['connecttimeout'])); + } else { + $curl_contime = intval(@get_config('system', 'curl_connecttimeout', 60)); + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_contime); + } - if(x($opts,'http_auth')) { - // "username" . ':' . "password" - @curl_setopt($ch, CURLOPT_USERPWD, $opts['http_auth']); - } + if (x($opts, 'http_auth')) { + // "username" . ':' . "password" + @curl_setopt($ch, CURLOPT_USERPWD, $opts['http_auth']); + } - if(x($opts,'cookiejar')) - @curl_setopt($ch, CURLOPT_COOKIEJAR, $opts['cookiejar']); - if(x($opts,'cookiefile')) - @curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']); + if (x($opts, 'cookiejar')) { + @curl_setopt($ch, CURLOPT_COOKIEJAR, $opts['cookiejar']); + } + if (x($opts, 'cookiefile')) { + @curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']); + } - if(x($opts,'cookie')) - @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']); + if (x($opts, 'cookie')) { + @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']); + } - @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, - ((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true)); + @curl_setopt( + $ch, + CURLOPT_SSL_VERIFYPEER, + ((x($opts, 'novalidate') && intval($opts['novalidate'])) ? false : true) + ); - $prx = @get_config('system','proxy'); - if(strlen($prx)) { - @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); - @curl_setopt($ch, CURLOPT_PROXY, $prx); - $prxusr = @get_config('system','proxyuser'); - if(strlen($prxusr)) - @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); - } - if($binary) - @curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); + $prx = @get_config('system', 'proxy'); + if (strlen($prx)) { + @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); + @curl_setopt($ch, CURLOPT_PROXY, $prx); + $prxusr = @get_config('system', 'proxyuser'); + if (strlen($prxusr)) { + @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); + } + } + if ($binary) { + @curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); + } - // don't let curl abort the entire application' - // if it throws any errors. + // don't let curl abort the entire application' + // if it throws any errors. - $s = @curl_exec($ch); + $s = @curl_exec($ch); - $base = $s; - $curl_info = @curl_getinfo($ch); - $http_code = $curl_info['http_code']; - //logger('fetch_url:' . $http_code . ' data: ' . $s); - $header = ''; + $base = $s; + $curl_info = @curl_getinfo($ch); + $http_code = $curl_info['http_code']; + //logger('fetch_url:' . $http_code . ' data: ' . $s); + $header = ''; - // For file redirects, set curl to follow location (indicated by $passthru). - // Then just return success or failure. - - if ($passthru) { - if ($http_code >= 200 && $http_code < 300) { - $ret['success'] = true; - } - $ret['return_code'] = $http_code; - @curl_close($ch); - return $ret; - } - + // For file redirects, set curl to follow location (indicated by $passthru). + // Then just return success or failure. - // Pull out multiple headers, e.g. proxy and continuation headers - // allow for HTTP/2.x without fixing code + if ($passthru) { + if ($http_code >= 200 && $http_code < 300) { + $ret['success'] = true; + } + $ret['return_code'] = $http_code; + @curl_close($ch); + return $ret; + } - while(preg_match('/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/',$base)) { - $chunk = substr($base,0,strpos($base,"\r\n\r\n")+4); - $header .= $chunk; - $base = substr($base,strlen($chunk)); - } - if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) { - $matches = []; - preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches); - $newurl = trim(array_pop($matches)); - if(strpos($newurl,'/') === 0) { - // We received a redirect to a relative path. - // Find the base component of the original url and re-assemble it with the new location - $base = @parse_url($url); - if ($base) { - unset($base['path']); unset($base['query']); unset($base['fragment']); - $newurl = unparse_url($base) . $newurl; - } - } - if ($newurl) { - @curl_close($ch); - return z_fetch_url($newurl,$binary,++$redirects,$opts); - } - } + // Pull out multiple headers, e.g. proxy and continuation headers + // allow for HTTP/2.x without fixing code - $rc = intval($http_code); - $ret['return_code'] = $rc; - $ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false); - if(! $ret['success']) { - $ret['error'] = curl_error($ch); - $ret['debug'] = $curl_info; - $dbg = [ - 'url' => $ret['debug']['url'], - 'content_type' => $ret['debug']['content_type'], - 'error_code' => ((isset($ret['debug']['error_code'])) ? $ret['debug']['error_code'] : 0), - 'request_header' => $ret['debug']['request_header'] - ]; - logger('z_fetch_url: error: ' . $url . ': ' . $ret['error'], LOGGER_DEBUG); - logger('z_fetch_url: debug: ' . print_r($dbg,true), LOGGER_DATA); - } - $ret['body'] = substr($s,strlen($header)); - $ret['header'] = $header; - $ret['request_target'] = $opts['request_target']; + while (preg_match('/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/', $base)) { + $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); + $header .= $chunk; + $base = substr($base, strlen($chunk)); + } - if(x($opts,'debug')) { - $ret['debug'] = $curl_info; - } + if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) { + $matches = []; + preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches); + $newurl = trim(array_pop($matches)); + if (strpos($newurl, '/') === 0) { + // We received a redirect to a relative path. + // Find the base component of the original url and re-assemble it with the new location + $base = @parse_url($url); + if ($base) { + unset($base['path']); + unset($base['query']); + unset($base['fragment']); + $newurl = unparse_url($base) . $newurl; + } + } + if ($newurl) { + @curl_close($ch); + return z_fetch_url($newurl, $binary, ++$redirects, $opts); + } + } - @curl_close($ch); - return($ret); + $rc = intval($http_code); + $ret['return_code'] = $rc; + $ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false); + if (! $ret['success']) { + $ret['error'] = curl_error($ch); + $ret['debug'] = $curl_info; + $dbg = [ + 'url' => $ret['debug']['url'], + 'content_type' => $ret['debug']['content_type'], + 'error_code' => ((isset($ret['debug']['error_code'])) ? $ret['debug']['error_code'] : 0), + 'request_header' => $ret['debug']['request_header'] + ]; + logger('z_fetch_url: error: ' . $url . ': ' . $ret['error'], LOGGER_DEBUG); + logger('z_fetch_url: debug: ' . print_r($dbg, true), LOGGER_DATA); + } + $ret['body'] = substr($s, strlen($header)); + $ret['header'] = $header; + $ret['request_target'] = $opts['request_target']; + + if (x($opts, 'debug')) { + $ret['debug'] = $curl_info; + } + + @curl_close($ch); + return($ret); } @@ -279,237 +296,250 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = []) { * * \e string \b body => content * * \e string \b debug => from curl_info() */ -function z_post_url($url, $params, $redirects = 0, $opts = []) { +function z_post_url($url, $params, $redirects = 0, $opts = []) +{ -// logger('url: ' . $url); -// logger('params: ' . print_r($params,true)); -// logger('opts: ' . print_r($opts,true)); +// logger('url: ' . $url); +// logger('params: ' . print_r($params,true)); +// logger('opts: ' . print_r($opts,true)); - $ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => ""); + $ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => ""); - $ch = curl_init($url); - if(($redirects > 8) || (! $ch)) - return $ret; + $ch = curl_init($url); + if (($redirects > 8) || (! $ch)) { + return $ret; + } - if(! array_key_exists('request_target',$opts)) { - $opts['request_target'] = 'post ' . get_request_string($url); - } + if (! array_key_exists('request_target', $opts)) { + $opts['request_target'] = 'post ' . get_request_string($url); + } - @curl_setopt($ch, CURLOPT_HEADER, true); - @curl_setopt($ch, CURLINFO_HEADER_OUT, true); - @curl_setopt($ch, CURLOPT_CAINFO, get_capath()); - @curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); - @curl_setopt($ch, CURLOPT_POST,1); - @curl_setopt($ch, CURLOPT_POSTFIELDS,$params); - @curl_setopt($ch, CURLOPT_ENCODING, ''); - - $ciphers = @get_config('system','curl_ssl_ciphers'); - if($ciphers) - @curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, $ciphers); + @curl_setopt($ch, CURLOPT_HEADER, true); + @curl_setopt($ch, CURLINFO_HEADER_OUT, true); + @curl_setopt($ch, CURLOPT_CAINFO, get_capath()); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($ch, CURLOPT_POST, 1); + @curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + @curl_setopt($ch, CURLOPT_ENCODING, ''); - if(x($opts,'filep')) { - @curl_setopt($ch, CURLOPT_FILE, $opts['filep']); - @curl_setopt($ch, CURLOPT_HEADER, false); - } + $ciphers = @get_config('system', 'curl_ssl_ciphers'); + if ($ciphers) { + @curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, $ciphers); + } - if (x($opts,'useragent')) { - @curl_setopt($ch, CURLOPT_USERAGENT, $opts['useragent']); - } - else { - @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)"); - } + if (x($opts, 'filep')) { + @curl_setopt($ch, CURLOPT_FILE, $opts['filep']); + @curl_setopt($ch, CURLOPT_HEADER, false); + } + + if (x($opts, 'useragent')) { + @curl_setopt($ch, CURLOPT_USERAGENT, $opts['useragent']); + } else { + @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)"); + } - $instance_headers = ((array_key_exists('headers',$opts) && is_array($opts['headers'])) ? $opts['headers'] : []); + $instance_headers = ((array_key_exists('headers', $opts) && is_array($opts['headers'])) ? $opts['headers'] : []); - if(x($opts,'session')) { - if(strpos($url,z_root()) === 0) { - $instance_headers[] = 'Cookie: PHPSESSID=' . session_id(); - } - } - if($instance_headers) - @curl_setopt($ch, CURLOPT_HTTPHEADER, $instance_headers); + if (x($opts, 'session')) { + if (strpos($url, z_root()) === 0) { + $instance_headers[] = 'Cookie: PHPSESSID=' . session_id(); + } + } + if ($instance_headers) { + @curl_setopt($ch, CURLOPT_HTTPHEADER, $instance_headers); + } - if(x($opts,'nobody')) - @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); + if (x($opts, 'nobody')) { + @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); + } - if(x($opts,'custom')) { - @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $opts['custom']); - @curl_setopt($ch, CURLOPT_POST,0); - } + if (x($opts, 'custom')) { + @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $opts['custom']); + @curl_setopt($ch, CURLOPT_POST, 0); + } - if(x($opts,'timeout') && intval($opts['timeout'])) { - @curl_setopt($ch, CURLOPT_TIMEOUT, intval($opts['timeout'])); - } - else { - $curl_time = intval(@get_config('system','curl_post_timeout',90)); - @curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time); - } + if (x($opts, 'timeout') && intval($opts['timeout'])) { + @curl_setopt($ch, CURLOPT_TIMEOUT, intval($opts['timeout'])); + } else { + $curl_time = intval(@get_config('system', 'curl_post_timeout', 90)); + @curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time); + } - if(x($opts,'connecttimeout') && intval($opts['connecttimeout'])) { - @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($opts['connecttimeout'])); - } - else { - $curl_contime = intval(@get_config('system','curl_post_connecttimeout',90)); - @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_contime); - } + if (x($opts, 'connecttimeout') && intval($opts['connecttimeout'])) { + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($opts['connecttimeout'])); + } else { + $curl_contime = intval(@get_config('system', 'curl_post_connecttimeout', 90)); + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_contime); + } - if(x($opts,'http_auth')) { - // "username" . ':' . "password" - @curl_setopt($ch, CURLOPT_USERPWD, $opts['http_auth']); - } + if (x($opts, 'http_auth')) { + // "username" . ':' . "password" + @curl_setopt($ch, CURLOPT_USERPWD, $opts['http_auth']); + } - if(x($opts,'cookiejar')) - @curl_setopt($ch, CURLOPT_COOKIEJAR, $opts['cookiejar']); - if(x($opts,'cookiefile')) - @curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']); - if(x($opts,'cookie')) - @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']); + if (x($opts, 'cookiejar')) { + @curl_setopt($ch, CURLOPT_COOKIEJAR, $opts['cookiejar']); + } + if (x($opts, 'cookiefile')) { + @curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']); + } + if (x($opts, 'cookie')) { + @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']); + } - @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, - ((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true)); + @curl_setopt( + $ch, + CURLOPT_SSL_VERIFYPEER, + ((x($opts, 'novalidate') && intval($opts['novalidate'])) ? false : true) + ); - $prx = get_config('system','proxy'); - if(strlen($prx)) { - @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); - @curl_setopt($ch, CURLOPT_PROXY, $prx); - $prxusr = get_config('system','proxyuser'); - if(strlen($prxusr)) - @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); - } + $prx = get_config('system', 'proxy'); + if (strlen($prx)) { + @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); + @curl_setopt($ch, CURLOPT_PROXY, $prx); + $prxusr = get_config('system', 'proxyuser'); + if (strlen($prxusr)) { + @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); + } + } - // don't let curl abort the entire application - // if it throws any errors. + // don't let curl abort the entire application + // if it throws any errors. - $s = @curl_exec($ch); + $s = @curl_exec($ch); - $base = $s; - $curl_info = @curl_getinfo($ch); - $http_code = $curl_info['http_code']; + $base = $s; + $curl_info = @curl_getinfo($ch); + $http_code = $curl_info['http_code']; - $header = ''; + $header = ''; - // Pull out multiple headers, e.g. proxy and continuation headers - // allow for HTTP/2.x without fixing code + // Pull out multiple headers, e.g. proxy and continuation headers + // allow for HTTP/2.x without fixing code - while(preg_match('/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/',$base)) { - $chunk = substr($base,0,strpos($base,"\r\n\r\n")+4); - $header .= $chunk; - $base = substr($base,strlen($chunk)); - } + while (preg_match('/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/', $base)) { + $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); + $header .= $chunk; + $base = substr($base, strlen($chunk)); + } - // would somebody take lighttpd and just shoot it? + // would somebody take lighttpd and just shoot it? - if($http_code == 417) { - curl_close($ch); - if($opts) { - if($opts['headers']) - $opts['headers'][] = 'Expect:'; - else - $opts['headers'] = array('Expect:'); - } - else - $opts = array('headers' => array('Expect:')); - return z_post_url($url,$params,++$redirects,$opts); - } + if ($http_code == 417) { + curl_close($ch); + if ($opts) { + if ($opts['headers']) { + $opts['headers'][] = 'Expect:'; + } else { + $opts['headers'] = array('Expect:'); + } + } else { + $opts = array('headers' => array('Expect:')); + } + return z_post_url($url, $params, ++$redirects, $opts); + } - if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) { - $matches = []; - preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); - $newurl = trim(array_pop($matches)); - if(strpos($newurl,'/') === 0) { - // We received a redirect to a relative path. - // Find the base component of the original url and re-assemble it with the new location - $base = @parse_url($url); - if ($base) { - unset($base['path']); unset($base['query']); unset($base['fragment']); - $newurl = unparse_url($base) . $newurl; - } - } - if ($newurl) { - curl_close($ch); - if($http_code == 303) { - return z_fetch_url($newurl,false,++$redirects,$opts); - } - else { - return z_post_url($newurl,$params,++$redirects,$opts); - } - } - } - $rc = intval($http_code); - $ret['return_code'] = $rc; - $ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false); - if(! $ret['success']) { - $ret['error'] = curl_error($ch); - $ret['debug'] = $curl_info; - $dbg = [ - 'url' => $ret['debug']['url'], - 'content_type' => $ret['debug']['content_type'], - 'error_code' => $ret['debug']['error_code'], - 'request_header' => $ret['debug']['request_header'] - ]; - logger('z_post_url: error: ' . $url . ': ' . $ret['error'], LOGGER_DEBUG); - logger('z_post_url: debug: ' . print_r($dbg,true), LOGGER_DATA); - } + if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) { + $matches = []; + preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); + $newurl = trim(array_pop($matches)); + if (strpos($newurl, '/') === 0) { + // We received a redirect to a relative path. + // Find the base component of the original url and re-assemble it with the new location + $base = @parse_url($url); + if ($base) { + unset($base['path']); + unset($base['query']); + unset($base['fragment']); + $newurl = unparse_url($base) . $newurl; + } + } + if ($newurl) { + curl_close($ch); + if ($http_code == 303) { + return z_fetch_url($newurl, false, ++$redirects, $opts); + } else { + return z_post_url($newurl, $params, ++$redirects, $opts); + } + } + } + $rc = intval($http_code); + $ret['return_code'] = $rc; + $ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false); + if (! $ret['success']) { + $ret['error'] = curl_error($ch); + $ret['debug'] = $curl_info; + $dbg = [ + 'url' => $ret['debug']['url'], + 'content_type' => $ret['debug']['content_type'], + 'error_code' => $ret['debug']['error_code'], + 'request_header' => $ret['debug']['request_header'] + ]; + logger('z_post_url: error: ' . $url . ': ' . $ret['error'], LOGGER_DEBUG); + logger('z_post_url: debug: ' . print_r($dbg, true), LOGGER_DATA); + } - $ret['body'] = substr($s, strlen($header)); - $ret['header'] = $header; - $ret['request_target'] = $opts['request_target']; + $ret['body'] = substr($s, strlen($header)); + $ret['header'] = $header; + $ret['request_target'] = $opts['request_target']; - if(x($opts,'debug')) { - $ret['debug'] = $curl_info; - } + if (x($opts, 'debug')) { + $ret['debug'] = $curl_info; + } - curl_close($ch); - return($ret); + curl_close($ch); + return($ret); } -function z_curl_error($ret) { - $output = EMPTY_STR; - if (isset($ret['debug'])) { - $output .= datetime_convert() . EOL; - $output .= t('url: ') . $ret['debug']['url'] . EOL; - $output .= t('error_code: ') . $ret['debug']['error_code'] . EOL; - $output .= t('error_string: ') . $ret['error'] . EOL; - $output .= t('content-type: ') . $ret['debug']['content_type'] . EOL; - } - return $output; +function z_curl_error($ret) +{ + $output = EMPTY_STR; + if (isset($ret['debug'])) { + $output .= datetime_convert() . EOL; + $output .= t('url: ') . $ret['debug']['url'] . EOL; + $output .= t('error_code: ') . $ret['debug']['error_code'] . EOL; + $output .= t('error_string: ') . $ret['error'] . EOL; + $output .= t('content-type: ') . $ret['debug']['content_type'] . EOL; + } + return $output; } -function json_return_and_die($x, $content_type = 'application/json', $debug = false) { - header("Content-type: $content_type"); - if ($debug) { - logger('returned_json: ' . json_encode($x,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA); - } - echo json_encode($x); - killme(); +function json_return_and_die($x, $content_type = 'application/json', $debug = false) +{ + header("Content-type: $content_type"); + if ($debug) { + logger('returned_json: ' . json_encode($x, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOGGER_DATA); + } + echo json_encode($x); + killme(); } -function as_return_and_die($obj,$channel) { +function as_return_and_die($obj, $channel) +{ - $x = array_merge(['@context' => [ - ACTIVITYSTREAMS_JSONLD_REV, - 'https://w3id.org/security/v1', - Activity::ap_schema() - ]], $obj ); + $x = array_merge(['@context' => [ + ACTIVITYSTREAMS_JSONLD_REV, + 'https://w3id.org/security/v1', + Activity::ap_schema() + ]], $obj); - $headers = []; - $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; - $x['signature'] = LDSignatures::sign($x,$channel); - $ret = json_encode($x, JSON_UNESCAPED_SLASHES); - logger('data: ' . jindent($ret), LOGGER_DATA); - $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); - $headers['Digest'] = HTTPSig::generate_digest_header($ret); - $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + $headers = []; + $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; + $x['signature'] = LDSignatures::sign($x, $channel); + $ret = json_encode($x, JSON_UNESCAPED_SLASHES); + logger('data: ' . jindent($ret), LOGGER_DATA); + $headers['Date'] = datetime_convert('UTC', 'UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); + $headers['Digest'] = HTTPSig::generate_digest_header($ret); + $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; - $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel)); - HTTPSig::set_headers($h); - - echo $ret; - killme(); + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel)); + HTTPSig::set_headers($h); + echo $ret; + killme(); } @@ -521,14 +551,17 @@ function as_return_and_die($obj,$channel) { * @param string $msg * optional message */ -function http_status($val, $msg = '') { - if ($val >= 400) - $msg = (($msg) ? $msg : 'Error'); - if ($val >= 200 && $val < 300) - $msg = (($msg) ? $msg : 'OK'); +function http_status($val, $msg = '') +{ + if ($val >= 400) { + $msg = (($msg) ? $msg : 'Error'); + } + if ($val >= 200 && $val < 300) { + $msg = (($msg) ? $msg : 'OK'); + } - logger(App::$query_string . ':' . $val . ' ' . $msg); - header($_SERVER['SERVER_PROTOCOL'] . ' ' . $val . ' ' . $msg); + logger(App::$query_string . ':' . $val . ' ' . $msg); + header($_SERVER['SERVER_PROTOCOL'] . ' ' . $val . ' ' . $msg); } @@ -541,9 +574,10 @@ function http_status($val, $msg = '') { * optional message * @return void does not return, process is terminated */ -function http_status_exit($val, $msg = '') { - http_status($val, $msg); - killme(); +function http_status_exit($val, $msg = '') +{ + http_status($val, $msg); + killme(); } /* @@ -551,19 +585,20 @@ function http_status_exit($val, $msg = '') { * Takes the output of parse_url and builds a URL from it * */ - -function unparse_url($parsed_url) { - $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; - $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; - $port = ((isset($parsed_url['port']) && intval($parsed_url['port'])) ? ':' . intval($parsed_url['port']) : ''); - $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; - $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; - $pass = ($user || $pass) ? "$pass@" : ''; - $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; - $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; - $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; - return "$scheme$user$pass$host$port$path$query$fragment"; -} + +function unparse_url($parsed_url) +{ + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; + $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; + $port = ((isset($parsed_url['port']) && intval($parsed_url['port'])) ? ':' . intval($parsed_url['port']) : ''); + $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + return "$scheme$user$pass$host$port$path$query$fragment"; +} @@ -576,72 +611,80 @@ function unparse_url($parsed_url) { * @param[in,out] int $recursion_depth * @return NULL|string|array */ -function convert_xml_element_to_array($xml_element, &$recursion_depth=0) { +function convert_xml_element_to_array($xml_element, &$recursion_depth = 0) +{ - // If we're getting too deep, bail out - if ($recursion_depth > 512) { - return(null); - } + // If we're getting too deep, bail out + if ($recursion_depth > 512) { + return(null); + } - if (!is_string($xml_element) && - !is_array($xml_element) && - (get_class($xml_element) == 'SimpleXMLElement')) { - $xml_element_copy = $xml_element; - $xml_element = get_object_vars($xml_element); - } + if ( + !is_string($xml_element) && + !is_array($xml_element) && + (get_class($xml_element) == 'SimpleXMLElement') + ) { + $xml_element_copy = $xml_element; + $xml_element = get_object_vars($xml_element); + } - if (is_array($xml_element)) { - $result_array = []; - if (count($xml_element) <= 0) { - return (trim(strval($xml_element_copy))); - } + if (is_array($xml_element)) { + $result_array = []; + if (count($xml_element) <= 0) { + return (trim(strval($xml_element_copy))); + } - foreach($xml_element as $key=>$value) { - $recursion_depth++; - $result_array[strtolower($key)] = - convert_xml_element_to_array($value, $recursion_depth); - $recursion_depth--; - } - if ($recursion_depth == 0) { - $temp_array = $result_array; - $result_array = array( - strtolower($xml_element_copy->getName()) => $temp_array, - ); - } + foreach ($xml_element as $key => $value) { + $recursion_depth++; + $result_array[strtolower($key)] = + convert_xml_element_to_array($value, $recursion_depth); + $recursion_depth--; + } + if ($recursion_depth == 0) { + $temp_array = $result_array; + $result_array = array( + strtolower($xml_element_copy->getName()) => $temp_array, + ); + } - return ($result_array); - } else { - return (trim(strval($xml_element))); - } + return ($result_array); + } else { + return (trim(strval($xml_element))); + } } -function z_dns_check($h,$check_mx = 0) { +function z_dns_check($h, $check_mx = 0) +{ - // dns_get_record() has issues on some platforms - // so allow somebody to ignore it completely - // Use config values from memory as this can be called during setup - // before a database or even any config structure exists. + // dns_get_record() has issues on some platforms + // so allow somebody to ignore it completely + // Use config values from memory as this can be called during setup + // before a database or even any config structure exists. - if(is_array(App::$config) && array_path_exists('system/do_not_check_dns', App::$config) && App::$config['system']['do_not_check_dns']) - return true; + if (is_array(App::$config) && array_path_exists('system/do_not_check_dns', App::$config) && App::$config['system']['do_not_check_dns']) { + return true; + } - // This will match either Windows or Mac ('Darwin') - if(stripos(PHP_OS,'win') !== false) - return true; + // This will match either Windows or Mac ('Darwin') + if (stripos(PHP_OS, 'win') !== false) { + return true; + } - // BSD variants have dns_get_record() but it only works reliably without any options - if(stripos(PHP_OS,'bsd') !== false) - return((@dns_get_record($h) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); + // BSD variants have dns_get_record() but it only works reliably without any options + if (stripos(PHP_OS, 'bsd') !== false) { + return((@dns_get_record($h) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); + } - // Otherwise we will assume dns_get_record() works as documented + // Otherwise we will assume dns_get_record() works as documented - $opts = DNS_A + DNS_CNAME + DNS_AAAA; - if($check_mx) - $opts += DNS_MX; + $opts = DNS_A + DNS_CNAME + DNS_AAAA; + if ($check_mx) { + $opts += DNS_MX; + } - return((@dns_get_record($h,$opts) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); + return((@dns_get_record($h, $opts) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); } /** @@ -655,22 +698,25 @@ function z_dns_check($h,$check_mx = 0) { * @param[in,out] string $url URL to check * @return bool Return true if it's OK, false if something is wrong with it */ -function validate_url(&$url) { +function validate_url(&$url) +{ - // no naked subdomains (allow localhost for tests) - if(strpos($url, '.') === false && strpos($url, '/localhost/') === false) - return false; + // no naked subdomains (allow localhost for tests) + if (strpos($url, '.') === false && strpos($url, '/localhost/') === false) { + return false; + } - if(substr($url, 0, 4) != 'http') - $url = 'http://' . $url; + if (substr($url, 0, 4) != 'http') { + $url = 'http://' . $url; + } - $h = @parse_url($url); + $h = @parse_url($url); - if(($h) && z_dns_check($h['host'])) { - return true; - } + if (($h) && z_dns_check($h['host'])) { + return true; + } - return false; + return false; } /** @@ -679,21 +725,24 @@ function validate_url(&$url) { * @param string $addr * @return bool */ -function validate_email($addr) { +function validate_email($addr) +{ - if(get_config('system', 'disable_email_validation')) - return true; + if (get_config('system', 'disable_email_validation')) { + return true; + } - if(! strpos($addr, '@')) - return false; + if (! strpos($addr, '@')) { + return false; + } - $h = substr($addr, strpos($addr, '@') + 1); + $h = substr($addr, strpos($addr, '@') + 1); - if(($h) && z_dns_check($h, true)) { - return true; - } + if (($h) && z_dns_check($h, true)) { + return true; + } - return false; + return false; } /** @@ -705,90 +754,96 @@ function validate_email($addr) { * @return bool Returns false if not allowed, true if allowed or if allowed list is * not configured. */ -function allowed_email($email) { - - $domain = strtolower(substr($email, strpos($email, '@') + 1)); - if(! $domain) - return false; - - $str_allowed = get_config('system', 'allowed_email'); - $str_not_allowed = get_config('system', 'not_allowed_email'); - - if(! $str_allowed && ! $str_not_allowed) - return true; - - $return = false; - $found_allowed = false; - $found_not_allowed = false; - - $fnmatch = function_exists('fnmatch'); - - $allowed = explode(',', $str_allowed); - - if(count($allowed)) { - foreach($allowed as $a) { - $pat = strtolower(trim($a)); - if(($fnmatch && fnmatch($pat,$email)) || ($pat == $domain)) { - $found_allowed = true; - break; - } - } - } - - $not_allowed = explode(',', $str_not_allowed); - - if(count($not_allowed)) { - foreach($not_allowed as $na) { - $pat = strtolower(trim($na)); - if(($fnmatch && fnmatch($pat,$email)) || ($pat == $domain)) { - $found_not_allowed = true; - break; - } - } - } - - if ($found_allowed) { - $return = true; - } elseif (!$str_allowed && !$found_not_allowed) { - $return = true; - } - - return $return; -} - - - -function parse_xml_string($s, $strict = true) { - if($strict) { - if(! strstr($s,'code . ' at ' . $err->line - . ':' . $err->column . ' : ' . $err->message, LOGGER_DATA); - } - libxml_clear_errors(); - } - - return $x; -} - - -function sxml2array ( $xmlObject, $out = array () ) +function allowed_email($email) { - foreach ( (array) $xmlObject as $index => $node ) - $out[$index] = ( is_object ( $node ) ) ? sxml2array ( $node ) : $node; + + $domain = strtolower(substr($email, strpos($email, '@') + 1)); + if (! $domain) { + return false; + } + + $str_allowed = get_config('system', 'allowed_email'); + $str_not_allowed = get_config('system', 'not_allowed_email'); + + if (! $str_allowed && ! $str_not_allowed) { + return true; + } + + $return = false; + $found_allowed = false; + $found_not_allowed = false; + + $fnmatch = function_exists('fnmatch'); + + $allowed = explode(',', $str_allowed); + + if (count($allowed)) { + foreach ($allowed as $a) { + $pat = strtolower(trim($a)); + if (($fnmatch && fnmatch($pat, $email)) || ($pat == $domain)) { + $found_allowed = true; + break; + } + } + } + + $not_allowed = explode(',', $str_not_allowed); + + if (count($not_allowed)) { + foreach ($not_allowed as $na) { + $pat = strtolower(trim($na)); + if (($fnmatch && fnmatch($pat, $email)) || ($pat == $domain)) { + $found_not_allowed = true; + break; + } + } + } + + if ($found_allowed) { + $return = true; + } elseif (!$str_allowed && !$found_not_allowed) { + $return = true; + } + + return $return; +} + + + +function parse_xml_string($s, $strict = true) +{ + if ($strict) { + if (! strstr($s, 'code . ' at ' . $err->line + . ':' . $err->column . ' : ' . $err->message, LOGGER_DATA); + } + libxml_clear_errors(); + } + + return $x; +} + + +function sxml2array($xmlObject, $out = array ()) +{ + foreach ((array) $xmlObject as $index => $node) { + $out[$index] = ( is_object($node) ) ? sxml2array($node) : $node; + } return $out; } @@ -797,7 +852,7 @@ function sxml2array ( $xmlObject, $out = array () ) * @brief xml2[] will convert the given XML text to an array in the XML structure. * * Link: http://www.bin-co.com/php/scripts/xml2array/ - * Portions significantly re-written by mike@macgirvin.com + * Portions significantly re-written by mike@macgirvin.com * (namespaces, lowercase tags, get_attribute default changed, more...) * * Examples: $array = xml2array(file_get_contents('feed.xml')); @@ -810,206 +865,214 @@ function sxml2array ( $xmlObject, $out = array () ) * * @return array The parsed XML in an array form. Use print_r() to see the resulting array structure. */ -function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') { - if(!$contents) - return []; +function xml2array($contents, $namespaces = true, $get_attributes = 1, $priority = 'attribute') +{ + if (!$contents) { + return []; + } - if(!function_exists('xml_parser_create')) { - logger('xml2array: parser function missing'); - return []; - } + if (!function_exists('xml_parser_create')) { + logger('xml2array: parser function missing'); + return []; + } - libxml_use_internal_errors(true); - libxml_clear_errors(); + libxml_use_internal_errors(true); + libxml_clear_errors(); - if($namespaces) - $parser = @xml_parser_create_ns("UTF-8",':'); - else - $parser = @xml_parser_create(); + if ($namespaces) { + $parser = @xml_parser_create_ns("UTF-8", ':'); + } else { + $parser = @xml_parser_create(); + } - if(! $parser) { - logger('xml2array: xml_parser_create: no resource'); - return []; - } + if (! $parser) { + logger('xml2array: xml_parser_create: no resource'); + return []; + } - xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); - // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss - xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); - xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); - @xml_parse_into_struct($parser, trim($contents), $xml_values); - @xml_parser_free($parser); + xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); + // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + @xml_parse_into_struct($parser, trim($contents), $xml_values); + @xml_parser_free($parser); - if(! $xml_values) { - logger('xml2array: libxml: parse error: ' . $contents, LOGGER_DATA); - foreach(libxml_get_errors() as $err) - logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA); - libxml_clear_errors(); + if (! $xml_values) { + logger('xml2array: libxml: parse error: ' . $contents, LOGGER_DATA); + foreach (libxml_get_errors() as $err) { + logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA); + } + libxml_clear_errors(); - return; - } + return; + } - //Initializations - $xml_array = []; - $parents = []; - $opened_tags = []; - $arr = []; + //Initializations + $xml_array = []; + $parents = []; + $opened_tags = []; + $arr = []; - $current = &$xml_array; // Reference + $current = &$xml_array; // Reference - // Go through the tags. - $repeated_tag_index = []; // Multiple tags with same name will be turned into an array - foreach($xml_values as $data) { - unset($attributes,$value); // Remove existing values, or there will be trouble + // Go through the tags. + $repeated_tag_index = []; // Multiple tags with same name will be turned into an array + foreach ($xml_values as $data) { + unset($attributes, $value); // Remove existing values, or there will be trouble - // This command will extract these variables into the foreach scope - // tag(string), type(string), level(int), attributes(array). - extract($data); // We could use the array by itself, but this cooler. + // This command will extract these variables into the foreach scope + // tag(string), type(string), level(int), attributes(array). + extract($data); // We could use the array by itself, but this cooler. - $result = []; - $attributes_data = []; + $result = []; + $attributes_data = []; - if(isset($value)) { - if($priority == 'tag') $result = $value; - else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode - } + if (isset($value)) { + if ($priority == 'tag') { + $result = $value; + } else { + $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode + } + } - //Set the attributes too. - if(isset($attributes) and $get_attributes) { - foreach($attributes as $attr => $val) { - if($priority == 'tag') $attributes_data[$attr] = $val; - else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr' - } - } + //Set the attributes too. + if (isset($attributes) and $get_attributes) { + foreach ($attributes as $attr => $val) { + if ($priority == 'tag') { + $attributes_data[$attr] = $val; + } else { + $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr' + } + } + } - // See tag status and do the needed. - if($namespaces && strpos($tag,':')) { - $namespc = substr($tag,0,strrpos($tag,':')); - $tag = strtolower(substr($tag,strlen($namespc)+1)); - $result['@namespace'] = $namespc; - } - $tag = strtolower($tag); + // See tag status and do the needed. + if ($namespaces && strpos($tag, ':')) { + $namespc = substr($tag, 0, strrpos($tag, ':')); + $tag = strtolower(substr($tag, strlen($namespc) + 1)); + $result['@namespace'] = $namespc; + } + $tag = strtolower($tag); - if($type == "open") { // The starting of the tag '' - $parent[$level-1] = &$current; - if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag - $current[$tag] = $result; - if($attributes_data) $current[$tag. '_attr'] = $attributes_data; - $repeated_tag_index[$tag.'_'.$level] = 1; + if ($type == "open") { // The starting of the tag '' + $parent[$level - 1] = &$current; + if (!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag + $current[$tag] = $result; + if ($attributes_data) { + $current[$tag . '_attr'] = $attributes_data; + } + $repeated_tag_index[$tag . '_' . $level] = 1; - $current = &$current[$tag]; + $current = &$current[$tag]; + } else { // There was another element with the same tag name + if (isset($current[$tag][0])) { // If there is a 0th element it is already an array + $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; + $repeated_tag_index[$tag . '_' . $level]++; + } else { // This section will make the value an array if multiple tags with the same name appear together + $current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array + $repeated_tag_index[$tag . '_' . $level] = 2; - } else { // There was another element with the same tag name + if (isset($current[$tag . '_attr'])) { // The attribute of the last(0th) tag must be moved as well + $current[$tag]['0_attr'] = $current[$tag . '_attr']; + unset($current[$tag . '_attr']); + } + } + $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1; + $current = &$current[$tag][$last_item_index]; + } + } elseif ($type == "complete") { // Tags that ends in 1 line '' + //See if the key is already taken. + if (!isset($current[$tag])) { //New Key + $current[$tag] = $result; + $repeated_tag_index[$tag . '_' . $level] = 1; + if ($priority == 'tag' and $attributes_data) { + $current[$tag . '_attr'] = $attributes_data; + } + } else { // If taken, put all things inside a list(array) + if (isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array... + // ...push the new element into that array. + $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; - if(isset($current[$tag][0])) { // If there is a 0th element it is already an array - $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; - $repeated_tag_index[$tag.'_'.$level]++; - } else { // This section will make the value an array if multiple tags with the same name appear together - $current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array - $repeated_tag_index[$tag.'_'.$level] = 2; + if ($priority == 'tag' and $get_attributes and $attributes_data) { + $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data; + } + $repeated_tag_index[$tag . '_' . $level]++; + } else { // If it is not an array... + $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value + $repeated_tag_index[$tag . '_' . $level] = 1; + if ($priority == 'tag' and $get_attributes) { + if (isset($current[$tag . '_attr'])) { // The attribute of the last(0th) tag must be moved as well + $current[$tag]['0_attr'] = $current[$tag . '_attr']; + unset($current[$tag . '_attr']); + } - if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well - $current[$tag]['0_attr'] = $current[$tag.'_attr']; - unset($current[$tag.'_attr']); - } - } - $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1; - $current = &$current[$tag][$last_item_index]; - } + if ($attributes_data) { + $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data; + } + } + $repeated_tag_index[$tag . '_' . $level]++; // 0 and 1 indexes are already taken + } + } + } elseif ($type == 'close') { // End of tag '' + $current = &$parent[$level - 1]; + } + } - } elseif($type == "complete") { // Tags that ends in 1 line '' - //See if the key is already taken. - if(!isset($current[$tag])) { //New Key - $current[$tag] = $result; - $repeated_tag_index[$tag.'_'.$level] = 1; - if($priority == 'tag' and $attributes_data) - $current[$tag. '_attr'] = $attributes_data; - - } else { // If taken, put all things inside a list(array) - if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array... - - // ...push the new element into that array. - $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; - - if($priority == 'tag' and $get_attributes and $attributes_data) { - $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; - } - $repeated_tag_index[$tag.'_'.$level]++; - } else { // If it is not an array... - $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value - $repeated_tag_index[$tag.'_'.$level] = 1; - if($priority == 'tag' and $get_attributes) { - if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well - $current[$tag]['0_attr'] = $current[$tag.'_attr']; - unset($current[$tag.'_attr']); - } - - if($attributes_data) { - $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; - } - } - $repeated_tag_index[$tag.'_'.$level]++; // 0 and 1 indexes are already taken - } - } - - } elseif($type == 'close') { // End of tag '' - $current = &$parent[$level-1]; - } - } - - return($xml_array); + return($xml_array); } -function email_header_encode($in_str, $charset = 'UTF-8', $header = 'Subject') { - $out_str = $in_str; - $need_to_convert = false; +function email_header_encode($in_str, $charset = 'UTF-8', $header = 'Subject') +{ + $out_str = $in_str; + $need_to_convert = false; - for($x = 0; $x < strlen($in_str); $x ++) { - if((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) { - $need_to_convert = true; - break; - } - } + for ($x = 0; $x < strlen($in_str); $x++) { + if ((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) { + $need_to_convert = true; + break; + } + } - if(! $need_to_convert) - return $in_str; + if (! $need_to_convert) { + return $in_str; + } - if ($out_str && $charset) { + if ($out_str && $charset) { + // define start delimimter, end delimiter and spacer + $end = "?="; + $start = "=?" . $charset . "?B?"; + $spacer = $end . PHP_EOL . " " . $start; - // define start delimimter, end delimiter and spacer - $end = "?="; - $start = "=?" . $charset . "?B?"; - $spacer = $end . PHP_EOL . " " . $start; + // determine length of encoded text within chunks + // and ensure length is even + $length = 75 - strlen($start) - strlen($end) - (strlen($header) + 2); - // determine length of encoded text within chunks - // and ensure length is even - $length = 75 - strlen($start) - strlen($end) - (strlen($header) + 2); + /* + [EDIT BY danbrown AT php DOT net: The following + is a bugfix provided by (gardan AT gmx DOT de) + on 31-MAR-2005 with the following note: + "This means: $length should not be even, + but divisible by 4. The reason is that in + base64-encoding 3 8-bit-chars are represented + by 4 6-bit-chars. These 4 chars must not be + split between two encoded words, according + to RFC-2047. + */ + $length = $length - ($length % 4); - /* - [EDIT BY danbrown AT php DOT net: The following - is a bugfix provided by (gardan AT gmx DOT de) - on 31-MAR-2005 with the following note: - "This means: $length should not be even, - but divisible by 4. The reason is that in - base64-encoding 3 8-bit-chars are represented - by 4 6-bit-chars. These 4 chars must not be - split between two encoded words, according - to RFC-2047. - */ - $length = $length - ($length % 4); + // encode the string and split it into chunks + // with spacers after each chunk + $out_str = base64_encode($out_str); + $out_str = chunk_split($out_str, $length, $spacer); - // encode the string and split it into chunks - // with spacers after each chunk - $out_str = base64_encode($out_str); - $out_str = chunk_split($out_str, $length, $spacer); - - // remove trailing spacer and - // add start and end delimiters - $spacer = preg_quote($spacer,'/'); - $out_str = preg_replace("/" . $spacer . "$/", "", $out_str); - $out_str = $start . $out_str . $end; - } - return $out_str; + // remove trailing spacer and + // add start and end delimiters + $spacer = preg_quote($spacer, '/'); + $out_str = preg_replace("/" . $spacer . "$/", "", $out_str); + $out_str = $start . $out_str . $end; + } + return $out_str; } /** @@ -1020,99 +1083,100 @@ function email_header_encode($in_str, $charset = 'UTF-8', $header = 'Subject') { * @param bool $verify (optional) default true, verify HTTP signatures on Zot discovery packets. * @return bool */ -function discover_by_webbie($webbie, $protocol = '', $verify = true) { +function discover_by_webbie($webbie, $protocol = '', $verify = true) +{ - $result = []; + $result = []; - $network = null; + $network = null; - $x = Webfinger::exec($webbie); + $x = Webfinger::exec($webbie); - $address = EMPTY_STR; + $address = EMPTY_STR; - if($x && array_key_exists('subject',$x) && strpos($x['subject'],'acct:') === 0) - $address = str_replace('acct:','',$x['subject']); - if($x && array_key_exists('aliases',$x) && count($x['aliases'])) { - foreach($x['aliases'] as $a) { - if(strpos($a,'acct:') === 0) { - $address = str_replace('acct:','',$a); + if ($x && array_key_exists('subject', $x) && strpos($x['subject'], 'acct:') === 0) { + $address = str_replace('acct:', '', $x['subject']); + } + if ($x && array_key_exists('aliases', $x) && count($x['aliases'])) { + foreach ($x['aliases'] as $a) { + if (strpos($a, 'acct:') === 0) { + $address = str_replace('acct:', '', $a); break; } } } - if($x && array_key_exists('links',$x) && is_array($x['links'])) { - foreach($x['links'] as $link) { - if(array_key_exists('rel',$link)) { + if ($x && array_key_exists('links', $x) && is_array($x['links'])) { + foreach ($x['links'] as $link) { + if (array_key_exists('rel', $link)) { + $apurl = null; - $apurl = null; + // If we discover zot - don't search further; grab the info and get out of + // here. - // If we discover zot - don't search further; grab the info and get out of - // here. + if ($link['rel'] === PROTOCOL_ZOT6 && ((! $protocol) || (strtolower($protocol) === 'zot6'))) { + logger('zot6 found for ' . $webbie, LOGGER_DEBUG); + $record = Zotfinger::exec($link['href'], null, $verify); - if($link['rel'] === PROTOCOL_ZOT6 && ((! $protocol) || (strtolower($protocol) === 'zot6'))) { - logger('zot6 found for ' . $webbie, LOGGER_DEBUG); - $record = Zotfinger::exec($link['href'], null, $verify); + // Check the HTTP signature - // Check the HTTP signature + if ($verify) { + $hsig = $record['signature']; + if ($hsig && ($hsig['signer'] === $url || $hsig['signer'] === $link['href']) && $hsig['header_valid'] === true && $hsig['content_valid'] === true) { + $hsig_valid = true; + } - if ($verify) { + if (! $hsig_valid) { + logger('http signature not valid: ' . print_r($hsig, true)); + continue; + } + } - $hsig = $record['signature']; - if($hsig && ($hsig['signer'] === $url || $hsig['signer'] === $link['href']) && $hsig['header_valid'] === true && $hsig['content_valid'] === true) { - $hsig_valid = true; - } + $x = Libzot::import_xchan($record['data']); + if ($x['success']) { + return $x['hash']; + } + } + if ($link['rel'] === 'self' && ($link['type'] === 'application/activity+json' || strpos($link['type'], 'ld+json') !== false) && ((! $protocol) || (strtolower($protocol) === 'activitypub'))) { + $ap = ActivityPub::discover($link['href']); + if ($ap) { + return $ap; + } + } + } + } + } - if(! $hsig_valid) { - logger('http signature not valid: ' . print_r($hsig,true)); - continue; - } - } + if (strpos($webbie, 'http') === 0) { + $ap = ActivityPub::discover($webbie); + if ($ap) { + return $ap; + } + } - $x = Libzot::import_xchan($record['data']); - if($x['success']) { - return $x['hash']; - } - } - if($link['rel'] === 'self' && ($link['type'] === 'application/activity+json' || strpos($link['type'],'ld+json') !== false) && ((! $protocol) || (strtolower($protocol) === 'activitypub'))) { - $ap = ActivityPub::discover($link['href']); - if($ap) { - return $ap; - } - } - } - } - } + logger('webfinger: ' . print_r($x, true), LOGGER_DATA, LOG_INFO); - if(strpos($webbie,'http') === 0) { - $ap = ActivityPub::discover($webbie); - if($ap) { - return $ap; - } - } + $arr = [ + 'address' => $webbie, + 'protocol' => $protocol, + 'success' => false, + 'xchan' => '', + 'webfinger' => $x + ]; + /** + * @hooks discover_channel_webfinger + * Called when performing a webfinger lookup. + * * \e string \b address - The webbie + * * \e string \b protocol + * * \e array \b webfinger - The result from webfinger_rfc7033() + * * \e boolean \b success - The return value, default false + */ + call_hooks('discover_channel_webfinger', $arr); + if ($arr['success']) { + return $arr['xchan']; + } - logger('webfinger: ' . print_r($x,true), LOGGER_DATA, LOG_INFO); - - $arr = [ - 'address' => $webbie, - 'protocol' => $protocol, - 'success' => false, - 'xchan' => '', - 'webfinger' => $x - ]; - /** - * @hooks discover_channel_webfinger - * Called when performing a webfinger lookup. - * * \e string \b address - The webbie - * * \e string \b protocol - * * \e array \b webfinger - The result from webfinger_rfc7033() - * * \e boolean \b success - The return value, default false - */ - call_hooks('discover_channel_webfinger', $arr); - if($arr['success']) - return $arr['xchan']; - - return false; + return false; } /** @@ -1122,201 +1186,215 @@ function discover_by_webbie($webbie, $protocol = '', $verify = true) { * @param string $webbie - The resource * @return bool|string false or associative array from result JSON */ -function webfinger_rfc7033($webbie) { +function webfinger_rfc7033($webbie) +{ - if(strpos($webbie,'@')) { - $lhs = substr($webbie,0,strpos($webbie,'@')); - $rhs = substr($webbie,strpos($webbie,'@')+1); - $resource = urlencode('acct:' . $webbie); - } - else { - $m = parse_url($webbie); - if($m) { - if($m['scheme'] !== 'https') - return false; + if (strpos($webbie, '@')) { + $lhs = substr($webbie, 0, strpos($webbie, '@')); + $rhs = substr($webbie, strpos($webbie, '@') + 1); + $resource = urlencode('acct:' . $webbie); + } else { + $m = parse_url($webbie); + if ($m) { + if ($m['scheme'] !== 'https') { + return false; + } - $rhs = $m['host'] . ((isset($m['port']) && intval($m['port'])) ? ':' . intval($m['port']) : ''); - $resource = urlencode($webbie); - } - else - return false; - } - logger('fetching url from resource: ' . $rhs . ':' . $webbie); + $rhs = $m['host'] . ((isset($m['port']) && intval($m['port'])) ? ':' . intval($m['port']) : ''); + $resource = urlencode($webbie); + } else { + return false; + } + } + logger('fetching url from resource: ' . $rhs . ':' . $webbie); - $counter = 0; - $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''), - false, $counter, [ 'headers' => [ 'Accept: application/jrd+json, application/json, */*' ] ]); + $counter = 0; + $s = z_fetch_url( + 'https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''), + false, + $counter, + [ 'headers' => [ 'Accept: application/jrd+json, application/json, */*' ] ] + ); - if($s['success']) { - $j = json_decode($s['body'], true); - return($j); - } + if ($s['success']) { + $j = json_decode($s['body'], true); + return($j); + } - return false; + return false; } -function do_delivery($deliveries, $force = false) { +function do_delivery($deliveries, $force = false) +{ - // $force is set if a site that wasn't responding suddenly returns to life. - // Try and shove through everything going to that site while it's responding. + // $force is set if a site that wasn't responding suddenly returns to life. + // Try and shove through everything going to that site while it's responding. - if(! (is_array($deliveries) && count($deliveries))) - return; + if (! (is_array($deliveries) && count($deliveries))) { + return; + } - $x = q("select count(outq_hash) as total from outq where outq_delivered = 0"); - if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',3000)) && (! $force)) { - logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO); - foreach($deliveries as $d) { - Queue::update($d); - } - return; - } + $x = q("select count(outq_hash) as total from outq where outq_delivered = 0"); + if (intval($x[0]['total']) > intval(get_config('system', 'force_queue_threshold', 3000)) && (! $force)) { + logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO); + foreach ($deliveries as $d) { + Queue::update($d); + } + return; + } - $interval = ((get_config('system','delivery_interval') !== false) - ? intval(get_config('system','delivery_interval')) : 2 ); + $interval = ((get_config('system', 'delivery_interval') !== false) + ? intval(get_config('system', 'delivery_interval')) : 2 ); - $deliveries_per_process = intval(get_config('system','delivery_batch_count')); + $deliveries_per_process = intval(get_config('system', 'delivery_batch_count')); - if($deliveries_per_process <= 0) - $deliveries_per_process = 1; + if ($deliveries_per_process <= 0) { + $deliveries_per_process = 1; + } - $deliver = []; - foreach($deliveries as $d) { + $deliver = []; + foreach ($deliveries as $d) { + if (! $d) { + continue; + } - if(! $d) - continue; + $deliver[] = $d; - $deliver[] = $d; + if (count($deliver) >= $deliveries_per_process) { + Run::Summon([ 'Deliver',$deliver ]); + $deliver = []; + if ($interval) { + @time_sleep_until(microtime(true) + (float) $interval); + } + } + } - if(count($deliver) >= $deliveries_per_process) { - Run::Summon( [ 'Deliver',$deliver ] ); - $deliver = []; - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } + // catch any stragglers - // catch any stragglers - - if($deliver) { - Run::Summon( [ 'Deliver',$deliver ] ); - } + if ($deliver) { + Run::Summon([ 'Deliver',$deliver ]); + } } -function get_site_info() { +function get_site_info() +{ - $register_policy = Array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN'); - $directory_mode = Array('DIRECTORY_MODE_NORMAL', 'DIRECTORY_MODE_PRIMARY', 'DIRECTORY_MODE_SECONDARY', 256 => 'DIRECTORY_MODE_STANDALONE'); + $register_policy = array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN'); + $directory_mode = array('DIRECTORY_MODE_NORMAL', 'DIRECTORY_MODE_PRIMARY', 'DIRECTORY_MODE_SECONDARY', 256 => 'DIRECTORY_MODE_STANDALONE'); - $sql_extra = ''; + $sql_extra = ''; - $r = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 ) > 0 and account_default_channel = channel_id"); + $r = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 ) > 0 and account_default_channel = channel_id"); - if($r) { - $admin = []; - foreach($r as $rr) { - if($rr['channel_pageflags'] & PAGE_HUBADMIN) - $admin[] = array( 'name' => $rr['channel_name'], 'address' => channel_reddress($rr), 'channel' => z_root() . '/channel/' . $rr['channel_address']); - } - if(! $admin) { - foreach($r as $rr) { - $admin[] = array( 'name' => $rr['channel_name'], 'address' => channel_reddress($rr), 'channel' => z_root() . '/channel/' . $rr['channel_address']); - } - } - } - else { - $admin = false; - } + if ($r) { + $admin = []; + foreach ($r as $rr) { + if ($rr['channel_pageflags'] & PAGE_HUBADMIN) { + $admin[] = array( 'name' => $rr['channel_name'], 'address' => channel_reddress($rr), 'channel' => z_root() . '/channel/' . $rr['channel_address']); + } + } + if (! $admin) { + foreach ($r as $rr) { + $admin[] = array( 'name' => $rr['channel_name'], 'address' => channel_reddress($rr), 'channel' => z_root() . '/channel/' . $rr['channel_address']); + } + } + } else { + $admin = false; + } - $def_service_class = get_config('system','default_service_class'); - if($def_service_class) - $service_class = get_config('service_class',$def_service_class); - else - $service_class = false; + $def_service_class = get_config('system', 'default_service_class'); + if ($def_service_class) { + $service_class = get_config('service_class', $def_service_class); + } else { + $service_class = false; + } - $visible_plugins = visible_plugin_list(); + $visible_plugins = visible_plugin_list(); - if(@is_dir('.git') && function_exists('shell_exec')) - $commit = trim(@shell_exec('git log -1 --format="%h"')); - if(! isset($commit) || strlen($commit) > 16) - $commit = ''; + if (@is_dir('.git') && function_exists('shell_exec')) { + $commit = trim(@shell_exec('git log -1 --format="%h"')); + } + if (! isset($commit) || strlen($commit) > 16) { + $commit = ''; + } - $site_info = get_config('system','info'); - $site_name = get_config('system','sitename'); - if(! get_config('system','hidden_version_siteinfo')) { - $version = System::get_project_version(); + $site_info = get_config('system', 'info'); + $site_name = get_config('system', 'sitename'); + if (! get_config('system', 'hidden_version_siteinfo')) { + $version = System::get_project_version(); - if(@is_dir('.git') && function_exists('shell_exec')) { - $commit = trim( @shell_exec('git log -1 --format="%h"')); - } + if (@is_dir('.git') && function_exists('shell_exec')) { + $commit = trim(@shell_exec('git log -1 --format="%h"')); + } - if(! isset($commit) || strlen($commit) > 16) - $commit = ''; - } - else { - $version = $commit = ''; - } + if (! isset($commit) || strlen($commit) > 16) { + $commit = ''; + } + } else { + $version = $commit = ''; + } - //Statistics -// $channels_total_stat = intval(get_config('system','channels_total_stat')); -// $channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat')); -// $channels_active_monthly_stat = intval(get_config('system','channels_active_monthly_stat')); -// $local_posts_stat = intval(get_config('system','local_posts_stat')); -// $local_comments_stat = intval(get_config('system','local_comments_stat')); -// $hide_in_statistics = intval(get_config('system','hide_in_statistics')); + //Statistics +// $channels_total_stat = intval(get_config('system','channels_total_stat')); +// $channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat')); +// $channels_active_monthly_stat = intval(get_config('system','channels_active_monthly_stat')); +// $local_posts_stat = intval(get_config('system','local_posts_stat')); +// $local_comments_stat = intval(get_config('system','local_comments_stat')); +// $hide_in_statistics = intval(get_config('system','hide_in_statistics')); - $site_expire = intval(get_config('system', 'default_expire_days')); + $site_expire = intval(get_config('system', 'default_expire_days')); - load_config('feature_lock'); - $locked_features = []; - if(is_array(App::$config['feature_lock']) && count(App::$config['feature_lock'])) { - foreach(App::$config['feature_lock'] as $k => $v) { - if($k === 'config_loaded') - continue; + load_config('feature_lock'); + $locked_features = []; + if (is_array(App::$config['feature_lock']) && count(App::$config['feature_lock'])) { + foreach (App::$config['feature_lock'] as $k => $v) { + if ($k === 'config_loaded') { + continue; + } - $locked_features[$k] = intval($v); - } - } + $locked_features[$k] = intval($v); + } + } - $protocols = [ 'nomad' ]; - if (get_config('system','activitypub', ACTIVITYPUB_ENABLED)) { - $protocols[] = 'activitypub'; - } + $protocols = [ 'nomad' ]; + if (get_config('system', 'activitypub', ACTIVITYPUB_ENABLED)) { + $protocols[] = 'activitypub'; + } - $data = [ - 'url' => z_root(), - 'platform' => System::get_platform_name(), - 'site_name' => (($site_name) ? $site_name : ''), - 'version' => $version, -// 'version_tag' => $tag, - 'addon_version' => defined('ADDON_VERSION') ? ADDON_VERSION : 'unknown', - 'commit' => $commit, - 'protocols' => $protocols, - 'plugins' => $visible_plugins, - 'register_policy' => $register_policy[get_config('system','register_policy')], - 'invitation_only' => (bool) (defined('INVITE_WORKING') && intval(get_config('system','invitation_only'))), - 'directory_mode' => $directory_mode[get_config('system','directory_mode')], -// 'directory_server' => get_config('system','directory_server'), - 'language' => get_config('system','language'), -// 'rss_connections' => (bool) intval(get_config('system','feed_contacts')), - 'expiration' => $site_expire, - 'default_service_restrictions' => $service_class, - 'locked_features' => $locked_features, - 'admin' => $admin, - 'dbdriver' => DBA::$dba->getdriver() . ' ' . ((ACTIVE_DBTYPE == DBTYPE_POSTGRES) ? 'postgres' : 'mysql'), - 'lastpoll' => get_config('system','lastpoll'), - 'ebs' => System::ebs(), // bit.ly/3DGCmki - 'info' => (($site_info) ? $site_info : '') + $data = [ + 'url' => z_root(), + 'platform' => System::get_platform_name(), + 'site_name' => (($site_name) ? $site_name : ''), + 'version' => $version, +// 'version_tag' => $tag, + 'addon_version' => defined('ADDON_VERSION') ? ADDON_VERSION : 'unknown', + 'commit' => $commit, + 'protocols' => $protocols, + 'plugins' => $visible_plugins, + 'register_policy' => $register_policy[get_config('system', 'register_policy')], + 'invitation_only' => (bool) (defined('INVITE_WORKING') && intval(get_config('system', 'invitation_only'))), + 'directory_mode' => $directory_mode[get_config('system', 'directory_mode')], +// 'directory_server' => get_config('system','directory_server'), + 'language' => get_config('system', 'language'), +// 'rss_connections' => (bool) intval(get_config('system','feed_contacts')), + 'expiration' => $site_expire, + 'default_service_restrictions' => $service_class, + 'locked_features' => $locked_features, + 'admin' => $admin, + 'dbdriver' => DBA::$dba->getdriver() . ' ' . ((ACTIVE_DBTYPE == DBTYPE_POSTGRES) ? 'postgres' : 'mysql'), + 'lastpoll' => get_config('system', 'lastpoll'), + 'ebs' => System::ebs(), // bit.ly/3DGCmki + 'info' => (($site_info) ? $site_info : '') - ]; + ]; - return $data; + return $data; } /** @@ -1325,56 +1403,57 @@ function get_site_info() { * @param string $url * @return bool */ -function check_siteallowed($url) { +function check_siteallowed($url) +{ - $retvalue = true; + $retvalue = true; - $arr = [ 'url' => $url ]; - /** - * @hooks check_siteallowed - * Used to over-ride or bypass the site black/white block lists. - * * \e string \b url - * * \e boolean \b allowed - optional return value set in hook - */ - call_hooks('check_siteallowed', $arr); + $arr = [ 'url' => $url ]; + /** + * @hooks check_siteallowed + * Used to over-ride or bypass the site black/white block lists. + * * \e string \b url + * * \e boolean \b allowed - optional return value set in hook + */ + call_hooks('check_siteallowed', $arr); - if (array_key_exists('allowed',$arr)) { - return $arr['allowed']; - } + if (array_key_exists('allowed', $arr)) { + return $arr['allowed']; + } - // your own site is always allowed - if (strpos($url, z_root()) !== false) { - return $retvalue; - } + // your own site is always allowed + if (strpos($url, z_root()) !== false) { + return $retvalue; + } - $bl1 = get_config('system','allowed_sites'); - $bl2 = get_config('system','denied_sites'); + $bl1 = get_config('system', 'allowed_sites'); + $bl2 = get_config('system', 'denied_sites'); - if (is_array($bl1) && $bl1) { - if (! (is_array($bl2) && $bl2)) { - $retvalue = false; - } - foreach ($bl1 as $bl) { - if ($bl === '*') { - $retvalue = true; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return true; - } - } - } - if (is_array($bl2) && $bl2) { - foreach ($bl2 as $bl) { - if ($bl === '*') { - $retvalue = false; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return false; - } - } - } + if (is_array($bl1) && $bl1) { + if (! (is_array($bl2) && $bl2)) { + $retvalue = false; + } + foreach ($bl1 as $bl) { + if ($bl === '*') { + $retvalue = true; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return true; + } + } + } + if (is_array($bl2) && $bl2) { + foreach ($bl2 as $bl) { + if ($bl === '*') { + $retvalue = false; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return false; + } + } + } - return $retvalue; + return $retvalue; } /** @@ -1383,56 +1462,57 @@ function check_siteallowed($url) { * @param string $url * @return bool */ -function check_pubstream_siteallowed($url) { +function check_pubstream_siteallowed($url) +{ - $retvalue = true; + $retvalue = true; - $arr = array('url' => $url); - /** - * @hooks check_siteallowed - * Used to over-ride or bypass the site black/white block lists. - * * \e string \b url - * * \e boolean \b allowed - optional return value set in hook - */ - call_hooks('pubstream_check_siteallowed', $arr); + $arr = array('url' => $url); + /** + * @hooks check_siteallowed + * Used to over-ride or bypass the site black/white block lists. + * * \e string \b url + * * \e boolean \b allowed - optional return value set in hook + */ + call_hooks('pubstream_check_siteallowed', $arr); - if (array_key_exists('allowed',$arr)) { - return $arr['allowed']; - } + if (array_key_exists('allowed', $arr)) { + return $arr['allowed']; + } - // your own site is always allowed - if (strpos($url, z_root()) !== false) { - return $retvalue; - } + // your own site is always allowed + if (strpos($url, z_root()) !== false) { + return $retvalue; + } - $bl1 = get_config('system','pubstream_allowed_sites'); - $bl2 = get_config('system','pubstream_denied_sites'); + $bl1 = get_config('system', 'pubstream_allowed_sites'); + $bl2 = get_config('system', 'pubstream_denied_sites'); - if (is_array($bl1) && $bl1) { - if (! (is_array($bl2) && $bl2)) { - $retvalue = false; - } - foreach ($bl1 as $bl) { - if ($bl === '*') { - $retvalue = true; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return true; - } - } - } - if (is_array($bl2) && $bl2) { - foreach ($bl2 as $bl) { - if ($bl === '*') { - $retvalue = false; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return false; - } - } - } + if (is_array($bl1) && $bl1) { + if (! (is_array($bl2) && $bl2)) { + $retvalue = false; + } + foreach ($bl1 as $bl) { + if ($bl === '*') { + $retvalue = true; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return true; + } + } + } + if (is_array($bl2) && $bl2) { + foreach ($bl2 as $bl) { + if ($bl === '*') { + $retvalue = false; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return false; + } + } + } - return $retvalue; + return $retvalue; } @@ -1443,51 +1523,52 @@ function check_pubstream_siteallowed($url) { * @param string $hash * @return bool */ -function check_channelallowed($hash) { +function check_channelallowed($hash) +{ - $retvalue = true; + $retvalue = true; - $arr = [ 'hash' => $hash ]; - /** - * @hooks check_channelallowed - * Used to over-ride or bypass the channel black/white block lists. - * * \e string \b hash - * * \e boolean \b allowed - optional return value set in hook - */ - call_hooks('check_channelallowed', $arr); + $arr = [ 'hash' => $hash ]; + /** + * @hooks check_channelallowed + * Used to over-ride or bypass the channel black/white block lists. + * * \e string \b hash + * * \e boolean \b allowed - optional return value set in hook + */ + call_hooks('check_channelallowed', $arr); - if (array_key_exists('allowed',$arr)) { - return $arr['allowed']; - } + if (array_key_exists('allowed', $arr)) { + return $arr['allowed']; + } - $bl1 = get_config('system','allowed_channels'); - $bl2 = get_config('system','denied_channels'); + $bl1 = get_config('system', 'allowed_channels'); + $bl2 = get_config('system', 'denied_channels'); - if (is_array($bl1) && $bl1) { - if (! (is_array($bl2) && $bl2)) { - $retvalue = false; - } - foreach ($bl1 as $bl) { - if ($bl === '*') { - $retvalue = true; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return true; - } - } - } - if (is_array($bl2) && $bl2) { - foreach ($bl2 as $bl) { - if ($bl === '*') { - $retvalue = false; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return false; - } - } - } + if (is_array($bl1) && $bl1) { + if (! (is_array($bl2) && $bl2)) { + $retvalue = false; + } + foreach ($bl1 as $bl) { + if ($bl === '*') { + $retvalue = true; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return true; + } + } + } + if (is_array($bl2) && $bl2) { + foreach ($bl2 as $bl) { + if ($bl === '*') { + $retvalue = false; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return false; + } + } + } - return $retvalue; + return $retvalue; } @@ -1497,89 +1578,97 @@ function check_channelallowed($hash) { * @param string $hash * @return bool */ -function check_pubstream_channelallowed($hash) { +function check_pubstream_channelallowed($hash) +{ - $retvalue = true; + $retvalue = true; - $arr = array('hash' => $hash); - /** - * @hooks check_channelallowed - * Used to over-ride or bypass the channel black/white block lists. - * * \e string \b hash - * * \e boolean \b allowed - optional return value set in hook - */ - call_hooks('check_pubstream_channelallowed', $arr); + $arr = array('hash' => $hash); + /** + * @hooks check_channelallowed + * Used to over-ride or bypass the channel black/white block lists. + * * \e string \b hash + * * \e boolean \b allowed - optional return value set in hook + */ + call_hooks('check_pubstream_channelallowed', $arr); - if (array_key_exists('allowed',$arr)) { - return $arr['allowed']; - } + if (array_key_exists('allowed', $arr)) { + return $arr['allowed']; + } - $bl1 = get_config('system','pubstream_allowed_channels'); - $bl2 = get_config('system','pubstream_denied_channels'); + $bl1 = get_config('system', 'pubstream_allowed_channels'); + $bl2 = get_config('system', 'pubstream_denied_channels'); - if (is_array($bl1) && $bl1) { - if (! (is_array($bl2) && $bl2)) { - $retvalue = false; - } - foreach ($bl1 as $bl) { - if ($bl === '*') { - $retvalue = true; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return true; - } - } - } - if (is_array($bl2) && $bl2) { - foreach ($bl2 as $bl) { - if ($bl === '*') { - $retvalue = false; - } - if ($bl && (strpos($url,$bl) !== false || wildmat($bl,$url))) { - return false; - } - } - } + if (is_array($bl1) && $bl1) { + if (! (is_array($bl2) && $bl2)) { + $retvalue = false; + } + foreach ($bl1 as $bl) { + if ($bl === '*') { + $retvalue = true; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return true; + } + } + } + if (is_array($bl2) && $bl2) { + foreach ($bl2 as $bl) { + if ($bl === '*') { + $retvalue = false; + } + if ($bl && (strpos($url, $bl) !== false || wildmat($bl, $url))) { + return false; + } + } + } - return $retvalue; + return $retvalue; } -function deliverable_singleton($channel_id,$xchan) { +function deliverable_singleton($channel_id, $xchan) +{ - if(array_key_exists('xchan_hash',$xchan)) - $xchan_hash = $xchan['xchan_hash']; - elseif(array_key_exists('hubloc_hash',$xchan)) - $xchan_hash = $xchan['hubloc_hash']; - else - return true; + if (array_key_exists('xchan_hash', $xchan)) { + $xchan_hash = $xchan['xchan_hash']; + } elseif (array_key_exists('hubloc_hash', $xchan)) { + $xchan_hash = $xchan['hubloc_hash']; + } else { + return true; + } - $r = q("select abook_instance from abook where abook_channel = %d and abook_xchan = '%s' limit 1", - intval($channel_id), - dbesc($xchan_hash) - ); - if($r) { - if(! $r[0]['abook_instance']) - return true; - if(strpos($r[0]['abook_instance'],z_root()) !== false) - return true; - } - return false; + $r = q( + "select abook_instance from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + intval($channel_id), + dbesc($xchan_hash) + ); + if ($r) { + if (! $r[0]['abook_instance']) { + return true; + } + if (strpos($r[0]['abook_instance'], z_root()) !== false) { + return true; + } + } + return false; } -function get_repository_version($branch = 'release') { +function get_repository_version($branch = 'release') +{ - $path = "https://codeberg.org/zot/" . ((PLATFORM_NAME === 'mistpark') ? 'misty' : PLATFORM_NAME) . "/raw/$branch/boot.php"; + $path = "https://codeberg.org/zot/" . ((PLATFORM_NAME === 'mistpark') ? 'misty' : PLATFORM_NAME) . "/raw/$branch/boot.php"; - $x = z_fetch_url($path); - if($x['success']) { - $y = preg_match('/define(.*?)STD_VERSION(.*?)([0-9.].*)\'/',$x['body'],$matches); - if($y) - return $matches[3]; - } - return '?.?'; + $x = z_fetch_url($path); + if ($x['success']) { + $y = preg_match('/define(.*?)STD_VERSION(.*?)([0-9.].*)\'/', $x['body'], $matches); + if ($y) { + return $matches[3]; + } + } + return '?.?'; } /** @@ -1588,35 +1677,36 @@ function get_repository_version($branch = 'release') { * @param string $s Network string, see boot.php * @return string Translated name of the network */ -function network_to_name($s) { +function network_to_name($s) +{ - $nets = array( - NETWORK_DFRN => t('Friendica'), - NETWORK_FRND => t('Friendica'), - NETWORK_OSTATUS => t('OStatus'), - NETWORK_GNUSOCIAL => t('GNU-Social'), - NETWORK_FEED => t('RSS/Atom'), - NETWORK_ACTIVITYPUB => t('ActivityPub'), - NETWORK_MAIL => t('Email'), - NETWORK_DIASPORA => t('Diaspora'), - NETWORK_FACEBOOK => t('Facebook'), - NETWORK_ZOT6 => t('Nomad'), - NETWORK_ZOT => t('Zot'), - NETWORK_LINKEDIN => t('LinkedIn'), - NETWORK_XMPP => t('XMPP/IM'), - NETWORK_MYSPACE => t('MySpace'), - ); + $nets = array( + NETWORK_DFRN => t('Friendica'), + NETWORK_FRND => t('Friendica'), + NETWORK_OSTATUS => t('OStatus'), + NETWORK_GNUSOCIAL => t('GNU-Social'), + NETWORK_FEED => t('RSS/Atom'), + NETWORK_ACTIVITYPUB => t('ActivityPub'), + NETWORK_MAIL => t('Email'), + NETWORK_DIASPORA => t('Diaspora'), + NETWORK_FACEBOOK => t('Facebook'), + NETWORK_ZOT6 => t('Nomad'), + NETWORK_ZOT => t('Zot'), + NETWORK_LINKEDIN => t('LinkedIn'), + NETWORK_XMPP => t('XMPP/IM'), + NETWORK_MYSPACE => t('MySpace'), + ); - /** - * @hooks network_to_name - * @deprecated - */ - call_hooks('network_to_name', $nets); + /** + * @hooks network_to_name + * @deprecated + */ + call_hooks('network_to_name', $nets); - $search = array_keys($nets); - $replace = array_values($nets); + $search = array_keys($nets); + $replace = array_values($nets); - return str_replace($search, $replace, $s); + return str_replace($search, $replace, $s); } /** @@ -1632,57 +1722,61 @@ function network_to_name($s) { * * \e string \b textVersion text only version of the message * * \e string \b additionalMailHeader additions to the smtp mail header */ -function z_mail($params) { +function z_mail($params) +{ - if(! $params['fromEmail']) { - $params['fromEmail'] = get_config('system','from_email'); - if(! $params['fromEmail']) - $params['fromEmail'] = 'Administrator' . '@' . App::get_hostname(); - } - if(! $params['fromName']) { - $params['fromName'] = get_config('system','from_email_name'); - if(! $params['fromName']) - $params['fromName'] = System::get_site_name(); - } - if(! $params['replyTo']) { - $params['replyTo'] = get_config('system','reply_address'); - if(! $params['replyTo']) - $params['replyTo'] = 'noreply' . '@' . App::get_hostname(); - } + if (! $params['fromEmail']) { + $params['fromEmail'] = get_config('system', 'from_email'); + if (! $params['fromEmail']) { + $params['fromEmail'] = 'Administrator' . '@' . App::get_hostname(); + } + } + if (! $params['fromName']) { + $params['fromName'] = get_config('system', 'from_email_name'); + if (! $params['fromName']) { + $params['fromName'] = System::get_site_name(); + } + } + if (! $params['replyTo']) { + $params['replyTo'] = get_config('system', 'reply_address'); + if (! $params['replyTo']) { + $params['replyTo'] = 'noreply' . '@' . App::get_hostname(); + } + } - $params['sent'] = false; - $params['result'] = false; + $params['sent'] = false; + $params['result'] = false; - /** - * @hooks email_send - * * \e params @see z_mail() - */ - call_hooks('email_send', $params); + /** + * @hooks email_send + * * \e params @see z_mail() + */ + call_hooks('email_send', $params); - if($params['sent']) { - logger('notification: z_mail returns ' . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG); - return $params['result']; - } + if ($params['sent']) { + logger('notification: z_mail returns ' . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG); + return $params['result']; + } - $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8'); - $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8'); + $fromName = email_header_encode(html_entity_decode($params['fromName'], ENT_QUOTES, 'UTF-8'), 'UTF-8'); + $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'], ENT_QUOTES, 'UTF-8'), 'UTF-8'); - $messageHeader = - $params['additionalMailHeader'] . + $messageHeader = + $params['additionalMailHeader'] . - "From: $fromName <{$params['fromEmail']}>" .PHP_EOL . - "Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL . - "Content-Type: text/plain; charset=UTF-8"; + "From: $fromName <{$params['fromEmail']}>" . PHP_EOL . + "Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL . + "Content-Type: text/plain; charset=UTF-8"; - // send the message - $res = mail( - $params['toEmail'], // send to address - $messageSubject, // subject - $params['textVersion'], - $messageHeader // message headers - ); - logger('notification: z_mail returns ' . (($res) ? 'success' : 'failure'), LOGGER_DEBUG); - return $res; + // send the message + $res = mail( + $params['toEmail'], // send to address + $messageSubject, // subject + $params['textVersion'], + $messageHeader // message headers + ); + logger('notification: z_mail returns ' . (($res) ? 'success' : 'failure'), LOGGER_DEBUG); + return $res; } @@ -1692,50 +1786,52 @@ function z_mail($params) { * @param string $host * @return string */ -function probe_api_path($host) { +function probe_api_path($host) +{ - $schemes = ['https', 'http' ]; - $paths = ['/api/z/1.0/version', '/api/red/version' ]; + $schemes = ['https', 'http' ]; + $paths = ['/api/z/1.0/version', '/api/red/version' ]; - foreach($schemes as $scheme) { - foreach($paths as $path) { - $curpath = $scheme . '://' . $host . $path; - $x = z_fetch_url($curpath); - if($x['success'] && ! strpos($x['body'], 'not implemented')) - return str_replace('version', '', $curpath); - } - } + foreach ($schemes as $scheme) { + foreach ($paths as $path) { + $curpath = $scheme . '://' . $host . $path; + $x = z_fetch_url($curpath); + if ($x['success'] && ! strpos($x['body'], 'not implemented')) { + return str_replace('version', '', $curpath); + } + } + } - return ''; + return ''; } -function service_plink($contact, $guid) { +function service_plink($contact, $guid) +{ - $plink = ''; + $plink = ''; - $m = parse_url($contact['xchan_url']); - if($m) { - $url = $m['scheme'] . '://' . $m['host'] . ((isset($m['port']) && intval($m['port'])) ? ':' . intval($m['port']) : ''); - } - else { - $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1); - } + $m = parse_url($contact['xchan_url']); + if ($m) { + $url = $m['scheme'] . '://' . $m['host'] . ((isset($m['port']) && intval($m['port'])) ? ':' . intval($m['port']) : ''); + } else { + $url = 'https://' . substr($contact['xchan_addr'], strpos($contact['xchan_addr'], '@') + 1); + } - $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@')); + $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'], '@')); - $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid; + $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid; - $x = [ 'xchan' => $contact, 'guid' => $guid, 'url' => $url, 'plink' => $plink ]; - /** - * @hooks service_plink - * * \e array \b xchan - * * \e string \b guid - * * \e string \b url - * * \e string \b plink will get returned - */ - call_hooks('service_plink', $x); + $x = [ 'xchan' => $contact, 'guid' => $guid, 'url' => $url, 'plink' => $plink ]; + /** + * @hooks service_plink + * * \e array \b xchan + * * \e string \b guid + * * \e string \b url + * * \e string \b plink will get returned + */ + call_hooks('service_plink', $x); - return $x['plink']; + return $x['plink']; } @@ -1746,44 +1842,49 @@ function service_plink($contact, $guid) { * @param string $acceptedTypes by default false will use $_SERVER['HTTP_ACCEPT'] * @return array|NULL */ -function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) { - // Values will be stored in this array - $AcceptTypes = []; +function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) +{ + // Values will be stored in this array + $AcceptTypes = []; - if($acceptedTypes === false) { - $acceptedTypes = ((isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : EMPTY_STR); - } + if ($acceptedTypes === false) { + $acceptedTypes = ((isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : EMPTY_STR); + } - // Accept header is case insensitive, and whitespace isn’t important - $accept = strtolower(str_replace(' ', '', $acceptedTypes)); - // divide it into parts in the place of a "," - $accept = explode(',', $accept); - foreach ($accept as $a) { - // the default quality is 1. - $q = 1; - // check if there is a different quality - if (strpos($a, ';q=')) { - // divide "mime/type;q=X" into two parts: "mime/type" i "X" - list($a, $q) = explode(';q=', $a); - } - // mime-type $a is accepted with the quality $q - // WARNING: $q == 0 means, that mime-type isn’t supported! - $AcceptTypes[$a] = $q; - } - arsort($AcceptTypes); + // Accept header is case insensitive, and whitespace isn’t important + $accept = strtolower(str_replace(' ', '', $acceptedTypes)); + // divide it into parts in the place of a "," + $accept = explode(',', $accept); + foreach ($accept as $a) { + // the default quality is 1. + $q = 1; + // check if there is a different quality + if (strpos($a, ';q=')) { + // divide "mime/type;q=X" into two parts: "mime/type" i "X" + list($a, $q) = explode(';q=', $a); + } + // mime-type $a is accepted with the quality $q + // WARNING: $q == 0 means, that mime-type isn’t supported! + $AcceptTypes[$a] = $q; + } + arsort($AcceptTypes); - // if no parameter was passed, just return parsed data - if (!$mimeTypes) return $AcceptTypes; + // if no parameter was passed, just return parsed data + if (!$mimeTypes) { + return $AcceptTypes; + } - $mimeTypes = array_map('strtolower', (array)$mimeTypes); + $mimeTypes = array_map('strtolower', (array)$mimeTypes); - // let’s check our supported types: - foreach ($AcceptTypes as $mime => $q) { - if ($q && in_array($mime, $mimeTypes)) return $mime; - } + // let’s check our supported types: + foreach ($AcceptTypes as $mime => $q) { + if ($q && in_array($mime, $mimeTypes)) { + return $mime; + } + } - // no mime-type found - return null; + // no mime-type found + return null; } /** @@ -1792,65 +1893,66 @@ function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) { * @param string $url * @return mixed|bool|array */ -function jsonld_document_loader($url) { +function jsonld_document_loader($url) +{ - require_once('library/jsonld/jsonld.php'); + require_once('library/jsonld/jsonld.php'); - $recursion = 0; + $recursion = 0; - $x = debug_backtrace(); - if($x) { - foreach($x as $n) { - if($n['function'] === __FUNCTION__) { - $recursion ++; - } - } - } - if($recursion > 5) { - logger('jsonld bomb detected at: ' . $url); - killme(); - } + $x = debug_backtrace(); + if ($x) { + foreach ($x as $n) { + if ($n['function'] === __FUNCTION__) { + $recursion++; + } + } + } + if ($recursion > 5) { + logger('jsonld bomb detected at: ' . $url); + killme(); + } - $cachepath = 'cache/ldcache'; - if(! is_dir($cachepath)) - os_mkdir($cachepath, STORAGE_DEFAULT_PERMISSIONS, true); + $cachepath = 'cache/ldcache'; + if (! is_dir($cachepath)) { + os_mkdir($cachepath, STORAGE_DEFAULT_PERMISSIONS, true); + } - $filename = $cachepath . '/' . urlencode($url); - if(file_exists($filename) && filemtime($filename) > time() - (12 * 60 * 60)) { - return json_decode(file_get_contents($filename)); - } + $filename = $cachepath . '/' . urlencode($url); + if (file_exists($filename) && filemtime($filename) > time() - (12 * 60 * 60)) { + return json_decode(file_get_contents($filename)); + } - $r = jsonld_default_document_loader($url); - if($r) { - file_put_contents($filename, json_encode($r)); - return $r; - } + $r = jsonld_default_document_loader($url); + if ($r) { + file_put_contents($filename, json_encode($r)); + return $r; + } - logger('not found'); - if(file_exists($filename)) { - return json_decode(file_get_contents($filename)); - } + logger('not found'); + if (file_exists($filename)) { + return json_decode(file_get_contents($filename)); + } - return []; + return []; } -function is_https_request() { +function is_https_request() +{ - $https = false; + $https = false; - if (array_key_exists('HTTPS',$_SERVER) && $_SERVER['HTTPS']) { - $https = true; - } - elseif (array_key_exists('SERVER_PORT',$_SERVER) && intval($_SERVER['SERVER_PORT']) === 443) { - $https = true; - } - elseif (array_key_exists('HTTP_X_FORWARDED_PROTO',$_SERVER) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $https = true; // technically this is not true, but pretending it is will allow reverse proxies to work - } + if (array_key_exists('HTTPS', $_SERVER) && $_SERVER['HTTPS']) { + $https = true; + } elseif (array_key_exists('SERVER_PORT', $_SERVER) && intval($_SERVER['SERVER_PORT']) === 443) { + $https = true; + } elseif (array_key_exists('HTTP_X_FORWARDED_PROTO', $_SERVER) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $https = true; // technically this is not true, but pretending it is will allow reverse proxies to work + } - return $https; + return $https; } /** @@ -1862,15 +1964,13 @@ function is_https_request() { * result always returns the leading slash */ -function get_request_string($url) { +function get_request_string($url) +{ - $m = parse_url($url); - if ($m) { - return ( (isset($m['path']) ? $m['path'] : '/' ) . (isset($m['query']) ? '?' . $m['query'] : EMPTY_STR) ); - } - - return EMPTY_STR; + $m = parse_url($url); + if ($m) { + return ( (isset($m['path']) ? $m['path'] : '/' ) . (isset($m['query']) ? '?' . $m['query'] : EMPTY_STR) ); + } + return EMPTY_STR; } - - diff --git a/include/oauth.php b/include/oauth.php index 7f3f24fd1..2d71cac1f 100644 --- a/include/oauth.php +++ b/include/oauth.php @@ -1,8 +1,10 @@ -key), dbesc($token_type), dbesc($token) @@ -58,7 +62,8 @@ class ZotOAuth1DataStore extends OAuth1DataStore public function lookup_nonce($consumer, $token, $nonce, $timestamp) { - $r = q("SELECT id, secret FROM tokens WHERE client_id = '%s' AND id = '%s' AND expires = %d", + $r = q( + "SELECT id, secret FROM tokens WHERE client_id = '%s' AND id = '%s' AND expires = %d", dbesc($consumer->key), dbesc($nonce), intval($timestamp) @@ -84,12 +89,14 @@ class ZotOAuth1DataStore extends OAuth1DataStore $k = $consumer; } - $r = q("INSERT INTO tokens (id, secret, client_id, auth_scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, 0)", + $r = q( + "INSERT INTO tokens (id, secret, client_id, auth_scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, 0)", dbesc($key), dbesc($sec), dbesc($k), 'request', - time() + intval(REQUEST_TOKEN_DURATION)); + time() + intval(REQUEST_TOKEN_DURATION) + ); if (!$r) { return null; @@ -113,17 +120,18 @@ class ZotOAuth1DataStore extends OAuth1DataStore $uverifier = get_config("oauth", $verifier); logger(__function__ . ':' . $verifier . ', ' . $uverifier, LOGGER_DEBUG); if (is_null($verifier) || ($uverifier !== false)) { - $key = $this->gen_token(); $sec = $this->gen_token(); - $r = q("INSERT INTO tokens (id, secret, client_id, auth_scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, %d)", + $r = q( + "INSERT INTO tokens (id, secret, client_id, auth_scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, %d)", dbesc($key), dbesc($sec), dbesc($consumer->key), 'access', time() + intval(ACCESS_TOKEN_DURATION), - intval($uverifier)); + intval($uverifier) + ); if ($r) { $ret = new OAuth1Token($key, $sec); @@ -156,7 +164,8 @@ class ZotOAuth1 extends OAuth1Server logger("ZotOAuth1::loginUser $uid"); - $r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1", + $r = q( + "SELECT * FROM channel WHERE channel_id = %d LIMIT 1", intval($uid) ); if ($r) { @@ -171,7 +180,8 @@ class ZotOAuth1 extends OAuth1Server $_SESSION['uid'] = $record['channel_id']; $_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; - $x = q("select * from account where account_id = %d limit 1", + $x = q( + "select * from account where account_id = %d limit 1", intval($record['channel_account_id']) ); if ($x) { @@ -180,6 +190,4 @@ class ZotOAuth1 extends OAuth1Server $_SESSION['allow_api'] = true; } } - } - diff --git a/include/oembed.php b/include/oembed.php index 78c53a2ba..50f68b581 100644 --- a/include/oembed.php +++ b/include/oembed.php @@ -1,453 +1,472 @@ -' . $result['url'] . ''; + } - $result = oembed_action($embedurl); - if($result['action'] === 'block') { - return '' . $result['url'] . ''; - } - - $j = oembed_fetch_url($result['url']); - $s = oembed_format_object($j); - return $s; + $j = oembed_fetch_url($result['url']); + $s = oembed_format_object($j); + return $s; } -function oembed_action($embedurl) { +function oembed_action($embedurl) +{ - $host = ''; - $action = 'filter'; + $host = ''; + $action = 'filter'; - $embedurl = trim(str_replace('&','&', $embedurl)); + $embedurl = trim(str_replace('&', '&', $embedurl)); - //logger('oembed_action: ' . $embedurl, LOGGER_DEBUG, LOG_INFO); + //logger('oembed_action: ' . $embedurl, LOGGER_DEBUG, LOG_INFO); - if(strpos($embedurl,'http://') === 0) { - if(intval(get_config('system','embed_sslonly'))) { - $action = 'block'; - } - } + if (strpos($embedurl, 'http://') === 0) { + if (intval(get_config('system', 'embed_sslonly'))) { + $action = 'block'; + } + } - if(strpos($embedurl,'.well-known') !== false) - $action = 'block'; + if (strpos($embedurl, '.well-known') !== false) { + $action = 'block'; + } - // site allow/deny list + // site allow/deny list - if(($x = get_config('system','embed_deny'))) { - if(($x) && (! is_array($x))) - $x = explode("\n",$x); - if($x) { - foreach($x as $ll) { - $t = trim($ll); - if(($t) && (strpos($embedurl,$t) !== false)) { - $action = 'block'; - break; - } - } - } - } - - $found = false; + if (($x = get_config('system', 'embed_deny'))) { + if (($x) && (! is_array($x))) { + $x = explode("\n", $x); + } + if ($x) { + foreach ($x as $ll) { + $t = trim($ll); + if (($t) && (strpos($embedurl, $t) !== false)) { + $action = 'block'; + break; + } + } + } + } - if(($x = get_config('system','embed_allow'))) { - if(($x) && (! is_array($x))) - $x = explode("\n",$x); - if($x) { - foreach($x as $ll) { - $t = trim($ll); - if(($t) && (strpos($embedurl,$t) !== false) && ($action !== 'block')) { - $found = true; - $action = 'allow'; - break; - } - } - } - if((! $found) && ($action !== 'block')) { - $action = 'filter'; - } - } + $found = false; - // allow individual members to block something that wasn't blocked already. - // They cannot over-ride the site to allow or change the filtering on an - // embed that is not allowed by the site admin. + if (($x = get_config('system', 'embed_allow'))) { + if (($x) && (! is_array($x))) { + $x = explode("\n", $x); + } + if ($x) { + foreach ($x as $ll) { + $t = trim($ll); + if (($t) && (strpos($embedurl, $t) !== false) && ($action !== 'block')) { + $found = true; + $action = 'allow'; + break; + } + } + } + if ((! $found) && ($action !== 'block')) { + $action = 'filter'; + } + } - if(local_channel()) { - if(($x = get_pconfig(local_channel(),'system','embed_deny'))) { - if(($x) && (! is_array($x))) - $x = explode("\n",$x); - if($x) { - foreach($x as $ll) { - $t = trim($ll); - if(($t) && (strpos($embedurl,$t) !== false)) { - $action = 'block'; - break; - } - } - } - } - } + // allow individual members to block something that wasn't blocked already. + // They cannot over-ride the site to allow or change the filtering on an + // embed that is not allowed by the site admin. - $arr = array('url' => $embedurl, 'action' => $action); - call_hooks('oembed_action',$arr); + if (local_channel()) { + if (($x = get_pconfig(local_channel(), 'system', 'embed_deny'))) { + if (($x) && (! is_array($x))) { + $x = explode("\n", $x); + } + if ($x) { + foreach ($x as $ll) { + $t = trim($ll); + if (($t) && (strpos($embedurl, $t) !== false)) { + $action = 'block'; + break; + } + } + } + } + } - //logger('action: ' . $arr['action'] . ' url: ' . $arr['url'], LOGGER_DEBUG,LOG_DEBUG); + $arr = array('url' => $embedurl, 'action' => $action); + call_hooks('oembed_action', $arr); - return $arr; + //logger('action: ' . $arr['action'] . ' url: ' . $arr['url'], LOGGER_DEBUG,LOG_DEBUG); + return $arr; } // if the url is embeddable with oembed, return the bbcode link. -function oembed_process($url) { +function oembed_process($url) +{ - $j = oembed_fetch_url($url); - logger('oembed_process: ' . print_r($j,true), LOGGER_DATA, LOG_DEBUG); - if($j && $j['type'] !== 'error') - return '[embed]' . $url . '[/embed]'; - return false; + $j = oembed_fetch_url($url); + logger('oembed_process: ' . print_r($j, true), LOGGER_DATA, LOG_DEBUG); + if ($j && $j['type'] !== 'error') { + return '[embed]' . $url . '[/embed]'; + } + return false; } -function oembed_fetch_url($embedurl){ +function oembed_fetch_url($embedurl) +{ - $noexts = [ '.mp3', '.mp4', '.ogg', '.ogv', '.oga', '.ogm', '.webm', '.opus', '.m4a', '.mov' ]; + $noexts = [ '.mp3', '.mp4', '.ogg', '.ogv', '.oga', '.ogm', '.webm', '.opus', '.m4a', '.mov' ]; - $result = oembed_action($embedurl); + $result = oembed_action($embedurl); - $embedurl = $result['url']; - $action = $result['action']; + $embedurl = $result['url']; + $action = $result['action']; - foreach($noexts as $ext) { - if(strpos(strtolower($embedurl),$ext) !== false) { - $action = 'block'; - } - } + foreach ($noexts as $ext) { + if (strpos(strtolower($embedurl), $ext) !== false) { + $action = 'block'; + } + } - $txt = null; + $txt = null; - // we should try to cache this and avoid a lookup on each render - $is_matrix = is_matrix_url($embedurl); + // we should try to cache this and avoid a lookup on each render + $is_matrix = is_matrix_url($embedurl); - $zrl = ((get_config('system','oembed_zrl')) ? $is_matrix : false); + $zrl = ((get_config('system', 'oembed_zrl')) ? $is_matrix : false); - $furl = ((local_channel() && $zrl) ? zid($embedurl) : $embedurl); + $furl = ((local_channel() && $zrl) ? zid($embedurl) : $embedurl); - if($action !== 'block' && (! get_config('system','oembed_cache_disable'))) { - $txt = Cache::get('[' . App::$videowidth . '] ' . $furl); - } + if ($action !== 'block' && (! get_config('system', 'oembed_cache_disable'))) { + $txt = Cache::get('[' . App::$videowidth . '] ' . $furl); + } - if(strpos(strtolower($embedurl),'.pdf') !== false && get_config('system','inline_pdf')) { - $action = 'allow'; - $j = [ - 'html' => '', - 'title' => t('View PDF'), - 'type' => 'pdf' - ]; - - // set $txt to something so that we don't attempt to fetch what could be a lengthy pdf. - $txt = EMPTY_STR; - } + if (strpos(strtolower($embedurl), '.pdf') !== false && get_config('system', 'inline_pdf')) { + $action = 'allow'; + $j = [ + 'html' => '', + 'title' => t('View PDF'), + 'type' => 'pdf' + ]; - if(is_null($txt)) { + // set $txt to something so that we don't attempt to fetch what could be a lengthy pdf. + $txt = EMPTY_STR; + } - $txt = ""; + if (is_null($txt)) { + $txt = ""; - if ($action !== 'block') { - // try oembed autodiscovery - $redirects = 0; - $result = z_fetch_url($furl, false, $redirects, - [ - 'timeout' => 30, - 'accept_content' => "text/*", - 'novalidate' => true, - 'session' => ((local_channel() && $zrl) ? true : false) - ] - ); + if ($action !== 'block') { + // try oembed autodiscovery + $redirects = 0; + $result = z_fetch_url( + $furl, + false, + $redirects, + [ + 'timeout' => 30, + 'accept_content' => "text/*", + 'novalidate' => true, + 'session' => ((local_channel() && $zrl) ? true : false) + ] + ); - if($result['success']) - $html_text = $result['body']; - else - logger('fetch failure: ' . $furl); + if ($result['success']) { + $html_text = $result['body']; + } else { + logger('fetch failure: ' . $furl); + } - if($html_text) { - $dom = new DOMDocument(); - @$dom->loadHTML($html_text); - if ($dom) { - $xpath = new DOMXPath($dom); - $attr = "oembed"; - $xattr = oe_build_xpath("class","oembed"); + if ($html_text) { + $dom = new DOMDocument(); + @$dom->loadHTML($html_text); + if ($dom) { + $xpath = new DOMXPath($dom); + $attr = "oembed"; + $xattr = oe_build_xpath("class", "oembed"); - $entries = $xpath->query("//link[@type='application/json+oembed']"); - foreach($entries as $e){ - $href = $e->getAttributeNode("href")->nodeValue; - - $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); - if($x['success']) - $txt = $x['body']; - else - logger('fetch failed: ' . $href); - break; - } - // soundcloud is now using text/json+oembed instead of application/json+oembed, - // others may be also - $entries = $xpath->query("//link[@type='text/json+oembed']"); - foreach($entries as $e){ - $href = $e->getAttributeNode("href")->nodeValue; - $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); - if($x['success']) - $txt = $x['body']; - else - logger('json fetch failed: ' . $href); - break; - } - } - } - } - - if ($txt==false || $txt=="") { - $x = array('url' => $embedurl,'videowidth' => App::$videowidth); - call_hooks('oembed_probe',$x); - if(array_key_exists('embed',$x)) - $txt = $x['embed']; - } - - $txt=trim($txt); + $entries = $xpath->query("//link[@type='application/json+oembed']"); + foreach ($entries as $e) { + $href = $e->getAttributeNode("href")->nodeValue; - if ($txt[0]!="{") $txt='{"type":"error"}'; - - // save in cache + $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); + if ($x['success']) { + $txt = $x['body']; + } else { + logger('fetch failed: ' . $href); + } + break; + } + // soundcloud is now using text/json+oembed instead of application/json+oembed, + // others may be also + $entries = $xpath->query("//link[@type='text/json+oembed']"); + foreach ($entries as $e) { + $href = $e->getAttributeNode("href")->nodeValue; + $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); + if ($x['success']) { + $txt = $x['body']; + } else { + logger('json fetch failed: ' . $href); + } + break; + } + } + } + } - if(! get_config('system','oembed_cache_disable')) - Cache::set('[' . App::$videowidth . '] ' . $furl, $txt); + if ($txt == false || $txt == "") { + $x = array('url' => $embedurl,'videowidth' => App::$videowidth); + call_hooks('oembed_probe', $x); + if (array_key_exists('embed', $x)) { + $txt = $x['embed']; + } + } - } + $txt = trim($txt); + + if ($txt[0] != "{") { + $txt = '{"type":"error"}'; + } + + // save in cache + + if (! get_config('system', 'oembed_cache_disable')) { + Cache::set('[' . App::$videowidth . '] ' . $furl, $txt); + } + } - if(! $j) { - $j = json_decode($txt,true); - } + if (! $j) { + $j = json_decode($txt, true); + } - if(! $j) { - $j = []; - } + if (! $j) { + $j = []; + } - if($action === 'filter') { - if($j['html']) { - $orig = $j['html']; - $allow_position = (($is_matrix) ? true : false); + if ($action === 'filter') { + if ($j['html']) { + $orig = $j['html']; + $allow_position = (($is_matrix) ? true : false); - // some sites (e.g. Mastodon) wrap their entire embed in an iframe - // which we will purify away and which we provide anyway. - // So if we see this, grab the frame src url and use that - // as the embed content - which will still need to be purified. + // some sites (e.g. Mastodon) wrap their entire embed in an iframe + // which we will purify away and which we provide anyway. + // So if we see this, grab the frame src url and use that + // as the embed content - which will still need to be purified. - if(preg_match('#\"; - switch ($j['type']) { - case "video": { - if (isset($j['thumbnail_url'])) { - $tw = (isset($j['thumbnail_width'])) ? $j['thumbnail_width'] : 200; - $th = (isset($j['thumbnail_height'])) ? $j['thumbnail_height'] : 180; - $tr = $tw/$th; - - $th=120; $tw = $th*$tr; - $tpl=get_markup_template('oembed_video.tpl'); + $ret = ""; + switch ($j['type']) { + case "video": { + if (isset($j['thumbnail_url'])) { + $tw = (isset($j['thumbnail_width'])) ? $j['thumbnail_width'] : 200; + $th = (isset($j['thumbnail_height'])) ? $j['thumbnail_height'] : 180; + $tr = $tw / $th; - $ret.=replace_macros($tpl, array( + $th = 120; + $tw = $th * $tr; + $tpl = get_markup_template('oembed_video.tpl'); + + $ret .= replace_macros($tpl, array( '$baseurl' => z_root(), - '$embedurl'=>$embedurl, - '$escapedhtml'=>base64_encode($jhtml), - '$tw'=>$tw, - '$th'=>$th, - '$turl'=> $j['thumbnail_url'], - )); - - } else { - $ret=$jhtml; - } - $ret.="
                    "; - } + '$embedurl' => $embedurl, + '$escapedhtml' => base64_encode($jhtml), + '$tw' => $tw, + '$th' => $th, + '$turl' => $j['thumbnail_url'], + )); + } else { + $ret = $jhtml; + } + $ret .= "
                    "; + } break; - case "photo": { - $ret.= ""; - $ret.="
                    "; - } + case "photo": { + $ret .= ""; + $ret .= "
                    "; + } break; - case "link": { - if($j['thumbnail_url']) { - if(is_matrix_url($embedurl)) { - $embedurl = zid($embedurl); - $j['thumbnail_url'] = zid($j['thumbnail_url']); - } - $ret = 'thumbnail

                    '; - } + case "link": { + if ($j['thumbnail_url']) { + if (is_matrix_url($embedurl)) { + $embedurl = zid($embedurl); + $j['thumbnail_url'] = zid($j['thumbnail_url']); + } + $ret = 'thumbnail

                    '; + } - //$ret = "".$j['title'].""; - } + //$ret = "".$j['title'].""; + } break; - case 'pdf': { - $ret = $j['html']; - break; - } + case 'pdf': { + $ret = $j['html']; + break; + } - case "rich": - if($j['zrl']) { - $ret = ((preg_match('/^]+>(.*?)<\/div>$/is',$j['html'],$o)) ? $o[1] : $j['html']); - } - else { - $ret.= $jhtml; - } - break; - } + case "rich": + if ($j['zrl']) { + $ret = ((preg_match('/^]+>(.*?)<\/div>$/is', $j['html'], $o)) ? $o[1] : $j['html']); + } else { + $ret .= $jhtml; + } + break; + } - // add link to source if not present in "rich" type - if ( $j['type'] != 'rich' || !strpos($j['html'],$embedurl) ){ - $embedlink = (isset($j['title']))?$j['title'] : $embedurl; - $ret .= '
                    ' . "$embedlink"; - $ret .= "
                    "; - if (isset($j['author_name'])) $ret .= t(' by ') . $j['author_name']; - if (isset($j['provider_name'])) $ret .= t(' on ') . $j['provider_name']; - } else { - // add for html2bbcode conversion - $ret .= "
                    $embedurl"; - } - $ret.="
                    "; - return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret)); + // add link to source if not present in "rich" type + if ($j['type'] != 'rich' || !strpos($j['html'], $embedurl)) { + $embedlink = (isset($j['title'])) ? $j['title'] : $embedurl; + $ret .= '
                    ' . "$embedlink"; + $ret .= "
                    "; + if (isset($j['author_name'])) { + $ret .= t(' by ') . $j['author_name']; + } + if (isset($j['provider_name'])) { + $ret .= t(' on ') . $j['provider_name']; + } + } else { + // add for html2bbcode conversion + $ret .= "
                    $embedurl"; + } + $ret .= "
                    "; + return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret)); } -function oembed_iframe($src,$width,$height) { - $scroll = ' scrolling="no" '; - if(! $width || strstr($width,'%')) { - $width = '640'; - $scroll = ' scrolling="auto" '; - } - if(! $height || strstr($height,'%')) { - $height = '300'; - $scroll = ' scrolling="auto" '; - } +function oembed_iframe($src, $width, $height) +{ + $scroll = ' scrolling="no" '; + if (! $width || strstr($width, '%')) { + $width = '640'; + $scroll = ' scrolling="auto" '; + } + if (! $height || strstr($height, '%')) { + $height = '300'; + $scroll = ' scrolling="auto" '; + } - // try and leave some room for the description line. - $height = intval($height) + 80; - $width = intval($width) + 40; + // try and leave some room for the description line. + $height = intval($height) + 80; + $width = intval($width) + 40; - $s = z_root() . '/oembed/' . base64url_encode($src); + $s = z_root() . '/oembed/' . base64url_encode($src); - // Make sure any children are sandboxed within their own iframe. - - return ''; + // Make sure any children are sandboxed within their own iframe. + return ''; } -function oembed_bbcode2html($text){ - $stopoembed = get_config("system","no_oembed"); - if ($stopoembed == true){ - return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "". t('Embedding disabled') ." : $1" ,$text); - } - return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", 'oembed_replacecb' ,$text); +function oembed_bbcode2html($text) +{ + $stopoembed = get_config("system", "no_oembed"); + if ($stopoembed == true) { + return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "" . t('Embedding disabled') . " : $1", $text); + } + return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", 'oembed_replacecb', $text); } -function oe_build_xpath($attr, $value){ - // http://westhoffswelt.de/blog/0036_xpath_to_select_html_by_class.html - return "contains( normalize-space( @$attr ), ' $value ' ) or substring( normalize-space( @$attr ), 1, string-length( '$value' ) + 1 ) = '$value ' or substring( normalize-space( @$attr ), string-length( @$attr ) - string-length( '$value' ) ) = ' $value' or @$attr = '$value'"; +function oe_build_xpath($attr, $value) +{ + // http://westhoffswelt.de/blog/0036_xpath_to_select_html_by_class.html + return "contains( normalize-space( @$attr ), ' $value ' ) or substring( normalize-space( @$attr ), 1, string-length( '$value' ) + 1 ) = '$value ' or substring( normalize-space( @$attr ), string-length( @$attr ) - string-length( '$value' ) ) = ' $value' or @$attr = '$value'"; } -function oe_get_inner_html( $node ) { - $innerHTML= ''; +function oe_get_inner_html($node) +{ + $innerHTML = ''; $children = $node->childNodes; foreach ($children as $child) { - $innerHTML .= $child->ownerDocument->saveXML( $child ); + $innerHTML .= $child->ownerDocument->saveXML($child); } return $innerHTML; -} +} /** * Find .... * and replace it with [embed]url[/embed] */ -function oembed_html2bbcode($text) { - // start parser only if 'oembed' is in text - if (strpos($text, "oembed")) { - - // convert non ascii chars to html entities - $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text)); - - // If it doesn't parse at all, just return the text. - $dom = new DOMDocument(); - @$dom->loadHTML($html_text); - if ($dom) { - $xpath = new DOMXPath($dom); - $attr = "oembed"; - - $xattr = oe_build_xpath("class","oembed"); - $entries = $xpath->query("//span[$xattr]"); +function oembed_html2bbcode($text) +{ + // start parser only if 'oembed' is in text + if (strpos($text, "oembed")) { + // convert non ascii chars to html entities + $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text)); - $xattr = "@rel='oembed'";//oe_build_xpath("rel","oembed"); - foreach($entries as $e) { - $href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue; - if(!is_null($href)) $e->parentNode->replaceChild(new DOMText("[embed]".$href."[/embed]"), $e); - } - return oe_get_inner_html( $dom->getElementsByTagName("body")->item(0) ); - } - } - return $text; + // If it doesn't parse at all, just return the text. + $dom = new DOMDocument(); + @$dom->loadHTML($html_text); + if ($dom) { + $xpath = new DOMXPath($dom); + $attr = "oembed"; + $xattr = oe_build_xpath("class", "oembed"); + $entries = $xpath->query("//span[$xattr]"); + + $xattr = "@rel='oembed'";//oe_build_xpath("rel","oembed"); + foreach ($entries as $e) { + $href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue; + if (!is_null($href)) { + $e->parentNode->replaceChild(new DOMText("[embed]" . $href . "[/embed]"), $e); + } + } + return oe_get_inner_html($dom->getElementsByTagName("body")->item(0)); + } + } + return $text; } - - - diff --git a/include/perm_upgrade.php b/include/perm_upgrade.php index 9eb1efba2..e09be409d 100644 --- a/include/perm_upgrade.php +++ b/include/perm_upgrade.php @@ -1,239 +1,290 @@ $v) { - set_pconfig($channel['channel_id'],'autoperms',$k,$v); - } - } - } +function autoperms_upgrade($channel) +{ + $x = get_pconfig($channel['channel_id'], 'system', 'autoperms'); + if (intval($x)) { + $y = perms_int_to_array($x); + if ($y) { + foreach ($y as $k => $v) { + set_pconfig($channel['channel_id'], 'autoperms', $k, $v); + } + } + } } -function perm_abook_upgrade($abook) { +function perm_abook_upgrade($abook) +{ - $x = perms_int_to_array($abook['abook_their_perms']); - if($x) { - foreach($x as $k => $v) { - set_abconfig($abook['abook_channel'],$abook['abook_xchan'],'their_perms',$k, $v); - } - } + $x = perms_int_to_array($abook['abook_their_perms']); + if ($x) { + foreach ($x as $k => $v) { + set_abconfig($abook['abook_channel'], $abook['abook_xchan'], 'their_perms', $k, $v); + } + } - $x = perms_int_to_array($abook['abook_my_perms']); - if($x) { - foreach($x as $k => $v) { - set_abconfig($abook['abook_channel'],$abook['abook_xchan'],'my_perms',$k, $v); - } - } + $x = perms_int_to_array($abook['abook_my_perms']); + if ($x) { + foreach ($x as $k => $v) { + set_abconfig($abook['abook_channel'], $abook['abook_xchan'], 'my_perms', $k, $v); + } + } } -function translate_channel_perms_outbound(&$channel) { - $r = q("select * from pconfig where uid = %d and cat = 'perm_limits' ", - intval($channel['channel_id']) - ); +function translate_channel_perms_outbound(&$channel) +{ + $r = q( + "select * from pconfig where uid = %d and cat = 'perm_limits' ", + intval($channel['channel_id']) + ); - if($r) { - foreach($r as $rr) { - if($rr['k'] === 'view_stream') - $channel['channel_r_stream'] = $rr['v']; - if($rr['k'] === 'view_profile') - $channel['channel_r_profile'] = $rr['v']; - if($rr['k'] === 'view_contacts') - $channel['channel_r_abook'] = $rr['v']; - if($rr['k'] === 'view_storage') - $channel['channel_r_storage'] = $rr['v']; - if($rr['k'] === 'view_pages') - $channel['channel_r_pages'] = $rr['v']; - if($rr['k'] === 'send_stream') - $channel['channel_w_stream'] = $rr['v']; - if($rr['k'] === 'post_wall') - $channel['channel_w_wall'] = $rr['v']; - if($rr['k'] === 'post_comments') - $channel['channel_w_comment'] = $rr['v']; - if($rr['k'] === 'post_mail') - $channel['channel_w_mail'] = $rr['v']; - if($rr['k'] === 'post_like') - $channel['channel_w_like'] = $rr['v']; - if($rr['k'] === 'tag_deliver') - $channel['channel_w_tagwall'] = $rr['v']; - if($rr['k'] === 'chat') - $channel['channel_w_chat'] = $rr['v']; - if($rr['k'] === 'write_storage') - $channel['channel_w_storage'] = $rr['v']; - if($rr['k'] === 'write_pages') - $channel['channel_w_pages'] = $rr['v']; - if($rr['k'] === 'republish') - $channel['channel_a_republish'] = $rr['v']; - if($rr['k'] === 'delegate') - $channel['channel_a_delegate'] = $rr['v']; - - } - $channel['perm_limits'] = $r; - } + if ($r) { + foreach ($r as $rr) { + if ($rr['k'] === 'view_stream') { + $channel['channel_r_stream'] = $rr['v']; + } + if ($rr['k'] === 'view_profile') { + $channel['channel_r_profile'] = $rr['v']; + } + if ($rr['k'] === 'view_contacts') { + $channel['channel_r_abook'] = $rr['v']; + } + if ($rr['k'] === 'view_storage') { + $channel['channel_r_storage'] = $rr['v']; + } + if ($rr['k'] === 'view_pages') { + $channel['channel_r_pages'] = $rr['v']; + } + if ($rr['k'] === 'send_stream') { + $channel['channel_w_stream'] = $rr['v']; + } + if ($rr['k'] === 'post_wall') { + $channel['channel_w_wall'] = $rr['v']; + } + if ($rr['k'] === 'post_comments') { + $channel['channel_w_comment'] = $rr['v']; + } + if ($rr['k'] === 'post_mail') { + $channel['channel_w_mail'] = $rr['v']; + } + if ($rr['k'] === 'post_like') { + $channel['channel_w_like'] = $rr['v']; + } + if ($rr['k'] === 'tag_deliver') { + $channel['channel_w_tagwall'] = $rr['v']; + } + if ($rr['k'] === 'chat') { + $channel['channel_w_chat'] = $rr['v']; + } + if ($rr['k'] === 'write_storage') { + $channel['channel_w_storage'] = $rr['v']; + } + if ($rr['k'] === 'write_pages') { + $channel['channel_w_pages'] = $rr['v']; + } + if ($rr['k'] === 'republish') { + $channel['channel_a_republish'] = $rr['v']; + } + if ($rr['k'] === 'delegate') { + $channel['channel_a_delegate'] = $rr['v']; + } + } + $channel['perm_limits'] = $r; + } } -function translate_channel_perms_inbound($channel) { - - if($channel['perm_limits']) { - foreach($channel['perm_limits'] as $p) { - set_pconfig($channel['channel_id'],'perm_limits',$p['k'],$p['v']); - } - } - else { - perm_limits_upgrade($channel); - } +function translate_channel_perms_inbound($channel) +{ + if ($channel['perm_limits']) { + foreach ($channel['perm_limits'] as $p) { + set_pconfig($channel['channel_id'], 'perm_limits', $p['k'], $p['v']); + } + } else { + perm_limits_upgrade($channel); + } } -function translate_abook_perms_outbound(&$abook) { - $my_perms = 0; - $their_perms = 0; +function translate_abook_perms_outbound(&$abook) +{ + $my_perms = 0; + $their_perms = 0; - if(! $abook) - return; + if (! $abook) { + return; + } - if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && $abook['abconfig']) { - foreach($abook['abconfig'] as $p) { - if($p['cat'] === 'their_perms') { - if($p['k'] === 'view_stream' && intval($p['v'])) - $their_perms += PERMS_R_STREAM; - if($p['k'] === 'view_profile' && intval($p['v'])) - $their_perms += PERMS_R_PROFILE; - if($p['k'] === 'view_contacts' && intval($p['v'])) - $their_perms += PERMS_R_ABOOK; - if($p['k'] === 'view_storage' && intval($p['v'])) - $their_perms += PERMS_R_STORAGE; - if($p['k'] === 'view_pages' && intval($p['v'])) - $their_perms += PERMS_R_PAGES; - if($p['k'] === 'send_stream' && intval($p['v'])) - $their_perms += PERMS_W_STREAM; - if($p['k'] === 'post_wall' && intval($p['v'])) - $their_perms += PERMS_W_WALL; - if($p['k'] === 'post_comments' && intval($p['v'])) - $their_perms += PERMS_W_COMMENT; - if($p['k'] === 'post_mail' && intval($p['v'])) - $their_perms += PERMS_W_MAIL; - if($p['k'] === 'post_like' && intval($p['v'])) - $their_perms += PERMS_W_LIKE; - if($p['k'] === 'tag_deliver' && intval($p['v'])) - $their_perms += PERMS_W_TAGWALL; - if($p['k'] === 'chat' && intval($p['v'])) - $their_perms += PERMS_W_CHAT; - if($p['k'] === 'write_storage' && intval($p['v'])) - $their_perms += PERMS_W_STORAGE; - if($p['k'] === 'write_pages' && intval($p['v'])) - $their_perms += PERMS_W_PAGES; - if($p['k'] === 'republish' && intval($p['v'])) - $their_perms += PERMS_A_REPUBLISH; - if($p['k'] === 'delegate' && intval($p['v'])) - $their_perms += PERMS_A_DELEGATE; - } - if($p['cat'] === 'my_perms') { - if($p['k'] === 'view_stream' && intval($p['v'])) - $my_perms += PERMS_R_STREAM; - if($p['k'] === 'view_profile' && intval($p['v'])) - $my_perms += PERMS_R_PROFILE; - if($p['k'] === 'view_contacts' && intval($p['v'])) - $my_perms += PERMS_R_ABOOK; - if($p['k'] === 'view_storage' && intval($p['v'])) - $my_perms += PERMS_R_STORAGE; - if($p['k'] === 'view_pages' && intval($p['v'])) - $my_perms += PERMS_R_PAGES; - if($p['k'] === 'send_stream' && intval($p['v'])) - $my_perms += PERMS_W_STREAM; - if($p['k'] === 'post_wall' && intval($p['v'])) - $my_perms += PERMS_W_WALL; - if($p['k'] === 'post_comments' && intval($p['v'])) - $my_perms += PERMS_W_COMMENT; - if($p['k'] === 'post_mail' && intval($p['v'])) - $my_perms += PERMS_W_MAIL; - if($p['k'] === 'post_like' && intval($p['v'])) - $my_perms += PERMS_W_LIKE; - if($p['k'] === 'tag_deliver' && intval($p['v'])) - $my_perms += PERMS_W_TAGWALL; - if($p['k'] === 'chat' && intval($p['v'])) - $my_perms += PERMS_W_CHAT; - if($p['k'] === 'write_storage' && intval($p['v'])) - $my_perms += PERMS_W_STORAGE; - if($p['k'] === 'write_pages' && intval($p['v'])) - $my_perms += PERMS_W_PAGES; - if($p['k'] === 'republish' && intval($p['v'])) - $my_perms += PERMS_A_REPUBLISH; - if($p['k'] === 'delegate' && intval($p['v'])) - $my_perms += PERMS_A_DELEGATE; - } - } + if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && $abook['abconfig']) { + foreach ($abook['abconfig'] as $p) { + if ($p['cat'] === 'their_perms') { + if ($p['k'] === 'view_stream' && intval($p['v'])) { + $their_perms += PERMS_R_STREAM; + } + if ($p['k'] === 'view_profile' && intval($p['v'])) { + $their_perms += PERMS_R_PROFILE; + } + if ($p['k'] === 'view_contacts' && intval($p['v'])) { + $their_perms += PERMS_R_ABOOK; + } + if ($p['k'] === 'view_storage' && intval($p['v'])) { + $their_perms += PERMS_R_STORAGE; + } + if ($p['k'] === 'view_pages' && intval($p['v'])) { + $their_perms += PERMS_R_PAGES; + } + if ($p['k'] === 'send_stream' && intval($p['v'])) { + $their_perms += PERMS_W_STREAM; + } + if ($p['k'] === 'post_wall' && intval($p['v'])) { + $their_perms += PERMS_W_WALL; + } + if ($p['k'] === 'post_comments' && intval($p['v'])) { + $their_perms += PERMS_W_COMMENT; + } + if ($p['k'] === 'post_mail' && intval($p['v'])) { + $their_perms += PERMS_W_MAIL; + } + if ($p['k'] === 'post_like' && intval($p['v'])) { + $their_perms += PERMS_W_LIKE; + } + if ($p['k'] === 'tag_deliver' && intval($p['v'])) { + $their_perms += PERMS_W_TAGWALL; + } + if ($p['k'] === 'chat' && intval($p['v'])) { + $their_perms += PERMS_W_CHAT; + } + if ($p['k'] === 'write_storage' && intval($p['v'])) { + $their_perms += PERMS_W_STORAGE; + } + if ($p['k'] === 'write_pages' && intval($p['v'])) { + $their_perms += PERMS_W_PAGES; + } + if ($p['k'] === 'republish' && intval($p['v'])) { + $their_perms += PERMS_A_REPUBLISH; + } + if ($p['k'] === 'delegate' && intval($p['v'])) { + $their_perms += PERMS_A_DELEGATE; + } + } + if ($p['cat'] === 'my_perms') { + if ($p['k'] === 'view_stream' && intval($p['v'])) { + $my_perms += PERMS_R_STREAM; + } + if ($p['k'] === 'view_profile' && intval($p['v'])) { + $my_perms += PERMS_R_PROFILE; + } + if ($p['k'] === 'view_contacts' && intval($p['v'])) { + $my_perms += PERMS_R_ABOOK; + } + if ($p['k'] === 'view_storage' && intval($p['v'])) { + $my_perms += PERMS_R_STORAGE; + } + if ($p['k'] === 'view_pages' && intval($p['v'])) { + $my_perms += PERMS_R_PAGES; + } + if ($p['k'] === 'send_stream' && intval($p['v'])) { + $my_perms += PERMS_W_STREAM; + } + if ($p['k'] === 'post_wall' && intval($p['v'])) { + $my_perms += PERMS_W_WALL; + } + if ($p['k'] === 'post_comments' && intval($p['v'])) { + $my_perms += PERMS_W_COMMENT; + } + if ($p['k'] === 'post_mail' && intval($p['v'])) { + $my_perms += PERMS_W_MAIL; + } + if ($p['k'] === 'post_like' && intval($p['v'])) { + $my_perms += PERMS_W_LIKE; + } + if ($p['k'] === 'tag_deliver' && intval($p['v'])) { + $my_perms += PERMS_W_TAGWALL; + } + if ($p['k'] === 'chat' && intval($p['v'])) { + $my_perms += PERMS_W_CHAT; + } + if ($p['k'] === 'write_storage' && intval($p['v'])) { + $my_perms += PERMS_W_STORAGE; + } + if ($p['k'] === 'write_pages' && intval($p['v'])) { + $my_perms += PERMS_W_PAGES; + } + if ($p['k'] === 'republish' && intval($p['v'])) { + $my_perms += PERMS_A_REPUBLISH; + } + if ($p['k'] === 'delegate' && intval($p['v'])) { + $my_perms += PERMS_A_DELEGATE; + } + } + } - $abook['abook_their_perms'] = $their_perms; - $abook['abook_my_perms'] = $my_perms; - } + $abook['abook_their_perms'] = $their_perms; + $abook['abook_my_perms'] = $my_perms; + } } -function translate_abook_perms_inbound($channel,$abook) { +function translate_abook_perms_inbound($channel, $abook) +{ - $new_perms = false; - $abook['abook_channel'] = $channel['channel_id']; + $new_perms = false; + $abook['abook_channel'] = $channel['channel_id']; - if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && $abook['abconfig']) { - foreach($abook['abconfig'] as $p) { - if($p['cat'] == 'their_perms' || $p['cat'] == 'my_perms') { - $new_perms = true; - break; - } - } - } - - if($new_perms == false) { - perm_abook_upgrade($abook); - } + if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && $abook['abconfig']) { + foreach ($abook['abconfig'] as $p) { + if ($p['cat'] == 'their_perms' || $p['cat'] == 'my_perms') { + $new_perms = true; + break; + } + } + } + if ($new_perms == false) { + perm_abook_upgrade($abook); + } } - - - diff --git a/include/permissions.php b/include/permissions.php index e3a44ea18..e0727692e 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -9,7 +9,7 @@ require_once('include/security.php'); * @file include/permissions.php * * This file conntains functions to check and work with permissions. - * + * */ @@ -26,213 +26,217 @@ require_once('include/security.php'); * * @returns array of all permissions, key is permission name, value is true or false */ -function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ignored = true) { +function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ignored = true) +{ - $api = App::get_oauth_key(); - if ($api) { - return get_all_api_perms($uid,$api); - } - - $global_perms = Permissions::Perms(); + $api = App::get_oauth_key(); + if ($api) { + return get_all_api_perms($uid, $api); + } - // Save lots of individual lookups + $global_perms = Permissions::Perms(); - $r = null; - $c = null; - $x = null; + // Save lots of individual lookups - $channel_checked = false; - $onsite_checked = false; - $abook_checked = false; + $r = null; + $c = null; + $x = null; - $ret = []; + $channel_checked = false; + $onsite_checked = false; + $abook_checked = false; - $abperms = (($uid && $observer_xchan) ? get_abconfig($uid,$observer_xchan,'system','my_perms','') : ''); + $ret = []; - foreach ($global_perms as $perm_name => $permission) { + $abperms = (($uid && $observer_xchan) ? get_abconfig($uid, $observer_xchan, 'system', 'my_perms', '') : ''); - // First find out what the channel owner declared permissions to be. + foreach ($global_perms as $perm_name => $permission) { + // First find out what the channel owner declared permissions to be. - $channel_perm = intval(PermissionLimits::Get($uid,$perm_name)); + $channel_perm = intval(PermissionLimits::Get($uid, $perm_name)); - if (! $channel_checked) { - $r = q("select * from channel where channel_id = %d limit 1", - intval($uid) - ); - $channel_checked = true; - } + if (! $channel_checked) { + $r = q( + "select * from channel where channel_id = %d limit 1", + intval($uid) + ); + $channel_checked = true; + } - // The uid provided doesn't exist. This would be a big fail. + // The uid provided doesn't exist. This would be a big fail. - if(! $r) { - $ret[$perm_name] = false; - continue; - } + if (! $r) { + $ret[$perm_name] = false; + continue; + } - // Next we're going to check for blocked or ignored contacts. - // These take priority over all other settings. + // Next we're going to check for blocked or ignored contacts. + // These take priority over all other settings. - if($observer_xchan) { - if($channel_perm & PERMS_AUTHED) { - $ret[$perm_name] = true; - continue; - } + if ($observer_xchan) { + if ($channel_perm & PERMS_AUTHED) { + $ret[$perm_name] = true; + continue; + } - if(! $abook_checked) { - $x = q("select abook_blocked, abook_ignored, abook_pending, xchan_network from abook + if (! $abook_checked) { + $x = q( + "select abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_xchan = '%s' and abook_self = 0 limit 1", - intval($uid), - dbesc($observer_xchan) - ); + intval($uid), + dbesc($observer_xchan) + ); - $abook_checked = true; - } + $abook_checked = true; + } - // If they're blocked - they can't read or write + // If they're blocked - they can't read or write - if(($x) && intval($x[0]['abook_blocked'])) { - $ret[$perm_name] = false; - continue; - } + if (($x) && intval($x[0]['abook_blocked'])) { + $ret[$perm_name] = false; + continue; + } - // Check if this is a write permission and they are being ignored - // This flag is only visible internally. + // Check if this is a write permission and they are being ignored + // This flag is only visible internally. - $blocked_anon_perms = Permissions::BlockedAnonPerms(); + $blocked_anon_perms = Permissions::BlockedAnonPerms(); - if(($x) && ($default_ignored) && in_array($perm_name,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) { - $ret[$perm_name] = false; - continue; - } - } + if (($x) && ($default_ignored) && in_array($perm_name, $blocked_anon_perms) && intval($x[0]['abook_ignored'])) { + $ret[$perm_name] = false; + continue; + } + } - // system is blocked to anybody who is not authenticated + // system is blocked to anybody who is not authenticated - if(($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) { - $ret[$perm_name] = false; - continue; - } + if (($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) { + $ret[$perm_name] = false; + continue; + } - // Check if this $uid is actually the $observer_xchan - if it's your content - // you always have permission to do anything - // if you've moved elsewhere, you will only have read only access + // Check if this $uid is actually the $observer_xchan - if it's your content + // you always have permission to do anything + // if you've moved elsewhere, you will only have read only access - if(($observer_xchan) && ($r[0]['channel_hash'] === $observer_xchan)) { + if (($observer_xchan) && ($r[0]['channel_hash'] === $observer_xchan)) { + if ($r[0]['channel_moved'] && (in_array($perm_name, $blocked_anon_perms))) { + $ret[$perm_name] = false; + } else { + $ret[$perm_name] = true; + } + // moderated is a negative permission, don't moderate your own posts + if ($perm_name === 'moderated') { + $ret[$perm_name] = false; + } - if($r[0]['channel_moved'] && (in_array($perm_name,$blocked_anon_perms))) - $ret[$perm_name] = false; - else - $ret[$perm_name] = true; - // moderated is a negative permission, don't moderate your own posts - if($perm_name === 'moderated') - $ret[$perm_name] = false; + continue; + } - continue; - } + // Anybody at all (that wasn't blocked or ignored). They have permission. - // Anybody at all (that wasn't blocked or ignored). They have permission. + if ($channel_perm & PERMS_PUBLIC) { + $ret[$perm_name] = true; + continue; + } - if($channel_perm & PERMS_PUBLIC) { - $ret[$perm_name] = true; - continue; - } + // From here on out, we need to know who they are. If we can't figure it + // out, permission is denied. - // From here on out, we need to know who they are. If we can't figure it - // out, permission is denied. + if (! $observer_xchan) { + $ret[$perm_name] = false; + continue; + } - if(! $observer_xchan) { - $ret[$perm_name] = false; - continue; - } + // If we're still here, we have an observer, check the network. - // If we're still here, we have an observer, check the network. + if ($channel_perm & PERMS_NETWORK) { + if ($x && $x[0]['xchan_network'] === 'zot6') { + $ret[$perm_name] = true; + continue; + } + } - if($channel_perm & PERMS_NETWORK) { - if($x && $x[0]['xchan_network'] === 'zot6') { - $ret[$perm_name] = true; - continue; - } - } + // If PERMS_SITE is specified, find out if they've got an account on this hub - // If PERMS_SITE is specified, find out if they've got an account on this hub + if ($channel_perm & PERMS_SITE) { + if (! $onsite_checked) { + $c = q( + "select channel_hash from channel where channel_hash = '%s' limit 1", + dbesc($observer_xchan) + ); - if($channel_perm & PERMS_SITE) { - if(! $onsite_checked) { - $c = q("select channel_hash from channel where channel_hash = '%s' limit 1", - dbesc($observer_xchan) - ); + $onsite_checked = true; + } - $onsite_checked = true; - } + if ($c) { + $ret[$perm_name] = true; + } else { + $ret[$perm_name] = false; + } - if($c) - $ret[$perm_name] = true; - else - $ret[$perm_name] = false; + continue; + } - continue; - } + // From here on we require that the observer be a connection and + // handle whether we're allowing any, approved or specific ones - // From here on we require that the observer be a connection and - // handle whether we're allowing any, approved or specific ones + if (! $x) { + $ret[$perm_name] = false; + continue; + } - if(! $x) { - $ret[$perm_name] = false; - continue; - } + // They are in your address book, but haven't been approved - // They are in your address book, but haven't been approved + if ($channel_perm & PERMS_PENDING) { + $ret[$perm_name] = true; + continue; + } - if($channel_perm & PERMS_PENDING) { - $ret[$perm_name] = true; - continue; - } + if (intval($x[0]['abook_pending'])) { + $ret[$perm_name] = false; + continue; + } - if(intval($x[0]['abook_pending'])) { - $ret[$perm_name] = false; - continue; - } + // They're a contact, so they have permission - // They're a contact, so they have permission + if ($channel_perm & PERMS_CONTACTS) { + $ret[$perm_name] = true; + continue; + } - if($channel_perm & PERMS_CONTACTS) { - $ret[$perm_name] = true; - continue; - } + // Permission granted to certain channels. Let's see if the observer is one of them - // Permission granted to certain channels. Let's see if the observer is one of them + if ($channel_perm & PERMS_SPECIFIC) { + if ($abperms) { + $arr = explode(',', $abperms); + if ($arr) { + if (in_array($perm_name, $arr)) { + $ret[$perm_name] = true; + } else { + $ret[$perm_name] = false; + } + } + continue; + } + } - if($channel_perm & PERMS_SPECIFIC) { - if($abperms) { - $arr = explode(',',$abperms); - if($arr) { - if (in_array($perm_name,$arr)) { - $ret[$perm_name] = true; - } - else { - $ret[$perm_name] = false; - } - } - continue; - } - } + // No permissions allowed. - // No permissions allowed. + $ret[$perm_name] = false; + continue; + } - $ret[$perm_name] = false; - continue; - } + $arr = array( + 'channel_id' => $uid, + 'observer_hash' => $observer_xchan, + 'permissions' => $ret); - $arr = array( - 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, - 'permissions' => $ret); + call_hooks('get_all_perms', $arr); - call_hooks('get_all_perms',$arr); - - return $arr['permissions']; + return $arr['permissions']; } /** @@ -248,236 +252,246 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ * if false bypass check for "Block Public" at the site level * @return bool true if permission is allowed for observer on channel */ -function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = true) { +function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = true) +{ - $api = App::get_oauth_key(); - if ($api) { - return api_perm_is_allowed($uid,$api,$permission); - } + $api = App::get_oauth_key(); + if ($api) { + return api_perm_is_allowed($uid, $api, $permission); + } - $arr = [ - 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, - 'permission' => $permission, - 'result' => 'unset' - ]; + $arr = [ + 'channel_id' => $uid, + 'observer_hash' => $observer_xchan, + 'permission' => $permission, + 'result' => 'unset' + ]; - call_hooks('perm_is_allowed', $arr); - if ($arr['result'] !== 'unset') { - return $arr['result']; - } + call_hooks('perm_is_allowed', $arr); + if ($arr['result'] !== 'unset') { + return $arr['result']; + } - $global_perms = Permissions::Perms(); + $global_perms = Permissions::Perms(); - // First find out what the channel owner declared permissions to be. + // First find out what the channel owner declared permissions to be. - $channel_perm = PermissionLimits::Get($uid,$permission); - if ($channel_perm === false) { - return false; - } + $channel_perm = PermissionLimits::Get($uid, $permission); + if ($channel_perm === false) { + return false; + } - $r = q("select channel_pageflags, channel_moved, channel_hash from channel where channel_id = %d limit 1", - intval($uid) - ); - if (! $r) { - return false; - } + $r = q( + "select channel_pageflags, channel_moved, channel_hash from channel where channel_id = %d limit 1", + intval($uid) + ); + if (! $r) { + return false; + } - $blocked_anon_perms = Permissions::BlockedAnonPerms(); + $blocked_anon_perms = Permissions::BlockedAnonPerms(); - if ($observer_xchan) { - if ($channel_perm & PERMS_AUTHED) { - return true; - } + if ($observer_xchan) { + if ($channel_perm & PERMS_AUTHED) { + return true; + } - $x = q("select abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash + $x = q( + "select abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_xchan = '%s' and abook_self = 0 limit 1", - intval($uid), - dbesc($observer_xchan) - ); + intval($uid), + dbesc($observer_xchan) + ); - // If they're blocked - they can't read or write - - if (($x) && intval($x[0]['abook_blocked'])) { - return false; - } + // If they're blocked - they can't read or write - if (($x) && in_array($permission,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) { - return false; - } + if (($x) && intval($x[0]['abook_blocked'])) { + return false; + } - $abperms = get_abconfig($uid,$observer_xchan,'system','my_perms',''); - } - + if (($x) && in_array($permission, $blocked_anon_perms) && intval($x[0]['abook_ignored'])) { + return false; + } - // system is blocked to anybody who is not authenticated + $abperms = get_abconfig($uid, $observer_xchan, 'system', 'my_perms', ''); + } - if (($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) { - return false; - } - // Check if this $uid is actually the $observer_xchan - // you will have full access unless the channel was moved - - // in which case you will have read_only access + // system is blocked to anybody who is not authenticated - if ($r[0]['channel_hash'] === $observer_xchan) { - // moderated is a negative permission - if ($permission === 'moderated') { - return false; - } - if ($r[0]['channel_moved'] && (in_array($permission,$blocked_anon_perms))) { - return false; - } - else { - return true; - } - } + if (($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) { + return false; + } - if ($channel_perm & PERMS_PUBLIC) { - return true; - } + // Check if this $uid is actually the $observer_xchan + // you will have full access unless the channel was moved - + // in which case you will have read_only access - // If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set + if ($r[0]['channel_hash'] === $observer_xchan) { + // moderated is a negative permission + if ($permission === 'moderated') { + return false; + } + if ($r[0]['channel_moved'] && (in_array($permission, $blocked_anon_perms))) { + return false; + } else { + return true; + } + } - if (! $observer_xchan) { - return false; - } + if ($channel_perm & PERMS_PUBLIC) { + return true; + } - // If we're still here, we have an observer, check the network. + // If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set - if ($channel_perm & PERMS_NETWORK) { - if ($x && $x[0]['xchan_network'] === 'zot6') { - return true; - } - } + if (! $observer_xchan) { + return false; + } - // If PERMS_SITE is specified, find out if they've got an account on this hub + // If we're still here, we have an observer, check the network. - if ($channel_perm & PERMS_SITE) { - $c = q("select channel_hash from channel where channel_hash = '%s' limit 1", - dbesc($observer_xchan) - ); - if ($c) { - return true; - } - return false; - } + if ($channel_perm & PERMS_NETWORK) { + if ($x && $x[0]['xchan_network'] === 'zot6') { + return true; + } + } - // From here on we require that the observer be a connection and - // handle whether we're allowing any, approved or specific ones + // If PERMS_SITE is specified, find out if they've got an account on this hub - if (! $x) { - return false; - } + if ($channel_perm & PERMS_SITE) { + $c = q( + "select channel_hash from channel where channel_hash = '%s' limit 1", + dbesc($observer_xchan) + ); + if ($c) { + return true; + } + return false; + } - // They are in your address book, but haven't been approved + // From here on we require that the observer be a connection and + // handle whether we're allowing any, approved or specific ones - if ($channel_perm & PERMS_PENDING) { - return true; - } + if (! $x) { + return false; + } - if (intval($x[0]['abook_pending'])) { - return false; - } + // They are in your address book, but haven't been approved - // They're a contact, so they have permission + if ($channel_perm & PERMS_PENDING) { + return true; + } - if ($channel_perm & PERMS_CONTACTS) { - return true; - } + if (intval($x[0]['abook_pending'])) { + return false; + } - // Permission granted to certain channels. Let's see if the observer is one of them + // They're a contact, so they have permission - if (($r) && ($channel_perm & PERMS_SPECIFIC)) { - if ($abperms) { - $arr = explode(',',$abperms); - if ($arr) { - if (in_array($permission,$arr)) { - return true; - } - } - } - return false; - } + if ($channel_perm & PERMS_CONTACTS) { + return true; + } - // No permissions allowed. + // Permission granted to certain channels. Let's see if the observer is one of them - return false; + if (($r) && ($channel_perm & PERMS_SPECIFIC)) { + if ($abperms) { + $arr = explode(',', $abperms); + if ($arr) { + if (in_array($permission, $arr)) { + return true; + } + } + } + return false; + } + + // No permissions allowed. + + return false; } -function get_all_api_perms($uid,$api) { +function get_all_api_perms($uid, $api) +{ - $global_perms = Permissions::Perms(); + $global_perms = Permissions::Perms(); - $ret = []; + $ret = []; - $r = q("select * from xperm where xp_client = '%s' and xp_channel = %d", - dbesc($api), - intval($uid) - ); + $r = q( + "select * from xperm where xp_client = '%s' and xp_channel = %d", + dbesc($api), + intval($uid) + ); - if(! $r) - return false; + if (! $r) { + return false; + } - $allow_all = false; - $allowed = []; - foreach($r as $rr) { - if($rr['xp_perm'] === 'all') - $allow_all = true; - if(! in_array($rr['xp_perm'],$allowed)) - $allowed[] = $rr['xp_perm']; - } + $allow_all = false; + $allowed = []; + foreach ($r as $rr) { + if ($rr['xp_perm'] === 'all') { + $allow_all = true; + } + if (! in_array($rr['xp_perm'], $allowed)) { + $allowed[] = $rr['xp_perm']; + } + } - foreach($global_perms as $perm_name => $permission) { - if($allow_all || in_array($perm_name,$allowed)) - $ret[$perm_name] = true; - else - $ret[$perm_name] = false; + foreach ($global_perms as $perm_name => $permission) { + if ($allow_all || in_array($perm_name, $allowed)) { + $ret[$perm_name] = true; + } else { + $ret[$perm_name] = false; + } + } - } + $arr = array( + 'channel_id' => $uid, + 'observer_hash' => $observer_xchan, + 'permissions' => $ret); - $arr = array( - 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, - 'permissions' => $ret); - - call_hooks('get_all_api_perms',$arr); - - return $arr['permissions']; + call_hooks('get_all_api_perms', $arr); + return $arr['permissions']; } -function api_perm_is_allowed($uid,$api,$permission) { +function api_perm_is_allowed($uid, $api, $permission) +{ - $arr = array( - 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, - 'permission' => $permission, - 'result' => false - ); + $arr = array( + 'channel_id' => $uid, + 'observer_hash' => $observer_xchan, + 'permission' => $permission, + 'result' => false + ); - call_hooks('api_perm_is_allowed', $arr); - if($arr['result']) - return true; + call_hooks('api_perm_is_allowed', $arr); + if ($arr['result']) { + return true; + } - $r = q("select * from xperm where xp_client = '%s' and xp_channel = %d and ( xp_perm = 'all' OR xp_perm = '%s' )", - dbesc($api), - intval($uid), - dbesc($permission) - ); + $r = q( + "select * from xperm where xp_client = '%s' and xp_channel = %d and ( xp_perm = 'all' OR xp_perm = '%s' )", + dbesc($api), + intval($uid), + dbesc($permission) + ); - if(! $r) - return false; + if (! $r) { + return false; + } - foreach($r as $rr) { - if($rr['xp_perm'] === 'all' || $rr['xp_perm'] === $permission) - return true; - - } - - return false; + foreach ($r as $rr) { + if ($rr['xp_perm'] === 'all' || $rr['xp_perm'] === $permission) { + return true; + } + } + return false; } @@ -485,14 +499,18 @@ function api_perm_is_allowed($uid,$api,$permission) { // Check a simple array of observers against a permissions // return a simple array of those with permission -function check_list_permissions($uid, $arr, $perm) { - $result = []; - if($arr) - foreach($arr as $x) - if(perm_is_allowed($uid, $x, $perm)) - $result[] = $x; +function check_list_permissions($uid, $arr, $perm) +{ + $result = []; + if ($arr) { + foreach ($arr as $x) { + if (perm_is_allowed($uid, $x, $perm)) { + $result[] = $x; + } + } + } - return($result); + return($result); } /** @@ -500,59 +518,62 @@ function check_list_permissions($uid, $arr, $perm) { * * @return array */ -function site_default_perms() { +function site_default_perms() +{ - $ret = []; + $ret = []; - $typical = array( - 'view_stream' => PERMS_PUBLIC, - 'view_profile' => PERMS_PUBLIC, - 'view_contacts' => PERMS_PUBLIC, - 'view_storage' => PERMS_PUBLIC, - 'view_pages' => PERMS_PUBLIC, - 'view_wiki' => PERMS_PUBLIC, - 'send_stream' => PERMS_SPECIFIC, - 'post_wall' => PERMS_SPECIFIC, - 'post_comments' => PERMS_SPECIFIC, - 'post_mail' => PERMS_SPECIFIC, - 'tag_deliver' => PERMS_SPECIFIC, - 'chat' => PERMS_SPECIFIC, - 'write_storage' => PERMS_SPECIFIC, - 'write_pages' => PERMS_SPECIFIC, - 'write_wiki' => PERMS_SPECIFIC, - 'delegate' => PERMS_SPECIFIC, - 'post_like' => PERMS_NETWORK - ); + $typical = array( + 'view_stream' => PERMS_PUBLIC, + 'view_profile' => PERMS_PUBLIC, + 'view_contacts' => PERMS_PUBLIC, + 'view_storage' => PERMS_PUBLIC, + 'view_pages' => PERMS_PUBLIC, + 'view_wiki' => PERMS_PUBLIC, + 'send_stream' => PERMS_SPECIFIC, + 'post_wall' => PERMS_SPECIFIC, + 'post_comments' => PERMS_SPECIFIC, + 'post_mail' => PERMS_SPECIFIC, + 'tag_deliver' => PERMS_SPECIFIC, + 'chat' => PERMS_SPECIFIC, + 'write_storage' => PERMS_SPECIFIC, + 'write_pages' => PERMS_SPECIFIC, + 'write_wiki' => PERMS_SPECIFIC, + 'delegate' => PERMS_SPECIFIC, + 'post_like' => PERMS_NETWORK + ); - $global_perms = Permissions::Perms(); + $global_perms = Permissions::Perms(); - foreach($global_perms as $perm => $v) { - $x = get_config('default_perms', $perm, $typical[$perm]); - $ret[$perm] = $x; - } + foreach ($global_perms as $perm => $v) { + $x = get_config('default_perms', $perm, $typical[$perm]); + $ret[$perm] = $x; + } - return $ret; + return $ret; } -function their_perms_contains($channel_id,$xchan_hash,$perm) { - $x = get_abconfig($channel_id,$xchan_hash,'system','their_perms'); - if($x) { - $y = explode(',',$x); - if(in_array($perm,$y)) { - return true; - } - } - return false; +function their_perms_contains($channel_id, $xchan_hash, $perm) +{ + $x = get_abconfig($channel_id, $xchan_hash, 'system', 'their_perms'); + if ($x) { + $y = explode(',', $x); + if (in_array($perm, $y)) { + return true; + } + } + return false; } -function my_perms_contains($channel_id,$xchan_hash,$perm) { - $x = get_abconfig($channel_id,$xchan_hash,'system','my_perms'); - if($x) { - $y = explode(',',$x); - if(in_array($perm,$y)) { - return true; - } - } - return false; -} \ No newline at end of file +function my_perms_contains($channel_id, $xchan_hash, $perm) +{ + $x = get_abconfig($channel_id, $xchan_hash, 'system', 'my_perms'); + if ($x) { + $y = explode(',', $x); + if (in_array($perm, $y)) { + return true; + } + } + return false; +} diff --git a/include/photo_factory.php b/include/photo_factory.php index 3c51eab54..48509b4f6 100644 --- a/include/photo_factory.php +++ b/include/photo_factory.php @@ -18,43 +18,44 @@ use Zotlabs\Lib\Hashpath; * @return null|PhotoDriver * NULL if unsupported image type or failure, otherwise photo driver object */ -function photo_factory($data, $type = null) { - $ph = null; - $m = null; +function photo_factory($data, $type = null) +{ + $ph = null; + $m = null; - $unsupported_types = [ - 'image/bmp', - 'image/vnd.microsoft.icon', - 'image/tiff', - 'image/svg+xml', - ]; + $unsupported_types = [ + 'image/bmp', + 'image/vnd.microsoft.icon', + 'image/tiff', + 'image/svg+xml', + ]; - if ($type && in_array(strtolower($type), $unsupported_types)) { - logger('Unsupported image type ' . $type); - return null; - } + if ($type && in_array(strtolower($type), $unsupported_types)) { + logger('Unsupported image type ' . $type); + return null; + } - $ignore_imagick = get_config('system','ignore_imagick'); + $ignore_imagick = get_config('system', 'ignore_imagick'); - if (class_exists('Imagick') && !$ignore_imagick) { - $ph = new PhotoImagick($data, $type); + if (class_exists('Imagick') && !$ignore_imagick) { + $ph = new PhotoImagick($data, $type); - // As of August 2020, webp support is still poor in both imagick and gd. Both claim to support it, - // but both may require additional configuration. If it's a webp and the imagick driver failed, - // we'll try again with GD just in case that one handles it. If not, you may need to install libwebp - // which should make imagick work and/or re-compile php-gd with the option to include that library. + // As of August 2020, webp support is still poor in both imagick and gd. Both claim to support it, + // but both may require additional configuration. If it's a webp and the imagick driver failed, + // we'll try again with GD just in case that one handles it. If not, you may need to install libwebp + // which should make imagick work and/or re-compile php-gd with the option to include that library. - if (! $ph->is_valid() && $type === 'image/webp') { - $ph = null; - } - } + if (! $ph->is_valid() && $type === 'image/webp') { + $ph = null; + } + } - if (! $ph) { - $ph = new PhotoGd($data, $type); - } + if (! $ph) { + $ph = new PhotoGd($data, $type); + } - return $ph; + return $ph; } @@ -67,81 +68,79 @@ function photo_factory($data, $type = null) { * Headers to check for Content-Type (from curl request) * @return null|string Guessed mimetype */ - -function guess_image_type($filename, $headers = '') { - // logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG); - $type = null; - $m = null; - if($headers) { - $hdrs = []; - $h = explode("\n", $headers); - foreach ($h as $l) { - if (strpos($l,':') !== false) { - list($k, $v) = array_map('trim', explode(':', trim($l), 2)); - $hdrs[strtolower($k)] = $v; - } - } - logger('Curl headers: ' . print_r($hdrs, true), LOGGER_DEBUG); - if (array_key_exists('content-type', $hdrs)) { - $ph = photo_factory(''); - $types = $ph->supportedTypes(); +function guess_image_type($filename, $headers = '') +{ + // logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG); + $type = null; + $m = null; - if (array_key_exists($hdrs['content-type'], $types)) - $type = $hdrs['content-type']; - } - } + if ($headers) { + $hdrs = []; + $h = explode("\n", $headers); + foreach ($h as $l) { + if (strpos($l, ':') !== false) { + list($k, $v) = array_map('trim', explode(':', trim($l), 2)); + $hdrs[strtolower($k)] = $v; + } + } + logger('Curl headers: ' . print_r($hdrs, true), LOGGER_DEBUG); + if (array_key_exists('content-type', $hdrs)) { + $ph = photo_factory(''); + $types = $ph->supportedTypes(); - if (is_null($type)) { - $ignore_imagick = get_config('system', 'ignore_imagick'); - // Guessing from extension? Isn't that... dangerous? - if(class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) { - /** - * Well, this not much better, - * but at least it comes from the data inside the image, - * we won't be tricked by a manipulated extension - */ - $image = new Imagick($filename); - $type = $image->getImageMimeType(); - } + if (array_key_exists($hdrs['content-type'], $types)) { + $type = $hdrs['content-type']; + } + } + } - if (is_null($type)) { - $ext = pathinfo($filename, PATHINFO_EXTENSION); - $ph = photo_factory(''); - $types = $ph->supportedTypes(); - foreach ($types as $m => $e) { - if ($ext === $e) { - $type = $m; - } - } - } + if (is_null($type)) { + $ignore_imagick = get_config('system', 'ignore_imagick'); + // Guessing from extension? Isn't that... dangerous? + if (class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) { + /** + * Well, this not much better, + * but at least it comes from the data inside the image, + * we won't be tricked by a manipulated extension + */ + $image = new Imagick($filename); + $type = $image->getImageMimeType(); + } - if (is_null($type) && (strpos($filename, 'http') === false)) { - $size = getimagesize($filename); - $ph = photo_factory(''); - $types = $ph->supportedTypes(); - $type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg'); - } - if (is_null($type)) { - if (strpos(strtolower($filename),'jpg') !== false) { - $type = 'image/jpeg'; - } - elseif (strpos(strtolower($filename),'jpeg') !== false) { - $type = 'image/jpeg'; - } - elseif (strpos(strtolower($filename),'gif') !== false) { - $type = 'image/gif'; - } - elseif (strpos(strtolower($filename),'png') !== false) { - $type = 'image/png'; - } - } + if (is_null($type)) { + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $ph = photo_factory(''); + $types = $ph->supportedTypes(); + foreach ($types as $m => $e) { + if ($ext === $e) { + $type = $m; + } + } + } - } - - logger('Photo: guess_image_type: filename = ' . $filename . ' type = ' . $type, LOGGER_DEBUG); + if (is_null($type) && (strpos($filename, 'http') === false)) { + $size = getimagesize($filename); + $ph = photo_factory(''); + $types = $ph->supportedTypes(); + $type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg'); + } + if (is_null($type)) { + if (strpos(strtolower($filename), 'jpg') !== false) { + $type = 'image/jpeg'; + } elseif (strpos(strtolower($filename), 'jpeg') !== false) { + $type = 'image/jpeg'; + } elseif (strpos(strtolower($filename), 'gif') !== false) { + $type = 'image/gif'; + } elseif (strpos(strtolower($filename), 'png') !== false) { + $type = 'image/png'; + } + } + } - return $type; + logger('Photo: guess_image_type: filename = ' . $filename . ' type = ' . $type, LOGGER_DEBUG); + + return $type; } /** @@ -151,38 +150,39 @@ function guess_image_type($filename, $headers = '') { * @param string $ob_hash * @return void */ -function delete_thing_photo($url, $ob_hash) { +function delete_thing_photo($url, $ob_hash) +{ - $hash = basename($url); - $dbhash = substr($hash, 0, strpos($hash, '-')); + $hash = basename($url); + $dbhash = substr($hash, 0, strpos($hash, '-')); - // hashes should be 32 bytes. + // hashes should be 32 bytes. - if ((! $ob_hash) || (strlen($dbhash) < 16)) { - return; - } + if ((! $ob_hash) || (strlen($dbhash) < 16)) { + return; + } - if (strpos($url,'/xp/') !== false && strpos($url,'.obj') !== false) { - $xppath = 'cache/xp/' . substr($hash,0,2) . '/' . substr($hash,2,2) . '/' . $hash; - if (file_exists($xppath)) { - unlink($xppath); - } - $xppath = str_replace('-4','-5',$xppath); - if (file_exists($xppath)) { - unlink($xppath); - } - $xppath = str_replace('-5','-6',$xppath); - if (file_exists($xppath)) { - unlink($xppath); - } - } - else { - q("delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'", - dbesc($ob_hash), - intval(PHOTO_THING), - dbesc($dbhash) - ); - } + if (strpos($url, '/xp/') !== false && strpos($url, '.obj') !== false) { + $xppath = 'cache/xp/' . substr($hash, 0, 2) . '/' . substr($hash, 2, 2) . '/' . $hash; + if (file_exists($xppath)) { + unlink($xppath); + } + $xppath = str_replace('-4', '-5', $xppath); + if (file_exists($xppath)) { + unlink($xppath); + } + $xppath = str_replace('-5', '-6', $xppath); + if (file_exists($xppath)) { + unlink($xppath); + } + } else { + q( + "delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'", + dbesc($ob_hash), + intval(PHOTO_THING), + dbesc($dbhash) + ); + } } /** @@ -205,281 +205,269 @@ function delete_thing_photo($url, $ob_hash) { * * \e boolean \b 4 => TRUE if fetch failure * * \e string \b 5 => modification date */ -function import_xchan_photo($photo, $xchan, $thing = false, $force = false) { +function import_xchan_photo($photo, $xchan, $thing = false, $force = false) +{ - logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG); + logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG); - $flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN); - $album = (($thing) ? 'Things' : 'Contact Photos'); - $modified = EMPTY_STR; - $matches = null; - $failed = true; - $img_str = EMPTY_STR; - $hash = photo_new_resource(); - $os_storage = false; + $flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN); + $album = (($thing) ? 'Things' : 'Contact Photos'); + $modified = EMPTY_STR; + $matches = null; + $failed = true; + $img_str = EMPTY_STR; + $hash = photo_new_resource(); + $os_storage = false; - if (! $thing) { - $r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1", - dbesc($xchan), - intval(PHOTO_XCHAN) - ); - if ($r) { - $r = array_shift($r); - $hash = $r['resource_id']; - $modified = $r['edited']; - $type = $r['mimetype']; - } - else { - $os_storage = true; - } - } + if (! $thing) { + $r = q( + "select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1", + dbesc($xchan), + intval(PHOTO_XCHAN) + ); + if ($r) { + $r = array_shift($r); + $hash = $r['resource_id']; + $modified = $r['edited']; + $type = $r['mimetype']; + } else { + $os_storage = true; + } + } - if ($photo) { + if ($photo) { + if ($modified === EMPTY_STR || $force) { + $result = z_fetch_url($photo, true); + } else { + $h = [ 'headers' => [ 'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', strtotime($modified . 'Z')) . ' GMT' ] ]; + $result = z_fetch_url($photo, true, 0, $h); + } - if ($modified === EMPTY_STR || $force) { - $result = z_fetch_url($photo, true); - } - else { - $h = [ 'headers' => [ 'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', strtotime($modified . 'Z')) . ' GMT' ] ]; - $result = z_fetch_url($photo, true, 0, $h); - } + if ($result['success']) { + $img_str = $result['body']; + $type = guess_image_type($photo, $result['header']); + $modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $matches) ? strtotime($matches[1] . 'Z') : time())); + if (! is_null($type)) { + $failed = false; + } + } elseif ($result['return_code'] == 304) { + $photo = z_root() . '/photo/' . $hash . '-4'; + $thumb = z_root() . '/photo/' . $hash . '-5'; + $micro = z_root() . '/photo/' . $hash . '-6'; + $failed = false; + } + } - if ($result['success']) { - $img_str = $result['body']; - $type = guess_image_type($photo, $result['header']); - $modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $matches) ? strtotime($matches[1] . 'Z') : time())); - if (! is_null($type)) { - $failed = false; - } - } - elseif ($result['return_code'] == 304) { - $photo = z_root() . '/photo/' . $hash . '-4'; - $thumb = z_root() . '/photo/' . $hash . '-5'; - $micro = z_root() . '/photo/' . $hash . '-6'; - $failed = false; - } - } + if (! $failed && $result['return_code'] != 304) { + $img = photo_factory($img_str, $type); + if ($img && $img->is_valid()) { + $width = $img->getWidth(); + $height = $img->getHeight(); - if (! $failed && $result['return_code'] != 304) { - $img = photo_factory($img_str, $type); - if ($img && $img->is_valid()) { - $width = $img->getWidth(); - $height = $img->getHeight(); + if ($width && $height) { + if (($width / $height) > 1.2) { + // crop out the sides + $margin = $width - $height; + $img->cropImage(300, ($margin / 2), 0, $height, $height); + } elseif (($height / $width) > 1.2) { + // crop out the bottom + $margin = $height - $width; + $img->cropImage(300, 0, 0, $width, $width); + } else { + $img->scaleImageSquare(300); + } + } else { + $failed = true; + } - if ($width && $height) { - if (($width / $height) > 1.2) { - // crop out the sides - $margin = $width - $height; - $img->cropImage(300, ($margin / 2), 0, $height, $height); - } - elseif (($height / $width) > 1.2) { - // crop out the bottom - $margin = $height - $width; - $img->cropImage(300, 0, 0, $width, $width); - } - else { - $img->scaleImageSquare(300); - } - } - else { - $failed = true; - } + $p = [ + 'xchan' => $xchan, + 'resource_id' => $hash, + 'filename' => basename($photo), + 'album' => $album, + 'photo_usage' => $flags, + 'imgscale' => 4, + 'edited' => $modified, + ]; - $p = [ - 'xchan' => $xchan, - 'resource_id' => $hash, - 'filename' => basename($photo), - 'album' => $album, - 'photo_usage' => $flags, - 'imgscale' => 4, - 'edited' => $modified, - ]; + $r = $img->save($p); + if ($r === false) { + $failed = true; + } + $img->scaleImage(80); + $p['imgscale'] = 5; + $r = $img->save($p); + if ($r === false) { + $failed = true; + } + $img->scaleImage(48); + $p['imgscale'] = 6; + $r = $img->save($p); + if ($r === false) { + $failed = true; + } + $photo = z_root() . '/photo/' . $hash . '-4'; + $thumb = z_root() . '/photo/' . $hash . '-5'; + $micro = z_root() . '/photo/' . $hash . '-6'; + } else { + logger('Invalid image from ' . $photo); + $failed = true; + } + } - $r = $img->save($p); - if ($r === false) { - $failed = true; - } - $img->scaleImage(80); - $p['imgscale'] = 5; - $r = $img->save($p); - if ($r === false) { - $failed = true; - } - $img->scaleImage(48); - $p['imgscale'] = 6; - $r = $img->save($p); - if ($r === false) { - $failed = true; - } - $photo = z_root() . '/photo/' . $hash . '-4'; - $thumb = z_root() . '/photo/' . $hash . '-5'; - $micro = z_root() . '/photo/' . $hash . '-6'; - } - else { - logger('Invalid image from ' . $photo); - $failed = true; - } - } - - if ($failed) { - $default = get_default_profile_photo(); - $photo = z_root() . '/' . $default; - $thumb = z_root() . '/' . get_default_profile_photo(80); - $micro = z_root() . '/' . get_default_profile_photo(48); - $type = 'image/png'; - $modified = gmdate('Y-m-d H:i:s', filemtime($default)); - } + if ($failed) { + $default = get_default_profile_photo(); + $photo = z_root() . '/' . $default; + $thumb = z_root() . '/' . get_default_profile_photo(80); + $micro = z_root() . '/' . get_default_profile_photo(48); + $type = 'image/png'; + $modified = gmdate('Y-m-d H:i:s', filemtime($default)); + } - logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified - . '; failure: ' . ($failed ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG); + logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified + . '; failure: ' . ($failed ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG); - return([$photo, $thumb, $micro, $type, $failed, $modified]); + return([$photo, $thumb, $micro, $type, $failed, $modified]); } -function import_remote_xchan_photo($photo, $xchan, $thing = false) { +function import_remote_xchan_photo($photo, $xchan, $thing = false) +{ -// logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG); +// logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG); - // Assume the worst. - $failed = true; - $type = EMPTY_STR; - - $path = Hashpath::path((($thing) ? $photo . $xchan : $xchan),'cache/xp',2); - $hash = basename($path); + // Assume the worst. + $failed = true; + $type = EMPTY_STR; - $cached_file = $path . '-4' . (($thing) ? '.obj' : EMPTY_STR); + $path = Hashpath::path((($thing) ? $photo . $xchan : $xchan), 'cache/xp', 2); + $hash = basename($path); - $animated = get_config('system','animated_avatars',true); + $cached_file = $path . '-4' . (($thing) ? '.obj' : EMPTY_STR); - $modified = ((file_exists($cached_file)) ? @filemtime($cached_file) : 0); + $animated = get_config('system', 'animated_avatars', true); - // Maybe it's already a cached xchan photo - - if (strpos($photo, z_root() . '/xp/') === 0) { - return false; - } - - if ($modified) { - $h = [ 'headers' => [ 'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', $modified) . ' GMT' ] ]; - $recurse = 0; - $result = z_fetch_url($photo, true, $recurse, $h); - } - else { - $result = z_fetch_url($photo, true); - } + $modified = ((file_exists($cached_file)) ? @filemtime($cached_file) : 0); - if ($result['success']) { - $type = guess_image_type($photo, $result['header']); - if ((! $type) || strpos($type,'image') === false) { - @file_put_contents('cache/' . $hash, $result['body']); - $info = getimagesize('cache/' . $hash); - @unlink('cache/' . $hash); - if (isset($info) && is_array($info) && array_key_exists('mime',$info)) { - $type = $info['mime']; - } - } - if ($type) { - $failed = false; - } - } - elseif (intval($result['return_code']) === 304) { - - // continue using our cached copy, although we still need to figure out the type - // for the benefit of upstream callers that may require it + // Maybe it's already a cached xchan photo - if (file_exists($cached_file)) { - $info = getimagesize($cached_file); - if (isset($info) && is_array($info) && array_key_exists('mime',$info)) { - $type = $info['mime']; - } - } - - $photo = z_root() . '/xp/' . $hash . '-4' . (($thing) ? '.obj' : EMPTY_STR); - $thumb = z_root() . '/xp/' . $hash . '-5' . (($thing) ? '.obj' : EMPTY_STR); - $micro = z_root() . '/xp/' . $hash . '-6' . (($thing) ? '.obj' : EMPTY_STR); - $failed = false; - } + if (strpos($photo, z_root() . '/xp/') === 0) { + return false; + } + + if ($modified) { + $h = [ 'headers' => [ 'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', $modified) . ' GMT' ] ]; + $recurse = 0; + $result = z_fetch_url($photo, true, $recurse, $h); + } else { + $result = z_fetch_url($photo, true); + } + + if ($result['success']) { + $type = guess_image_type($photo, $result['header']); + if ((! $type) || strpos($type, 'image') === false) { + @file_put_contents('cache/' . $hash, $result['body']); + $info = getimagesize('cache/' . $hash); + @unlink('cache/' . $hash); + if (isset($info) && is_array($info) && array_key_exists('mime', $info)) { + $type = $info['mime']; + } + } + if ($type) { + $failed = false; + } + } elseif (intval($result['return_code']) === 304) { + // continue using our cached copy, although we still need to figure out the type + // for the benefit of upstream callers that may require it + + if (file_exists($cached_file)) { + $info = getimagesize($cached_file); + if (isset($info) && is_array($info) && array_key_exists('mime', $info)) { + $type = $info['mime']; + } + } + + $photo = z_root() . '/xp/' . $hash . '-4' . (($thing) ? '.obj' : EMPTY_STR); + $thumb = z_root() . '/xp/' . $hash . '-5' . (($thing) ? '.obj' : EMPTY_STR); + $micro = z_root() . '/xp/' . $hash . '-6' . (($thing) ? '.obj' : EMPTY_STR); + $failed = false; + } - if (! $failed && intval($result['return_code']) !== 304) { - $img = photo_factory($result['body'], $type); - if ($img && $img->is_valid()) { - $width = $img->getWidth(); - $height = $img->getHeight(); + if (! $failed && intval($result['return_code']) !== 304) { + $img = photo_factory($result['body'], $type); + if ($img && $img->is_valid()) { + $width = $img->getWidth(); + $height = $img->getHeight(); - if ($width && $height) { - if (($width / $height) > 1.2) { - // crop out the sides - $margin = $width - $height; - $img->cropImage(300, ($margin / 2), 0, $height, $height); - } - elseif (($height / $width) > 1.2) { - // crop out the bottom - $margin = $height - $width; - $img->cropImage(300, 0, 0, $width, $width); - } - else { - $img->scaleImageSquare(300); - } - } - else { - $failed = true; - } + if ($width && $height) { + if (($width / $height) > 1.2) { + // crop out the sides + $margin = $width - $height; + $img->cropImage(300, ($margin / 2), 0, $height, $height); + } elseif (($height / $width) > 1.2) { + // crop out the bottom + $margin = $height - $width; + $img->cropImage(300, 0, 0, $width, $width); + } else { + $img->scaleImageSquare(300); + } + } else { + $failed = true; + } - $p = [ - 'xchan' => $xchan, - 'resource_id' => $hash, - 'filename' => basename($photo), - 'album' => EMPTY_STR, - 'photo_usage' => 0, - 'imgscale' => 4, - 'edited' => $modified, - ]; + $p = [ + 'xchan' => $xchan, + 'resource_id' => $hash, + 'filename' => basename($photo), + 'album' => EMPTY_STR, + 'photo_usage' => 0, + 'imgscale' => 4, + 'edited' => $modified, + ]; - $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $photo = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $r = $img->saveImage($savepath,$animated); - if ($r === false) { - $failed = true; - } - $img->scaleImage(80); - $p['imgscale'] = 5; - $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $thumb = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $r = $img->saveImage($savepath,$animated); - if ($r === false) { - $failed = true; - } - $img->scaleImage(48); - $p['imgscale'] = 6; - $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $micro = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); - $r = $img->saveImage($savepath,$animated); - if ($r === false) { - $failed = true; - } - } - else { - logger('Invalid image from ' . $photo); - $failed = true; - } - } - - if ($failed) { - $default = get_default_profile_photo(); - $photo = z_root() . '/' . $default; - $thumb = z_root() . '/' . get_default_profile_photo(80); - $micro = z_root() . '/' . get_default_profile_photo(48); - $type = 'image/png'; - $modified = filemtime($default); - } + $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $photo = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $r = $img->saveImage($savepath, $animated); + if ($r === false) { + $failed = true; + } + $img->scaleImage(80); + $p['imgscale'] = 5; + $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $thumb = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $r = $img->saveImage($savepath, $animated); + if ($r === false) { + $failed = true; + } + $img->scaleImage(48); + $p['imgscale'] = 6; + $savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $micro = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR); + $r = $img->saveImage($savepath, $animated); + if ($r === false) { + $failed = true; + } + } else { + logger('Invalid image from ' . $photo); + $failed = true; + } + } - logger('HTTP code: ' . $result['return_code'] . '; modified: ' . (($modified) ? gmdate('D, d M Y H:i:s', $modified) . ' GMT' : 0 ) - . '; failure: ' . ($failed ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG); + if ($failed) { + $default = get_default_profile_photo(); + $photo = z_root() . '/' . $default; + $thumb = z_root() . '/' . get_default_profile_photo(80); + $micro = z_root() . '/' . get_default_profile_photo(48); + $type = 'image/png'; + $modified = filemtime($default); + } - return([$photo, $thumb, $micro, $type, $failed, $modified]); + logger('HTTP code: ' . $result['return_code'] . '; modified: ' . (($modified) ? gmdate('D, d M Y H:i:s', $modified) . ' GMT' : 0 ) + . '; failure: ' . ($failed ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG); + + return([$photo, $thumb, $micro, $type, $failed, $modified]); } @@ -495,21 +483,22 @@ function import_remote_xchan_photo($photo, $xchan, $thing = false) { * @param int $uid channel_id * @return null|string Guessed image mimetype or null. */ -function import_channel_photo_from_url($photo, $aid, $uid) { - $type = null; +function import_channel_photo_from_url($photo, $aid, $uid) +{ + $type = null; - if ($photo) { - $result = z_fetch_url($photo, true); + if ($photo) { + $result = z_fetch_url($photo, true); - if ($result['success']) { - $img_str = $result['body']; - $type = guess_image_type($photo, $result['header']); + if ($result['success']) { + $img_str = $result['body']; + $type = guess_image_type($photo, $result['header']); - import_channel_photo($img_str, $type, $aid, $uid); - } - } + import_channel_photo($img_str, $type, $aid, $uid); + } + } - return $type; + return $type; } /** @@ -521,69 +510,67 @@ function import_channel_photo_from_url($photo, $aid, $uid) { * @param int $uid channel_id * @return bool|string false on failure, otherwise resource_id of photo */ -function import_channel_photo($photo, $type, $aid, $uid) { +function import_channel_photo($photo, $type, $aid, $uid) +{ - logger('Importing channel photo for ' . $uid, LOGGER_DEBUG); + logger('Importing channel photo for ' . $uid, LOGGER_DEBUG); - $r = q("select resource_id from photo where uid = %d and photo_usage = 1 and imgscale = 4", - intval($uid) - ); - if ($r) { - $hash = $r[0]['resource_id']; - } - else { - $hash = photo_new_resource(); - } - - $photo_failure = false; - $filename = $hash; + $r = q( + "select resource_id from photo where uid = %d and photo_usage = 1 and imgscale = 4", + intval($uid) + ); + if ($r) { + $hash = $r[0]['resource_id']; + } else { + $hash = photo_new_resource(); + } - $img = photo_factory($photo, $type); - if ($img->is_valid()) { + $photo_failure = false; + $filename = $hash; - // config array for image save method - $p = [ - 'aid' => $aid, - 'uid' => $uid, - 'resource_id' => $hash, - 'filename' => $filename, - 'album' => t('Profile Photos'), - 'photo_usage' => PHOTO_PROFILE, - 'imgscale' => PHOTO_RES_PROFILE_300, - ]; + $img = photo_factory($photo, $type); + if ($img->is_valid()) { + // config array for image save method + $p = [ + 'aid' => $aid, + 'uid' => $uid, + 'resource_id' => $hash, + 'filename' => $filename, + 'album' => t('Profile Photos'), + 'photo_usage' => PHOTO_PROFILE, + 'imgscale' => PHOTO_RES_PROFILE_300, + ]; - // photo size - $img->scaleImageSquare(300); - $r = $img->save($p); - if ($r === false) { - $photo_failure = true; - } - - // thumb size - $img->scaleImage(80); - $p['imgscale'] = 5; - $r = $img->save($p); - if ($r === false) { - $photo_failure = true; - } - - // micro size - $img->scaleImage(48); - $p['imgscale'] = 6; - $r = $img->save($p); - if ($r === false) { - $photo_failure = true; - } + // photo size + $img->scaleImageSquare(300); + $r = $img->save($p); + if ($r === false) { + $photo_failure = true; + } - } - else { - logger('Invalid image.'); - $photo_failure = true; - } + // thumb size + $img->scaleImage(80); + $p['imgscale'] = 5; + $r = $img->save($p); + if ($r === false) { + $photo_failure = true; + } - if ($photo_failure) { - return false; - } + // micro size + $img->scaleImage(48); + $p['imgscale'] = 6; + $r = $img->save($p); + if ($r === false) { + $photo_failure = true; + } + } else { + logger('Invalid image.'); + $photo_failure = true; + } - return $hash; + if ($photo_failure) { + return false; + } + + return $hash; } diff --git a/include/photos.php b/include/photos.php index f60e58688..da0edc952 100644 --- a/include/photos.php +++ b/include/photos.php @@ -1,4 +1,5 @@ false ]; - $channel_id = $channel['channel_id']; - $account_id = $channel['channel_account_id']; - - if (! perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) { - $ret['message'] = t('Permission denied.'); - return $ret; - } - - /* - * Determine the album to use - */ - - $album = $args['album']; - - $visible = ((intval($args['visible']) || $args['visible'] === 'true') ? 1 : 0); - $deliver = ((array_key_exists('deliver', $args)) ? intval($args['deliver']) : 1 ); - - - // Set to default channel permissions. If the parent directory (album) has permissions set, - // use those instead. If we have specific permissions supplied, they take precedence over - // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings. - // ...messy... needs re-factoring once the photos/files integration stabilises - - $acl = new AccessControl($channel); - if (array_key_exists('directory',$args) && $args['directory']) { - $acl->set($args['directory']); - } - if (array_key_exists('allow_cid',$args)) { - $acl->set($args); - } - if ((array_key_exists('group_allow',$args)) - || (array_key_exists('contact_allow',$args)) - || (array_key_exists('group_deny',$args)) - || (array_key_exists('contact_deny',$args))) { - $acl->set_from_array($args); - } - - $ac = $acl->get(); - - $width = $height = 0; - - if($args['getimagesize']) { - $width = $args['getimagesize'][0]; - $height = $args['getimagesize'][1]; - } - - $os_storage = 0; - - $max_thumb = get_config('system','max_thumbnail',1600); - - if($args['os_syspath'] && $args['getimagesize']) { - if($args['getimagesize'][0] > $max_thumb || $args['getimagesize'][1] > $max_thumb) { - $imagick_path = get_config('system','imagick_convert_path'); - if($imagick_path && @file_exists($imagick_path)) { - $tmp_name = $args['os_syspath'] . '-001'; - $newsize = photo_calculate_scale(array_merge($args['getimagesize'],['max' => $max_thumb])); - $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $args['os_syspath']) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); - logger('imagick thumbnail command: ' . $cmd); - for($x = 0; $x < 4; $x ++) { - exec($cmd); - if(file_exists($tmp_name)) { - break; - } - logger('imagick scale failed. Retrying.'); - continue; - } - if(! file_exists($tmp_name)) { - logger('imagick scale failed. Abort.'); - return $ret; - } - - $imagedata = @file_get_contents($tmp_name); - $filesize = @filesize($args['os_syspath']); - } - else { - $imagedata = @file_get_contents($args['os_syspath']); - $filesize = strlen($imagedata); - } - } - else { - $imagedata = @file_get_contents($args['os_syspath']); - $filesize = strlen($imagedata); - } - $filename = $args['filename']; - // this is going to be deleted if it exists - $src = '/tmp/deletemenow'; - $type = $args['getimagesize']['mime']; - $os_storage = 1; - } - elseif ($args['data'] || $args['content']) { - - // allow an import from a binary string representing the image. - // This bypasses the upload step and max size limit checking - - $imagedata = (($args['content']) ? $args['content'] : $args['data']); - $filename = $args['filename']; - $filesize = strlen($imagedata); - // this is going to be deleted if it exists - $src = '/tmp/deletemenow'; - $type = (($args['mimetype']) ? $args['mimetype'] : $args['type']); - } else { - $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); - - if (x($f,'src') && x($f,'filesize')) { - $src = $f['src']; - $filename = $f['filename']; - $filesize = $f['filesize']; - $type = $f['type']; - } else { - $src = $_FILES['userfile']['tmp_name']; - $filename = basename($_FILES['userfile']['name']); - $filesize = intval($_FILES['userfile']['size']); - $type = $_FILES['userfile']['type']; - } - - if (! $type) - $type=guess_image_type($filename); - - logger('Received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG); - - $maximagesize = get_config('system','maximagesize'); - - if (($maximagesize) && ($filesize > $maximagesize)) { - $ret['message'] = sprintf ( t('Image exceeds website size limit of %lu bytes'), $maximagesize); - @unlink($src); - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - return $ret; - } - - if (! $filesize) { - $ret['message'] = t('Image file is empty.'); - @unlink($src); - /** - * @hooks photo_post_end - * Called after uploading a photo. - */ - call_hooks('photo_post_end', $ret); - return $ret; - } - - logger('Loading the contents of ' . $src , LOGGER_DEBUG); - $imagedata = @file_get_contents($src); - } - - $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", - intval($account_id) - ); - - $limit = engr_units_to_bytes(service_class_fetch($channel_id,'photo_upload_limit')); - - if (($r) && ($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { - $ret['message'] = upgrade_message(); - @unlink($src); - /** - * @hooks photo_post_end - * Called after uploading a photo. - */ - call_hooks('photo_post_end', $ret); - return $ret; - } - - $ph = photo_factory($imagedata, $type); - - if (! ($ph && $ph->is_valid())) { - $ret['message'] = t('Unable to process image'); - logger('unable to process image'); - @unlink($src); - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - return $ret; - } - - // obtain exif data from the source file if present - - $exif = $ph->exif(($args['os_syspath']) ? $args['os_syspath'] : $src); - - if($exif) { - $ph->orient($exif); - } - - $ph->clearexif(); - - if(get_pconfig($channel_id,'system','clearexif',false)) { - - // only do this on the original if it was uploaded by some method other than WebDAV. - // Otherwise Microsoft Windows will note the file size mismatch, erase the file and - // upload it again and again. - - } - - @unlink($src); - - $max_length = get_config('system','max_image_length', MAX_IMAGE_LENGTH); - if ($max_length > 0) { - $ph->scaleImage($max_length); - } - - if (! $width) { - $width = $ph->getWidth(); - } - if (! $height) { - $height = $ph->getHeight(); - } - $smallest = 0; - - $photo_hash = (($args['resource_id']) ? $args['resource_id'] : photo_new_resource()); - - $visitor = ''; - if ($channel['channel_hash'] !== $observer['xchan_hash']) - $visitor = $observer['xchan_hash']; - - $errors = false; - - $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, - 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, - 'width' => $width, 'height' => $height, - 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], - 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], - 'os_storage' => $os_storage, 'os_syspath' => $args['os_syspath'], - 'os_path' => $args['os_path'], 'display_path' => $args['display_path'] - ); - if($args['created']) - $p['created'] = $args['created']; - if($args['edited']) - $p['edited'] = $args['edited']; - if($args['title']) - $p['title'] = $args['title']; - - if ($args['description']) { - $p['description'] = $args['description']; - } - - $alt_desc = ((isset($p['description']) && $p['description']) ? $p['description'] : $p['filename']); - - $url = []; - - $r0 = $ph->save($p); - $url[0] = [ - 'type' => 'Link', - 'rel' => 'alternate', - 'mediaType' => $type, - 'summary' => $alt_desc, - 'href' => z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt(), - 'width' => $width, - 'height' => $height - ]; - if(! $r0) - $errors = true; - - unset($p['os_storage']); - unset($p['os_syspath']); - unset($p['width']); - unset($p['height']); - - if(($width > 1024 || $height > 1024) && (! $errors)) - $ph->scaleImage(1024); - - $p['imgscale'] = 1; - $r1 = $ph->storeThumbnail($p, PHOTO_RES_1024); - $url[1] = [ - 'type' => 'Link', - 'rel' => 'alternate', - 'mediaType' => $type, - 'summary' => $alt_desc, - 'href' => z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt(), - 'width' => $ph->getWidth(), - 'height' => $ph->getHeight() - ]; - if(! $r1) - $errors = true; - - if(($width > 640 || $height > 640) && (! $errors)) - $ph->scaleImage(640); - - $p['imgscale'] = 2; - $r2 = $ph->storeThumbnail($p, PHOTO_RES_640); - $url[2] = [ - 'type' => 'Link', - 'rel' => 'alternate', - 'mediaType' => $type, - 'summary' => $alt_desc, - 'href' => z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt(), - 'width' => $ph->getWidth(), - 'height' => $ph->getHeight() - ]; - if(! $r2) - $errors = true; - - if(($width > 320 || $height > 320) && (! $errors)) - $ph->scaleImage(320); - - $p['imgscale'] = 3; - $r3 = $ph->storeThumbnail($p, PHOTO_RES_320); - $url[3] = [ - 'type' => 'Link', - 'rel' => 'alternate', - 'mediaType' => $type, - 'summary' => $alt_desc, - 'href' => z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt(), - 'width' => $ph->getWidth(), - 'height' => $ph->getHeight() - ]; - if(! $r3) - $errors = true; - - if($errors) { - q("delete from photo where resource_id = '%s' and uid = %d", - dbesc($photo_hash), - intval($channel_id) - ); - $ret['message'] = t('Photo storage failed.'); - logger('Photo store failed.'); - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - return $ret; - } - - $url[] = [ - 'type' => 'Link', - 'rel' => 'about', - 'mediaType' => 'text/html', - 'href' => z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash - ]; - - $item_hidden = (($visible) ? 0 : 1 ); - - $lat = $lon = null; - - if($exif && Apps::system_app_installed($channel_id,'Photomap')) { - $gps = null; - if(array_key_exists('GPS',$exif)) { - $gps = $exif['GPS']; - } - elseif(array_key_exists('GPSLatitude',$exif)) { - $gps = $exif; - } - if($gps) { - $lat = getGps($gps['GPSLatitude'], $gps['GPSLatitudeRef']); - $lon = getGps($gps['GPSLongitude'], $gps['GPSLongitudeRef']); - } - } - - $title = ((isset($args['title']) && $args['title']) ? $args['title'] : $args['filename']); - - $desc = htmlspecialchars($alt_desc); - - $found_tags = linkify_tags($args['body'], $channel_id); - - $alt = ' alt="' . $desc . '"' ; - - $scale = 1; - $width = $url[1]['width']; - $height = $url[1]['height']; - $tag = (($r1) ? '[zmg width="' . $width . '" height="' . $height . '"' . $alt . ']' : '[zmg' . $alt . ']'); - - $author_link = '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/zrl]'; - - $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]'; - - $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $args['directory']['hash'] . ']' . ((strlen($album)) ? $album : '/') . '[/zrl]'; - - $activity_format = sprintf(t('%1$s posted %2$s to %3$s','photo_upload'), $author_link, $photo_link, $album_link); - - $body = (($args['body']) ? $args['body'] : '') . '[footer]' . $activity_format . '[/footer]'; - - // If uploaded into a post, this is the text that is returned to the webapp for inclusion in the post. - - $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' - . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]' - . '[/zrl]'; - - $attribution = (($visitor) ? $visitor['xchan_url'] : $channel['xchan_url']); - - // Create item object - $object = [ - 'type' => ACTIVITY_OBJ_PHOTO, - 'name' => $title, - 'summary' => $p['description'], - 'published' => datetime_convert('UTC','UTC',$p['created'],ATOM_TIME), - 'updated' => datetime_convert('UTC','UTC',$p['edited'],ATOM_TIME), - 'attributedTo' => $attribution, - // This is a placeholder and will get over-ridden by the item mid, which is critical for sharing as a conversational item over activitypub - 'id' => z_root() . '/photo/' . $photo_hash, - 'url' => $url, - 'source' => [ 'content' => $body, 'mediaType' => 'text/bbcode' ], - 'content' => bbcode($body) - ]; - - $public = (($ac['allow_cid'] || $ac['allow_gid'] || $ac['deny_cid'] || $ac['deny_gid']) ? false : true); - - if ($public) { - $object['to'] = [ ACTIVITY_PUBLIC_INBOX ]; - $object['cc'] = [ z_root() . '/followers/' . $channel['channel_address'] ]; - } - else { - $object['to'] = Activity::map_acl(array_merge($ac, ['item_private' => 1 - intval($public) ])); - } - - $target = [ - 'type' => 'orderedCollection', - 'name' => ((strlen($album)) ? $album : '/'), - 'id' => z_root() . '/album/' . $channel['channel_address'] . ((isset($args['folder'])) ? '/' . $args['folder'] : EMPTY_STR) - ]; - - $post_tags = []; - - if ($found_tags) { - foreach($found_tags as $result) { - $success = $result['success']; - if($success['replaced']) { - $post_tags[] = array( - 'uid' => $channel['channel_id'], - 'ttype' => $success['termtype'], - 'otype' => TERM_OBJ_POST, - 'term' => $success['term'], - 'url' => $success['url'] - ); - } - } - } - - // Create item container - if ($args['item']) { - foreach ($args['item'] as $i) { - - $item = get_item_elements($i); - $force = false; - - if($item['mid'] === $item['parent_mid']) { - - $object['id'] = $item['mid']; - $item['summary'] = $summary; - $item['body'] = $body; - $item['mimetype'] = 'text/bbcode'; - $item['obj_type'] = ACTIVITY_OBJ_PHOTO; - $item['obj'] = json_encode($object); - - $item['tgt_type'] = 'orderedCollection'; - $item['target'] = json_encode($target); - if ($post_tags) { - $arr['term'] = $post_tags; - } - $force = true; - } - $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']) || $force) { - $item['id'] = $r[0]['id']; - $item['uid'] = $channel['channel_id']; - item_store_update($item,false,$deliver); - continue; - } - } - else { - $item['aid'] = $channel['channel_account_id']; - $item['uid'] = $channel['channel_id']; - $item_result = item_store($item,false,$deliver); - } - } - } - else { - - $uuid = new_uuid(); - $mid = z_root() . '/item/' . $uuid; - - $object['id'] = $mid; - - $arr = [ - 'aid' => $account_id, - 'uid' => $channel_id, - 'uuid' => $uuid, - 'mid' => $mid, - 'parent_mid' => $mid, - 'created' => $p['created'], - 'edited' => $p['edited'], - 'item_hidden' => $item_hidden, - 'resource_type' => 'photo', - 'resource_id' => $photo_hash, - 'owner_xchan' => $channel['channel_hash'], - 'author_xchan' => $observer['xchan_hash'], - 'title' => $title, - 'allow_cid' => $ac['allow_cid'], - 'allow_gid' => $ac['allow_gid'], - 'deny_cid' => $ac['deny_cid'], - 'deny_gid' => $ac['deny_gid'], - 'verb' => ACTIVITY_POST, - 'obj_type' => ACTIVITY_OBJ_PHOTO, - 'obj' => json_encode($object), - 'tgt_type' => 'orderedCollection', - 'target' => json_encode($target), - 'item_wall' => 1, - 'item_origin' => 1, - 'item_thread_top' => 1, - 'item_private' => intval($acl->is_private()), - 'summary' => $summary, - 'body' => $body - ]; - - if ($post_tags) { - $arr['term'] = $post_tags; - } - - $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); - - if($lat && $lon) - $arr['coord'] = $lat . ' ' . $lon; - - // this one is tricky because the item and the photo have the same permissions, those of the photo. - // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the - // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use - // public policy when federating items to other sites, but should probably ignore them when accessing the item - // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo - // linked item from leaking into the feed when somebody has a channel with read_stream restrictions. - - $arr['public_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'view_stream'),true); - if($arr['public_policy']) - $arr['item_private'] = 1; - - - $result = item_store($arr,false,$deliver); - $item_id = $result['item_id']; - - if($visible && $deliver) - Run::Summon( [ 'Notifier', 'wall-new', $item_id ] ); - } - - $ret['success'] = true; - $ret['item'] = $arr; - $ret['body'] = $obj_body; - $ret['resource_id'] = $photo_hash; - $ret['photoitem_id'] = $item_id; - - /** - * @hooks photo_upload_end - * Called when a photo upload has been processed. - */ - call_hooks('photo_upload_end', $ret); - - return $ret; +function photo_upload($channel, $observer, $args) +{ + + $ret = [ 'success' => false ]; + $channel_id = $channel['channel_id']; + $account_id = $channel['channel_account_id']; + + if (! perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) { + $ret['message'] = t('Permission denied.'); + return $ret; + } + + /* + * Determine the album to use + */ + + $album = $args['album']; + + $visible = ((intval($args['visible']) || $args['visible'] === 'true') ? 1 : 0); + $deliver = ((array_key_exists('deliver', $args)) ? intval($args['deliver']) : 1 ); + + + // Set to default channel permissions. If the parent directory (album) has permissions set, + // use those instead. If we have specific permissions supplied, they take precedence over + // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings. + // ...messy... needs re-factoring once the photos/files integration stabilises + + $acl = new AccessControl($channel); + if (array_key_exists('directory', $args) && $args['directory']) { + $acl->set($args['directory']); + } + if (array_key_exists('allow_cid', $args)) { + $acl->set($args); + } + if ( + (array_key_exists('group_allow', $args)) + || (array_key_exists('contact_allow', $args)) + || (array_key_exists('group_deny', $args)) + || (array_key_exists('contact_deny', $args)) + ) { + $acl->set_from_array($args); + } + + $ac = $acl->get(); + + $width = $height = 0; + + if ($args['getimagesize']) { + $width = $args['getimagesize'][0]; + $height = $args['getimagesize'][1]; + } + + $os_storage = 0; + + $max_thumb = get_config('system', 'max_thumbnail', 1600); + + if ($args['os_syspath'] && $args['getimagesize']) { + if ($args['getimagesize'][0] > $max_thumb || $args['getimagesize'][1] > $max_thumb) { + $imagick_path = get_config('system', 'imagick_convert_path'); + if ($imagick_path && @file_exists($imagick_path)) { + $tmp_name = $args['os_syspath'] . '-001'; + $newsize = photo_calculate_scale(array_merge($args['getimagesize'], ['max' => $max_thumb])); + $cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $args['os_syspath']) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name); + logger('imagick thumbnail command: ' . $cmd); + for ($x = 0; $x < 4; $x++) { + exec($cmd); + if (file_exists($tmp_name)) { + break; + } + logger('imagick scale failed. Retrying.'); + continue; + } + if (! file_exists($tmp_name)) { + logger('imagick scale failed. Abort.'); + return $ret; + } + + $imagedata = @file_get_contents($tmp_name); + $filesize = @filesize($args['os_syspath']); + } else { + $imagedata = @file_get_contents($args['os_syspath']); + $filesize = strlen($imagedata); + } + } else { + $imagedata = @file_get_contents($args['os_syspath']); + $filesize = strlen($imagedata); + } + $filename = $args['filename']; + // this is going to be deleted if it exists + $src = '/tmp/deletemenow'; + $type = $args['getimagesize']['mime']; + $os_storage = 1; + } elseif ($args['data'] || $args['content']) { + // allow an import from a binary string representing the image. + // This bypasses the upload step and max size limit checking + + $imagedata = (($args['content']) ? $args['content'] : $args['data']); + $filename = $args['filename']; + $filesize = strlen($imagedata); + // this is going to be deleted if it exists + $src = '/tmp/deletemenow'; + $type = (($args['mimetype']) ? $args['mimetype'] : $args['type']); + } else { + $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); + + if (x($f, 'src') && x($f, 'filesize')) { + $src = $f['src']; + $filename = $f['filename']; + $filesize = $f['filesize']; + $type = $f['type']; + } else { + $src = $_FILES['userfile']['tmp_name']; + $filename = basename($_FILES['userfile']['name']); + $filesize = intval($_FILES['userfile']['size']); + $type = $_FILES['userfile']['type']; + } + + if (! $type) { + $type = guess_image_type($filename); + } + + logger('Received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG); + + $maximagesize = get_config('system', 'maximagesize'); + + if (($maximagesize) && ($filesize > $maximagesize)) { + $ret['message'] = sprintf(t('Image exceeds website size limit of %lu bytes'), $maximagesize); + @unlink($src); + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + return $ret; + } + + if (! $filesize) { + $ret['message'] = t('Image file is empty.'); + @unlink($src); + /** + * @hooks photo_post_end + * Called after uploading a photo. + */ + call_hooks('photo_post_end', $ret); + return $ret; + } + + logger('Loading the contents of ' . $src, LOGGER_DEBUG); + $imagedata = @file_get_contents($src); + } + + $r = q( + "select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", + intval($account_id) + ); + + $limit = engr_units_to_bytes(service_class_fetch($channel_id, 'photo_upload_limit')); + + if (($r) && ($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + $ret['message'] = upgrade_message(); + @unlink($src); + /** + * @hooks photo_post_end + * Called after uploading a photo. + */ + call_hooks('photo_post_end', $ret); + return $ret; + } + + $ph = photo_factory($imagedata, $type); + + if (! ($ph && $ph->is_valid())) { + $ret['message'] = t('Unable to process image'); + logger('unable to process image'); + @unlink($src); + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + return $ret; + } + + // obtain exif data from the source file if present + + $exif = $ph->exif(($args['os_syspath']) ? $args['os_syspath'] : $src); + + if ($exif) { + $ph->orient($exif); + } + + $ph->clearexif(); + + if (get_pconfig($channel_id, 'system', 'clearexif', false)) { + // only do this on the original if it was uploaded by some method other than WebDAV. + // Otherwise Microsoft Windows will note the file size mismatch, erase the file and + // upload it again and again. + } + + @unlink($src); + + $max_length = get_config('system', 'max_image_length', MAX_IMAGE_LENGTH); + if ($max_length > 0) { + $ph->scaleImage($max_length); + } + + if (! $width) { + $width = $ph->getWidth(); + } + if (! $height) { + $height = $ph->getHeight(); + } + $smallest = 0; + + $photo_hash = (($args['resource_id']) ? $args['resource_id'] : photo_new_resource()); + + $visitor = ''; + if ($channel['channel_hash'] !== $observer['xchan_hash']) { + $visitor = $observer['xchan_hash']; + } + + $errors = false; + + $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, + 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, + 'width' => $width, 'height' => $height, + 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], + 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], + 'os_storage' => $os_storage, 'os_syspath' => $args['os_syspath'], + 'os_path' => $args['os_path'], 'display_path' => $args['display_path'] + ); + if ($args['created']) { + $p['created'] = $args['created']; + } + if ($args['edited']) { + $p['edited'] = $args['edited']; + } + if ($args['title']) { + $p['title'] = $args['title']; + } + + if ($args['description']) { + $p['description'] = $args['description']; + } + + $alt_desc = ((isset($p['description']) && $p['description']) ? $p['description'] : $p['filename']); + + $url = []; + + $r0 = $ph->save($p); + $url[0] = [ + 'type' => 'Link', + 'rel' => 'alternate', + 'mediaType' => $type, + 'summary' => $alt_desc, + 'href' => z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt(), + 'width' => $width, + 'height' => $height + ]; + if (! $r0) { + $errors = true; + } + + unset($p['os_storage']); + unset($p['os_syspath']); + unset($p['width']); + unset($p['height']); + + if (($width > 1024 || $height > 1024) && (! $errors)) { + $ph->scaleImage(1024); + } + + $p['imgscale'] = 1; + $r1 = $ph->storeThumbnail($p, PHOTO_RES_1024); + $url[1] = [ + 'type' => 'Link', + 'rel' => 'alternate', + 'mediaType' => $type, + 'summary' => $alt_desc, + 'href' => z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt(), + 'width' => $ph->getWidth(), + 'height' => $ph->getHeight() + ]; + if (! $r1) { + $errors = true; + } + + if (($width > 640 || $height > 640) && (! $errors)) { + $ph->scaleImage(640); + } + + $p['imgscale'] = 2; + $r2 = $ph->storeThumbnail($p, PHOTO_RES_640); + $url[2] = [ + 'type' => 'Link', + 'rel' => 'alternate', + 'mediaType' => $type, + 'summary' => $alt_desc, + 'href' => z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt(), + 'width' => $ph->getWidth(), + 'height' => $ph->getHeight() + ]; + if (! $r2) { + $errors = true; + } + + if (($width > 320 || $height > 320) && (! $errors)) { + $ph->scaleImage(320); + } + + $p['imgscale'] = 3; + $r3 = $ph->storeThumbnail($p, PHOTO_RES_320); + $url[3] = [ + 'type' => 'Link', + 'rel' => 'alternate', + 'mediaType' => $type, + 'summary' => $alt_desc, + 'href' => z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt(), + 'width' => $ph->getWidth(), + 'height' => $ph->getHeight() + ]; + if (! $r3) { + $errors = true; + } + + if ($errors) { + q( + "delete from photo where resource_id = '%s' and uid = %d", + dbesc($photo_hash), + intval($channel_id) + ); + $ret['message'] = t('Photo storage failed.'); + logger('Photo store failed.'); + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + return $ret; + } + + $url[] = [ + 'type' => 'Link', + 'rel' => 'about', + 'mediaType' => 'text/html', + 'href' => z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash + ]; + + $item_hidden = (($visible) ? 0 : 1 ); + + $lat = $lon = null; + + if ($exif && Apps::system_app_installed($channel_id, 'Photomap')) { + $gps = null; + if (array_key_exists('GPS', $exif)) { + $gps = $exif['GPS']; + } elseif (array_key_exists('GPSLatitude', $exif)) { + $gps = $exif; + } + if ($gps) { + $lat = getGps($gps['GPSLatitude'], $gps['GPSLatitudeRef']); + $lon = getGps($gps['GPSLongitude'], $gps['GPSLongitudeRef']); + } + } + + $title = ((isset($args['title']) && $args['title']) ? $args['title'] : $args['filename']); + + $desc = htmlspecialchars($alt_desc); + + $found_tags = linkify_tags($args['body'], $channel_id); + + $alt = ' alt="' . $desc . '"' ; + + $scale = 1; + $width = $url[1]['width']; + $height = $url[1]['height']; + $tag = (($r1) ? '[zmg width="' . $width . '" height="' . $height . '"' . $alt . ']' : '[zmg' . $alt . ']'); + + $author_link = '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/zrl]'; + + $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]'; + + $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $args['directory']['hash'] . ']' . ((strlen($album)) ? $album : '/') . '[/zrl]'; + + $activity_format = sprintf(t('%1$s posted %2$s to %3$s', 'photo_upload'), $author_link, $photo_link, $album_link); + + $body = (($args['body']) ? $args['body'] : '') . '[footer]' . $activity_format . '[/footer]'; + + // If uploaded into a post, this is the text that is returned to the webapp for inclusion in the post. + + $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' + . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]' + . '[/zrl]'; + + $attribution = (($visitor) ? $visitor['xchan_url'] : $channel['xchan_url']); + + // Create item object + $object = [ + 'type' => ACTIVITY_OBJ_PHOTO, + 'name' => $title, + 'summary' => $p['description'], + 'published' => datetime_convert('UTC', 'UTC', $p['created'], ATOM_TIME), + 'updated' => datetime_convert('UTC', 'UTC', $p['edited'], ATOM_TIME), + 'attributedTo' => $attribution, + // This is a placeholder and will get over-ridden by the item mid, which is critical for sharing as a conversational item over activitypub + 'id' => z_root() . '/photo/' . $photo_hash, + 'url' => $url, + 'source' => [ 'content' => $body, 'mediaType' => 'text/bbcode' ], + 'content' => bbcode($body) + ]; + + $public = (($ac['allow_cid'] || $ac['allow_gid'] || $ac['deny_cid'] || $ac['deny_gid']) ? false : true); + + if ($public) { + $object['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + $object['cc'] = [ z_root() . '/followers/' . $channel['channel_address'] ]; + } else { + $object['to'] = Activity::map_acl(array_merge($ac, ['item_private' => 1 - intval($public) ])); + } + + $target = [ + 'type' => 'orderedCollection', + 'name' => ((strlen($album)) ? $album : '/'), + 'id' => z_root() . '/album/' . $channel['channel_address'] . ((isset($args['folder'])) ? '/' . $args['folder'] : EMPTY_STR) + ]; + + $post_tags = []; + + if ($found_tags) { + foreach ($found_tags as $result) { + $success = $result['success']; + if ($success['replaced']) { + $post_tags[] = array( + 'uid' => $channel['channel_id'], + 'ttype' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } + } + } + + // Create item container + if ($args['item']) { + foreach ($args['item'] as $i) { + $item = get_item_elements($i); + $force = false; + + if ($item['mid'] === $item['parent_mid']) { + $object['id'] = $item['mid']; + $item['summary'] = $summary; + $item['body'] = $body; + $item['mimetype'] = 'text/bbcode'; + $item['obj_type'] = ACTIVITY_OBJ_PHOTO; + $item['obj'] = json_encode($object); + + $item['tgt_type'] = 'orderedCollection'; + $item['target'] = json_encode($target); + if ($post_tags) { + $arr['term'] = $post_tags; + } + $force = true; + } + $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']) || $force) { + $item['id'] = $r[0]['id']; + $item['uid'] = $channel['channel_id']; + item_store_update($item, false, $deliver); + continue; + } + } else { + $item['aid'] = $channel['channel_account_id']; + $item['uid'] = $channel['channel_id']; + $item_result = item_store($item, false, $deliver); + } + } + } else { + $uuid = new_uuid(); + $mid = z_root() . '/item/' . $uuid; + + $object['id'] = $mid; + + $arr = [ + 'aid' => $account_id, + 'uid' => $channel_id, + 'uuid' => $uuid, + 'mid' => $mid, + 'parent_mid' => $mid, + 'created' => $p['created'], + 'edited' => $p['edited'], + 'item_hidden' => $item_hidden, + 'resource_type' => 'photo', + 'resource_id' => $photo_hash, + 'owner_xchan' => $channel['channel_hash'], + 'author_xchan' => $observer['xchan_hash'], + 'title' => $title, + 'allow_cid' => $ac['allow_cid'], + 'allow_gid' => $ac['allow_gid'], + 'deny_cid' => $ac['deny_cid'], + 'deny_gid' => $ac['deny_gid'], + 'verb' => ACTIVITY_POST, + 'obj_type' => ACTIVITY_OBJ_PHOTO, + 'obj' => json_encode($object), + 'tgt_type' => 'orderedCollection', + 'target' => json_encode($target), + 'item_wall' => 1, + 'item_origin' => 1, + 'item_thread_top' => 1, + 'item_private' => intval($acl->is_private()), + 'summary' => $summary, + 'body' => $body + ]; + + if ($post_tags) { + $arr['term'] = $post_tags; + } + + $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); + + if ($lat && $lon) { + $arr['coord'] = $lat . ' ' . $lon; + } + + // this one is tricky because the item and the photo have the same permissions, those of the photo. + // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the + // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use + // public policy when federating items to other sites, but should probably ignore them when accessing the item + // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo + // linked item from leaking into the feed when somebody has a channel with read_stream restrictions. + + $arr['public_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'view_stream'), true); + if ($arr['public_policy']) { + $arr['item_private'] = 1; + } + + + $result = item_store($arr, false, $deliver); + $item_id = $result['item_id']; + + if ($visible && $deliver) { + Run::Summon([ 'Notifier', 'wall-new', $item_id ]); + } + } + + $ret['success'] = true; + $ret['item'] = $arr; + $ret['body'] = $obj_body; + $ret['resource_id'] = $photo_hash; + $ret['photoitem_id'] = $item_id; + + /** + * @hooks photo_upload_end + * Called when a photo upload has been processed. + */ + call_hooks('photo_upload_end', $ret); + + return $ret; } -function photo_calculate_scale($arr) { +function photo_calculate_scale($arr) +{ - $max = $arr['max']; - $width = $arr[0]; - $height = $arr[1]; + $max = $arr['max']; + $width = $arr[0]; + $height = $arr[1]; - $dest_width = $dest_height = 0; + $dest_width = $dest_height = 0; - if (! ($width && $height)) { - return false; - } + if (! ($width && $height)) { + return false; + } - if ($width > $max && $height > $max) { + if ($width > $max && $height > $max) { + // very tall image (greater than 16:9) + // constrain the width - let the height float. - // very tall image (greater than 16:9) - // constrain the width - let the height float. + if ((($height * 9) / 16) > $width) { + $dest_width = $max; + $dest_height = intval(( $height * $max ) / $width); + } - if ((($height * 9) / 16) > $width) { - $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); - } + // else constrain both dimensions - // else constrain both dimensions + elseif ($width > $height) { + $dest_width = $max; + $dest_height = intval(( $height * $max ) / $width); + } else { + $dest_width = intval(( $width * $max ) / $height); + $dest_height = $max; + } + } else { + if ($width > $max) { + $dest_width = $max; + $dest_height = intval(( $height * $max ) / $width); + } else { + if ($height > $max) { + // very tall image (greater than 16:9) + // but width is OK - don't do anything - elseif ($width > $height) { - $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); - } - else { - $dest_width = intval(( $width * $max ) / $height); - $dest_height = $max; - } - } - else { - if ( $width > $max ) { - $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); - } - else { - if ( $height > $max ) { + if ((($height * 9) / 16) > $width) { + $dest_width = $width; + $dest_height = $height; + } else { + $dest_width = intval(( $width * $max ) / $height); + $dest_height = $max; + } + } else { + $dest_width = $width; + $dest_height = $height; + } + } + } - // very tall image (greater than 16:9) - // but width is OK - don't do anything - - if ((($height * 9) / 16) > $width) { - $dest_width = $width; - $dest_height = $height; - } - else { - $dest_width = intval(( $width * $max ) / $height); - $dest_height = $max; - } - } - else { - $dest_width = $width; - $dest_height = $height; - } - } - } - - return $dest_width . 'x' . $dest_height; + return $dest_width . 'x' . $dest_height; } /** @@ -659,99 +662,102 @@ function photo_calculate_scale($arr) { * * \e boolean \b success * * \e array \b albums */ -function photos_albums_list($channel, $observer, $sort_key = 'display_path', $direction = 'asc') { +function photos_albums_list($channel, $observer, $sort_key = 'display_path', $direction = 'asc') +{ - $channel_id = $channel['channel_id']; - $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); + $channel_id = $channel['channel_id']; + $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); - if (! perm_is_allowed($channel_id, $observer_xchan, 'view_storage')) { - return false; - } + if (! perm_is_allowed($channel_id, $observer_xchan, 'view_storage')) { + return false; + } - $sql_extra = permissions_sql($channel_id,$observer_xchan); + $sql_extra = permissions_sql($channel_id, $observer_xchan); - $sort_key = dbesc($sort_key); - $direction = dbesc($direction); + $sort_key = dbesc($sort_key); + $direction = dbesc($direction); - $r = q("select display_path, hash from attach where is_dir = 1 and uid = %d $sql_extra order by $sort_key $direction", - intval($channel_id) - ); + $r = q( + "select display_path, hash from attach where is_dir = 1 and uid = %d $sql_extra order by $sort_key $direction", + intval($channel_id) + ); - // add a 'root directory' to the results - - array_unshift($r,[ 'display_path' => '/', 'hash' => '' ]); - $str = ids_to_querystr($r,'hash',true); + // add a 'root directory' to the results - $albums = []; + array_unshift($r, [ 'display_path' => '/', 'hash' => '' ]); + $str = ids_to_querystr($r, 'hash', true); - if ($str) { - $x = q("select count( distinct hash ) as total, folder from attach where is_photo = 1 and uid = %d and folder in ( $str ) $sql_extra group by folder ", - intval($channel_id) - ); - if ($x) { - foreach ($r as $rv) { - foreach ($x as $xv) { - if ($xv['folder'] === $rv['hash']) { - if ($xv['total'] != 0 && attach_can_view_folder($channel_id,$observer_xchan,$xv['folder'])) { - $albums[] = [ 'album' => $rv['display_path'], 'folder' => $xv['folder'], 'total' => $xv['total'] ]; - } - continue; - } - } - } - } - } + $albums = []; - // add various encodings to the array so we can just loop through and pick them out in a template + if ($str) { + $x = q( + "select count( distinct hash ) as total, folder from attach where is_photo = 1 and uid = %d and folder in ( $str ) $sql_extra group by folder ", + intval($channel_id) + ); + if ($x) { + foreach ($r as $rv) { + foreach ($x as $xv) { + if ($xv['folder'] === $rv['hash']) { + if ($xv['total'] != 0 && attach_can_view_folder($channel_id, $observer_xchan, $xv['folder'])) { + $albums[] = [ 'album' => $rv['display_path'], 'folder' => $xv['folder'], 'total' => $xv['total'] ]; + } + continue; + } + } + } + } + } - $ret = [ 'success' => false ]; + // add various encodings to the array so we can just loop through and pick them out in a template - if ($albums) { - $ret['success'] = true; - $ret['albums'] = []; - foreach ($albums as $k => $album) { - $entry = [ - 'text' => (($album['album']) ? $album['album'] : '/'), - 'shorttext' => (($album['album']) ? ellipsify($album['album'],28) : '/'), - 'jstext' => (($album['album']) ? addslashes($album['album']) : '/'), - 'total' => $album['total'], - 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $album['folder'], - 'urlencode' => urlencode($album['album']), - 'bin2hex' => $album['folder'] - ]; - $ret['albums'][] = $entry; - } - } + $ret = [ 'success' => false ]; - App::$data['albums'] = $ret; + if ($albums) { + $ret['success'] = true; + $ret['albums'] = []; + foreach ($albums as $k => $album) { + $entry = [ + 'text' => (($album['album']) ? $album['album'] : '/'), + 'shorttext' => (($album['album']) ? ellipsify($album['album'], 28) : '/'), + 'jstext' => (($album['album']) ? addslashes($album['album']) : '/'), + 'total' => $album['total'], + 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $album['folder'], + 'urlencode' => urlencode($album['album']), + 'bin2hex' => $album['folder'] + ]; + $ret['albums'][] = $entry; + } + } - return $ret; + App::$data['albums'] = $ret; + + return $ret; } -function photos_album_widget($channelx,$observer,$sortkey = 'display_path',$direction = 'asc') { +function photos_album_widget($channelx, $observer, $sortkey = 'display_path', $direction = 'asc') +{ - $o = EMPTY_STR; + $o = EMPTY_STR; - if (array_key_exists('albums', App::$data)) { - $albums = App::$data['albums']; - } - else { - $albums = photos_albums_list($channelx,$observer,$sortkey,$direction); - } - - if ($albums['success']) { - $o = replace_macros(get_markup_template('photo_albums.tpl'), [ - '$nick' => $channelx['channel_address'], - '$title' => t('Photo Albums'), - '$recent' => t('Recent Photos'), - '$albums' => $albums['albums'], - '$baseurl' => z_root(), - '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage')) - ? t('Upload New Photos') : '') - ]); - } + if (array_key_exists('albums', App::$data)) { + $albums = App::$data['albums']; + } else { + $albums = photos_albums_list($channelx, $observer, $sortkey, $direction); + } - return $o; + if ($albums['success']) { + $o = replace_macros(get_markup_template('photo_albums.tpl'), [ + '$nick' => $channelx['channel_address'], + '$title' => t('Photo Albums'), + '$recent' => t('Recent Photos'), + '$albums' => $albums['albums'], + '$baseurl' => z_root(), + '$upload' => ((perm_is_allowed($channelx['channel_id'], (($observer) ? $observer['xchan_hash'] : ''), 'write_storage')) + ? t('Upload New Photos') : '') + ]); + } + + return $o; } /** @@ -762,38 +768,40 @@ function photos_album_widget($channelx,$observer,$sortkey = 'display_path',$dire * @param string $album (optional) default empty * @return bool|array */ -function photos_list_photos($channel, $observer, $album = '') { +function photos_list_photos($channel, $observer, $album = '') +{ - $channel_id = $channel['channel_id']; - $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); + $channel_id = $channel['channel_id']; + $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); - if (! perm_is_allowed($channel_id,$observer_xchan,'view_storage')) { - return false; - } + if (! perm_is_allowed($channel_id, $observer_xchan, 'view_storage')) { + return false; + } - $sql_extra = permissions_sql($channel_id); + $sql_extra = permissions_sql($channel_id); - if ($album) { - $sql_extra .= " and album = '" . protect_sprintf(dbesc($album)) . "' "; - } - - $ret = [ 'success' => false ]; + if ($album) { + $sql_extra .= " and album = '" . protect_sprintf(dbesc($album)) . "' "; + } - $r = q("select resource_id, created, edited, title, description, album, filename, mimetype, height, width, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and photo_usage in ( %d, %d ) $sql_extra ", - intval($channel_id), - intval(PHOTO_NORMAL), - intval(PHOTO_PROFILE) - ); + $ret = [ 'success' => false ]; - if ($r) { - for ($x = 0; $x < count($r); $x ++) { - $r[$x]['src'] = z_root() . '/photo/' . $r[$x]['resource_id'] . '-' . $r[$x]['imgscale']; - } - $ret['success'] = true; - $ret['photos'] = $r; - } + $r = q( + "select resource_id, created, edited, title, description, album, filename, mimetype, height, width, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and photo_usage in ( %d, %d ) $sql_extra ", + intval($channel_id), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) + ); - return $ret; + if ($r) { + for ($x = 0; $x < count($r); $x++) { + $r[$x]['src'] = z_root() . '/photo/' . $r[$x]['resource_id'] . '-' . $r[$x]['imgscale']; + } + $ret['success'] = true; + $ret['photos'] = $r; + } + + return $ret; } /** @@ -804,16 +812,18 @@ function photos_list_photos($channel, $observer, $album = '') { * @param string $album name of the album * @return bool */ -function photos_album_exists($channel_id, $observer_hash, $album) { +function photos_album_exists($channel_id, $observer_hash, $album) +{ - $sql_extra = permissions_sql($channel_id, $observer_hash); + $sql_extra = permissions_sql($channel_id, $observer_hash); - $r = q("SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE hash = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1", - dbesc($album), - intval($channel_id) - ); + $r = q( + "SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE hash = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1", + dbesc($album), + intval($channel_id) + ); - return (($r) ? array_shift($r) : false); + return (($r) ? array_shift($r) : false); } /** @@ -826,12 +836,14 @@ function photos_album_exists($channel_id, $observer_hash, $album) { * @param string $newname The new name of the album * @return bool|array */ -function photos_album_rename($channel_id, $oldname, $newname) { - return q("UPDATE photo SET album = '%s' WHERE album = '%s' AND uid = %d", - dbesc($newname), - dbesc($oldname), - intval($channel_id) - ); +function photos_album_rename($channel_id, $oldname, $newname) +{ + return q( + "UPDATE photo SET album = '%s' WHERE album = '%s' AND uid = %d", + dbesc($newname), + dbesc($oldname), + intval($channel_id) + ); } /** @@ -844,43 +856,48 @@ function photos_album_rename($channel_id, $oldname, $newname) { * @param string $remote_xchan (optional) default empty * @return string|bool */ -function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') { +function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') +{ - if($remote_xchan) { - $r = q("SELECT hash from attach where creator = '%s' and uid = %d and folder = '%s' ", - dbesc($remote_xchan), - intval($channel_id), - dbesc($album) - ); - } - else { - $r = q("SELECT hash from attach where uid = %d and folder = '%s' ", - intval($channel_id), - dbesc($album) - ); - } - if ($r) { - return ids_to_querystr($r,'hash',true); - } + if ($remote_xchan) { + $r = q( + "SELECT hash from attach where creator = '%s' and uid = %d and folder = '%s' ", + dbesc($remote_xchan), + intval($channel_id), + dbesc($album) + ); + } else { + $r = q( + "SELECT hash from attach where uid = %d and folder = '%s' ", + intval($channel_id), + dbesc($album) + ); + } + if ($r) { + return ids_to_querystr($r, 'hash', true); + } - return false; + return false; } -function photos_album_get_db_idstr_admin($channel_id, $album) { +function photos_album_get_db_idstr_admin($channel_id, $album) +{ - if(! is_site_admin()) - return false; + if (! is_site_admin()) { + return false; + } - $r = q("SELECT hash from attach where uid = %d and folder = '%s' ", - intval($channel_id), - dbesc($album) - ); + $r = q( + "SELECT hash from attach where uid = %d and folder = '%s' ", + intval($channel_id), + dbesc($album) + ); - if ($r) { - return ids_to_querystr($r,'hash',true); - } + if ($r) { + return ids_to_querystr($r, 'hash', true); + } - return false; + return false; } @@ -894,112 +911,124 @@ function photos_album_get_db_idstr_admin($channel_id, $album) { * @param bool $visible (optional) default false * @return int item_id */ -function photos_create_item($channel, $creator_hash, $photo, $visible = false) { +function photos_create_item($channel, $creator_hash, $photo, $visible = false) +{ - // Create item container + // Create item container - $item_hidden = (($visible) ? 0 : 1 ); + $item_hidden = (($visible) ? 0 : 1 ); - $uuid = new_uuid(); - $mid = z_root() . '/item/' . $uuid; + $uuid = new_uuid(); + $mid = z_root() . '/item/' . $uuid; - $arr = []; + $arr = []; - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $channel['channel_id']; - $arr['uuid'] = $uuid; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_thread_top'] = 1; - $arr['item_hidden'] = $item_hidden; - $arr['resource_type'] = 'photo'; - $arr['resource_id'] = $photo['resource_id']; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $creator_hash; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['uuid'] = $uuid; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_thread_top'] = 1; + $arr['item_hidden'] = $item_hidden; + $arr['resource_type'] = 'photo'; + $arr['resource_id'] = $photo['resource_id']; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $creator_hash; - $arr['allow_cid'] = $photo['allow_cid']; - $arr['allow_gid'] = $photo['allow_gid']; - $arr['deny_cid'] = $photo['deny_cid']; - $arr['deny_gid'] = $photo['deny_gid']; + $arr['allow_cid'] = $photo['allow_cid']; + $arr['allow_gid'] = $photo['allow_gid']; + $arr['deny_cid'] = $photo['deny_cid']; + $arr['deny_gid'] = $photo['deny_gid']; - $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); + $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); - $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' - . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]' - . '[/zrl]'; + $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' + . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]' + . '[/zrl]'; - $result = item_store($arr); - $item_id = $result['item_id']; + $result = item_store($arr); + $item_id = $result['item_id']; - return $item_id; + return $item_id; } -function getGps($exifCoord, $hemi) { +function getGps($exifCoord, $hemi) +{ - $degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; - $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; - $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; + $degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; + $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; + $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; - $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; + $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; - return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600))); + return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600))); } -function getGpstimestamp($exifCoord) { +function getGpstimestamp($exifCoord) +{ - $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; - $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; - $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; + $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0; + $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; + $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; - return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds); + return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds); } -function gps2Num($coordPart) { +function gps2Num($coordPart) +{ - $parts = explode('/', $coordPart); + $parts = explode('/', $coordPart); - if (count($parts) <= 0) - return 0; + if (count($parts) <= 0) { + return 0; + } - if (count($parts) == 1) - return $parts[0]; + if (count($parts) == 1) { + return $parts[0]; + } - return floatval($parts[0]) / floatval($parts[1]); + return floatval($parts[0]) / floatval($parts[1]); } -function photo_profile_setperms($channel_id,$resource_id,$profile_id) { +function photo_profile_setperms($channel_id, $resource_id, $profile_id) +{ - if(! $profile_id) - return; + if (! $profile_id) { + return; + } - $r = q("select profile_guid, is_default from profile where id = %d and uid = %d limit 1", - dbesc($profile_id), - intval($channel_id) - ); + $r = q( + "select profile_guid, is_default from profile where id = %d and uid = %d limit 1", + dbesc($profile_id), + intval($channel_id) + ); - if(! $r) - return; + if (! $r) { + return; + } - $is_default = $r[0]['is_default']; - $profile_guid = $r[0]['profile_guid']; + $is_default = $r[0]['is_default']; + $profile_guid = $r[0]['profile_guid']; - if($is_default) { - $r = q("update photo set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = '' + if ($is_default) { + $r = q( + "update photo set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = '' where resource_id = '%s' and uid = %d", - dbesc($resource_id), - intval($channel_id) - ); - $r = q("update attach set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = '' + dbesc($resource_id), + intval($channel_id) + ); + $r = q( + "update attach set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = '' where hash = '%s' and uid = %d", - dbesc($resource_id), - intval($channel_id) - ); - } + dbesc($resource_id), + intval($channel_id) + ); + } } /** @@ -1008,85 +1037,93 @@ function photo_profile_setperms($channel_id,$resource_id,$profile_id) { * @param int $uid * @param int|string $profileid */ -function profile_photo_set_profile_perms($uid, $profileid = 0) { +function profile_photo_set_profile_perms($uid, $profileid = 0) +{ - $allowcid = ''; + $allowcid = ''; - if($profileid) { - $r = q("SELECT photo, profile_guid, id, is_default, uid + if ($profileid) { + $r = q( + "SELECT photo, profile_guid, id, is_default, uid FROM profile WHERE uid = %d and ( profile.id = %d OR profile.profile_guid = '%s') LIMIT 1", - intval($uid), - intval($profileid), - dbesc($profileid) - ); - } - else { - logger('Resetting permissions on default-profile-photo for user ' . $uid); + intval($uid), + intval($profileid), + dbesc($profileid) + ); + } else { + logger('Resetting permissions on default-profile-photo for user ' . $uid); - $r = q("SELECT photo, profile_guid, id, is_default, uid FROM profile + $r = q( + "SELECT photo, profile_guid, id, is_default, uid FROM profile WHERE profile.uid = %d AND is_default = 1 LIMIT 1", - intval($uid) - ); //If no profile is given, we update the default profile - } - if(! $r) - return; + intval($uid) + ); //If no profile is given, we update the default profile + } + if (! $r) { + return; + } - $profile = $r[0]; + $profile = $r[0]; - if($profile['id'] && $profile['photo']) { - preg_match("@\w*(?=-\d*$)@i", $profile['photo'], $resource_id); - $resource_id = $resource_id[0]; + if ($profile['id'] && $profile['photo']) { + preg_match("@\w*(?=-\d*$)@i", $profile['photo'], $resource_id); + $resource_id = $resource_id[0]; - if (! intval($profile['is_default'])) { - $r0 = q("SELECT channel_hash FROM channel WHERE channel_id = %d LIMIT 1", - intval($uid) - ); - //Should not be needed in future. Catches old int-profile-ids. - $r1 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%d' ", - intval($profile['id']) - ); - $r2 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%s'", - dbesc($profile['profile_guid']) - ); - $allowcid = "<" . $r0[0]['channel_hash'] . ">"; - foreach ($r1 as $entry) { - $allowcid .= "<" . $entry['abook_xchan'] . ">"; - } - foreach ($r2 as $entry) { - $allowcid .= "<" . $entry['abook_xchan'] . ">"; - } + if (! intval($profile['is_default'])) { + $r0 = q( + "SELECT channel_hash FROM channel WHERE channel_id = %d LIMIT 1", + intval($uid) + ); + //Should not be needed in future. Catches old int-profile-ids. + $r1 = q( + "SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%d' ", + intval($profile['id']) + ); + $r2 = q( + "SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%s'", + dbesc($profile['profile_guid']) + ); + $allowcid = "<" . $r0[0]['channel_hash'] . ">"; + foreach ($r1 as $entry) { + $allowcid .= "<" . $entry['abook_xchan'] . ">"; + } + foreach ($r2 as $entry) { + $allowcid .= "<" . $entry['abook_xchan'] . ">"; + } - q("UPDATE photo SET allow_cid = '%s' WHERE resource_id = '%s' AND uid = %d", - dbesc($allowcid), - dbesc($resource_id), - intval($uid) - ); - } - else { - // Reset permissions on default profile picture to public - q("UPDATE photo SET allow_cid = '' WHERE photo_usage = %d AND uid = %d", - intval(PHOTO_PROFILE), - intval($uid) - ); - } - } + q( + "UPDATE photo SET allow_cid = '%s' WHERE resource_id = '%s' AND uid = %d", + dbesc($allowcid), + dbesc($resource_id), + intval($uid) + ); + } else { + // Reset permissions on default profile picture to public + q( + "UPDATE photo SET allow_cid = '' WHERE photo_usage = %d AND uid = %d", + intval(PHOTO_PROFILE), + intval($uid) + ); + } + } } -function fetch_image_from_url($url,&$mimetype) { +function fetch_image_from_url($url, &$mimetype) +{ - $redirects = 0; - $x = z_fetch_url($url,true,$redirects,[ 'novalidate' => true ]); - if($x['success']) { - $ht = new HTTPHeaders($x['header']); - $hdrs = $ht->fetcharr(); - if ($hdrs && array_key_exists('content-type', $hdrs)) { - $mimetype = $hdrs['content-type']; - } + $redirects = 0; + $x = z_fetch_url($url, true, $redirects, [ 'novalidate' => true ]); + if ($x['success']) { + $ht = new HTTPHeaders($x['header']); + $hdrs = $ht->fetcharr(); + if ($hdrs && array_key_exists('content-type', $hdrs)) { + $mimetype = $hdrs['content-type']; + } - return $x['body']; - } + return $x['body']; + } - return EMPTY_STR; + return EMPTY_STR; } @@ -1128,4 +1165,3 @@ function isAnimatedGif($fileName) return $totalCount > 1; } - diff --git a/include/security.php b/include/security.php index 49eb52441..7c27b833f 100644 --- a/include/security.php +++ b/include/security.php @@ -1,4 +1,5 @@ $atoken['atoken_id'], - 'xchan_hash' => substr($c['channel_hash'],0,16) . '.' . $atoken['atoken_guid'], - 'xchan_name' => $atoken['atoken_name'], - 'xchan_addr' => 'guest:' . $atoken['atoken_name'] . '@' . App::get_hostname(), - 'xchan_network' => 'token', - 'xchan_url' => z_root() . '/guest/' . substr($c['channel_hash'],0,16) . '.' . $atoken['atoken_guid'], - 'xchan_hidden' => 1, - 'xchan_photo_mimetype' => 'image/png', - 'xchan_photo_l' => z_root() . '/' . get_default_profile_photo(300), - 'xchan_photo_m' => z_root() . '/' . get_default_profile_photo(80), - 'xchan_photo_s' => z_root() . '/' . get_default_profile_photo(48) - ]; - } + $c = channelx_by_n($atoken['atoken_uid']); + if ($c) { + return [ + 'atoken_id' => $atoken['atoken_id'], + 'xchan_hash' => substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], + 'xchan_name' => $atoken['atoken_name'], + 'xchan_addr' => 'guest:' . $atoken['atoken_name'] . '@' . App::get_hostname(), + 'xchan_network' => 'token', + 'xchan_url' => z_root() . '/guest/' . substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], + 'xchan_hidden' => 1, + 'xchan_photo_mimetype' => 'image/png', + 'xchan_photo_l' => z_root() . '/' . get_default_profile_photo(300), + 'xchan_photo_m' => z_root() . '/' . get_default_profile_photo(80), + 'xchan_photo_s' => z_root() . '/' . get_default_profile_photo(48) + ]; + } - return null; + return null; } -function atoken_delete($atoken_id) { +function atoken_delete($atoken_id) +{ - $r = q("select * from atoken where atoken_id = %d", - intval($atoken_id) - ); - if (! $r) { - return; - } + $r = q( + "select * from atoken where atoken_id = %d", + intval($atoken_id) + ); + if (! $r) { + return; + } - $c = q("select channel_id, channel_hash from channel where channel_id = %d", - intval($r[0]['atoken_uid']) - ); - if (! $c) { - return; - } + $c = q( + "select channel_id, channel_hash from channel where channel_id = %d", + intval($r[0]['atoken_uid']) + ); + if (! $c) { + return; + } - $atoken_xchan = substr($c[0]['channel_hash'],0,16) . '.' . $r[0]['atoken_guid']; + $atoken_xchan = substr($c[0]['channel_hash'], 0, 16) . '.' . $r[0]['atoken_guid']; - q("delete from atoken where atoken_id = %d", - intval($atoken_id) - ); - q("delete from abook where abook_channel = %d and abook_xchan = '%s'", - intval($c[0]['channel_id']), - dbesc($atoken_xchan) - ); - - q("delete from abconfig where chan = %d and xchan = '%s'", - intval($c[0]['channel_id']), - dbesc($atoken_xchan) - ); + q( + "delete from atoken where atoken_id = %d", + intval($atoken_id) + ); + q( + "delete from abook where abook_channel = %d and abook_xchan = '%s'", + intval($c[0]['channel_id']), + dbesc($atoken_xchan) + ); + + q( + "delete from abconfig where chan = %d and xchan = '%s'", + intval($c[0]['channel_id']), + dbesc($atoken_xchan) + ); } /** @@ -182,70 +195,79 @@ function atoken_delete($atoken_id) { * @param array $xchan * @return void|bool */ -function atoken_create_xchan($xchan) { +function atoken_create_xchan($xchan) +{ - $r = q("select xchan_hash from xchan where xchan_hash = '%s'", - dbesc($xchan['xchan_hash']) - ); - if ($r) { - return; - } - - $xchan['xchan_guid'] = $xchan['xchan_hash']; + $r = q( + "select xchan_hash from xchan where xchan_hash = '%s'", + dbesc($xchan['xchan_hash']) + ); + if ($r) { + return; + } - $store = []; - foreach ($xchan as $k => $v) { - if (strpos($k,'xchan_') === 0) { - $store[$k] = $v; - } - } - - $r = xchan_store_lowlevel($store); + $xchan['xchan_guid'] = $xchan['xchan_hash']; - return true; + $store = []; + foreach ($xchan as $k => $v) { + if (strpos($k, 'xchan_') === 0) { + $store[$k] = $v; + } + } + + $r = xchan_store_lowlevel($store); + + return true; } -function atoken_abook($uid,$xchan_hash) { +function atoken_abook($uid, $xchan_hash) +{ - if(substr($xchan_hash,16,1) != '.') - return false; + if (substr($xchan_hash, 16, 1) != '.') { + return false; + } - $r = q("select channel_hash from channel where channel_id = %d limit 1", - intval($uid) - ); + $r = q( + "select channel_hash from channel where channel_id = %d limit 1", + intval($uid) + ); - if(! $r) - return false; + if (! $r) { + return false; + } - $x = q("select * from atoken where atoken_uid = %d and atoken_guid = '%s'", - intval($uid), - dbesc(substr($xchan_hash,17)) - ); + $x = q( + "select * from atoken where atoken_uid = %d and atoken_guid = '%s'", + intval($uid), + dbesc(substr($xchan_hash, 17)) + ); - if($x) { - $xchan = atoken_xchan($x[0]); - $xchan['abook_blocked'] = 0; - $xchan['abook_ignored'] = 0; - $xchan['abook_pending'] = 0; - return $xchan; - } + if ($x) { + $xchan = atoken_xchan($x[0]); + $xchan['abook_blocked'] = 0; + $xchan['abook_ignored'] = 0; + $xchan['abook_pending'] = 0; + return $xchan; + } - return false; + return false; } -function pseudo_abook($xchan) { - if(! $xchan) - return false; +function pseudo_abook($xchan) +{ + if (! $xchan) { + return false; + } - // set abook_pseudo to flag that we aren't really connected. + // set abook_pseudo to flag that we aren't really connected. - $xchan['abook_pseudo'] = 1; - $xchan['abook_blocked'] = 0; - $xchan['abook_ignored'] = 0; - $xchan['abook_pending'] = 0; + $xchan['abook_pseudo'] = 1; + $xchan['abook_blocked'] = 0; + $xchan['abook_ignored'] = 0; + $xchan['abook_pending'] = 0; - return $xchan; + return $xchan; } @@ -256,61 +278,65 @@ function pseudo_abook($xchan) { * * @return bool|array false or channel record of the new channel */ -function change_channel($change_channel) { +function change_channel($change_channel) +{ - $ret = false; + $ret = false; - if($change_channel) { + if ($change_channel) { + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1", + intval($change_channel), + intval(get_account_id()) + ); - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1", - intval($change_channel), - intval(get_account_id()) - ); + // It's not there. Is this an administrator, and is this the sys channel? + if (! $r) { + if (is_developer() || is_site_admin()) { + $r = q( + "select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_system = 1 and channel_removed = 0 limit 1", + intval($change_channel) + ); + } + } - // It's not there. Is this an administrator, and is this the sys channel? - if (! $r) { - if (is_developer() || is_site_admin()) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_system = 1 and channel_removed = 0 limit 1", - intval($change_channel) - ); - } - } + if ($r) { + $hash = $r[0]['channel_hash']; + $_SESSION['uid'] = intval($r[0]['channel_id']); + App::set_channel($r[0]); + $_SESSION['theme'] = $r[0]['channel_theme']; + $_SESSION['mobile_theme'] = get_pconfig(local_channel(), 'system', 'mobile_theme'); + $_SESSION['cloud_tiles'] = get_pconfig(local_channel(), 'system', 'cloud_tiles'); + date_default_timezone_set($r[0]['channel_timezone']); - if($r) { - $hash = $r[0]['channel_hash']; - $_SESSION['uid'] = intval($r[0]['channel_id']); - App::set_channel($r[0]); - $_SESSION['theme'] = $r[0]['channel_theme']; - $_SESSION['mobile_theme'] = get_pconfig(local_channel(),'system', 'mobile_theme'); - $_SESSION['cloud_tiles'] = get_pconfig(local_channel(),'system', 'cloud_tiles'); - date_default_timezone_set($r[0]['channel_timezone']); + // Update the active timestamp at most once a day - // Update the active timestamp at most once a day + if (substr($r[0]['channel_active'], 0, 10) !== substr(datetime_convert(), 0, 10) && (! (isset($_SESSION['sudo']) && $_SESSION['sudo']))) { + $z = q( + "UPDATE channel SET channel_active = '%s' WHERE channel_id = %d", + dbesc(datetime_convert()), + intval($r[0]['channel_id']) + ); + } + $ret = $r[0]; + } + $x = xchan_match([ 'xchan_hash' => $hash ]); + if ($x) { + $_SESSION['my_url'] = $x['xchan_url']; + $_SESSION['my_address'] = channel_reddress($r[0]); - if(substr($r[0]['channel_active'],0,10) !== substr(datetime_convert(),0,10) && (! (isset($_SESSION['sudo']) && $_SESSION['sudo']))) { - $z = q("UPDATE channel SET channel_active = '%s' WHERE channel_id = %d", - dbesc(datetime_convert()), - intval($r[0]['channel_id']) - ); - } - $ret = $r[0]; - } - $x = xchan_match([ 'xchan_hash' => $hash ]); - if($x) { - $_SESSION['my_url'] = $x['xchan_url']; - $_SESSION['my_address'] = channel_reddress($r[0]); + App::set_observer($x); + App::set_perms(get_all_perms(local_channel(), $hash)); + } + if (! is_dir('store/' . $r[0]['channel_address'])) { + @os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS, true); + } - App::set_observer($x); - App::set_perms(get_all_perms(local_channel(), $hash)); - } - if(! is_dir('store/' . $r[0]['channel_address'])) - @os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS,true); + $arr = [ 'channel_id' => $change_channel, 'chanx' => $ret ]; + call_hooks('change_channel', $arr); + } - $arr = [ 'channel_id' => $change_channel, 'chanx' => $ret ]; - call_hooks('change_channel', $arr); - } - - return $ret; + return $ret; } /** @@ -324,110 +350,107 @@ function change_channel($change_channel) { */ -function permissions_sql($owner_id, $remote_observer = null, $table = '', $token = EMPTY_STR) { +function permissions_sql($owner_id, $remote_observer = null, $table = '', $token = EMPTY_STR) +{ - $local_channel = local_channel(); + $local_channel = local_channel(); - /** - * Construct permissions - * - * default permissions - anonymous user - */ + /** + * Construct permissions + * + * default permissions - anonymous user + */ - if ($table) - $table .= '.'; + if ($table) { + $table .= '.'; + } - $sql = " AND {$table}allow_cid = '' + $sql = " AND {$table}allow_cid = '' AND {$table}allow_gid = '' AND {$table}deny_cid = '' AND {$table}deny_gid = '' "; - /** - * Profile owner - everything is visible - */ + /** + * Profile owner - everything is visible + */ - if (($local_channel) && ($local_channel == $owner_id)) { - return EMPTY_STR; - } + if (($local_channel) && ($local_channel == $owner_id)) { + return EMPTY_STR; + } - /** - * Authenticated visitor. - */ + /** + * Authenticated visitor. + */ - else { + else { + $observer = ((! is_null($remote_observer)) ? $remote_observer : get_observer_hash()); - $observer = ((! is_null($remote_observer)) ? $remote_observer : get_observer_hash()); + if ($observer) { + $sec = get_security_ids($owner_id, $observer); - if ($observer) { + if ($token) { + if (! array_key_exists('allow_cid', $sec)) { + $sec['allow_cid'] = []; + } + $sec['allow_cid'][] = 'token:' . $token; + } - $sec = get_security_ids($owner_id,$observer); + // always allow the channel owner, even if authenticated as a visitor - if ($token) { - if (! array_key_exists('allow_cid',$sec)) { - $sec['allow_cid'] = []; - } - $sec['allow_cid'][] = 'token:' . $token; - } + if ($sec['channel_id']) { + foreach ($sec['channel_id'] as $ch) { + if ($observer === $ch) { + return EMPTY_STR; + } + } + } - // always allow the channel owner, even if authenticated as a visitor + if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { + $ca = []; + foreach ($sec['allow_cid'] as $c) { + $ca[] = '<' . $c . '>'; + } + $cs = implode('|', $ca); + } else { + $cs = '<<>>'; // should be impossible to match + } - if ($sec['channel_id']) { - foreach ($sec['channel_id'] as $ch) { - if ($observer === $ch) { - return EMPTY_STR; - } - } - } + if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { + $ga = []; + foreach ($sec['allow_gid'] as $g) { + $ga[] = '<' . $g . '>'; + } + $gs = implode('|', $ga); + } else { + $gs = '<<>>'; // should be impossible to match + } - if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { - $ca = []; - foreach ($sec['allow_cid'] as $c) { - $ca[] = '<' . $c . '>'; - } - $cs = implode('|',$ca); - } - else { - $cs = '<<>>'; // should be impossible to match - } - - if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { - $ga = []; - foreach ($sec['allow_gid'] as $g) { - $ga[] = '<' . $g . '>'; - } - $gs = implode('|',$ga); - } - else { - $gs = '<<>>'; // should be impossible to match - } - - $regexop = db_getfunc('REGEXP'); - $sql = sprintf( - " AND ( NOT ({$table}deny_cid $regexop '%s' OR {$table}deny_gid $regexop '%s') + $regexop = db_getfunc('REGEXP'); + $sql = sprintf( + " AND ( NOT ({$table}deny_cid $regexop '%s' OR {$table}deny_gid $regexop '%s') AND ( {$table}allow_cid $regexop '%s' OR {$table}allow_gid $regexop '%s' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '') ) ) ", - dbesc($cs), - dbesc($gs), - dbesc($cs), - dbesc($gs) - ); - } + dbesc($cs), + dbesc($gs), + dbesc($cs), + dbesc($gs) + ); + } - /* - * OCAP token access - */ - - elseif ($token) { - $sql = " and ( {$table}allow_cid like '" . protect_sprintf('%%') . - "' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '' AND {$table}deny_cid = '' AND {$table}deny_gid = '' ) )"; - } + /* + * OCAP token access + */ - } + elseif ($token) { + $sql = " and ( {$table}allow_cid like '" . protect_sprintf('%%') . + "' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '' AND {$table}deny_cid = '' AND {$table}deny_gid = '' ) )"; + } + } - return $sql; + return $sql; } /** @@ -439,92 +462,89 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '', $token * @return string additional SQL where statement */ -function item_permissions_sql($owner_id, $remote_observer = null) { +function item_permissions_sql($owner_id, $remote_observer = null) +{ - $local_channel = local_channel(); + $local_channel = local_channel(); - /** - * Construct permissions - * - * default permissions - anonymous user - */ + /** + * Construct permissions + * + * default permissions - anonymous user + */ - $sql = " AND item_private = 0 "; + $sql = " AND item_private = 0 "; - /** - * Profile owner - everything is visible - */ + /** + * Profile owner - everything is visible + */ - if(($local_channel) && ($local_channel == $owner_id)) { - $sql = ''; - } + if (($local_channel) && ($local_channel == $owner_id)) { + $sql = ''; + } - /** - * Authenticated visitor. - */ - - else { + /** + * Authenticated visitor. + */ + else { $observer = (($remote_observer) ? $remote_observer : get_observer_hash()); - if($observer) { + if ($observer) { + $sec = get_security_ids($owner_id, $observer); - $sec = get_security_ids($owner_id,$observer); + // always allow the channel owner, even if authenticated as a visitor - // always allow the channel owner, even if authenticated as a visitor + if ($sec['channel_id']) { + foreach ($sec['channel_id'] as $ch) { + if ($observer === $ch) { + return EMPTY_STR; + } + } + } - if($sec['channel_id']) { - foreach($sec['channel_id'] as $ch) { - if($observer === $ch) { - return EMPTY_STR; - } - } - } + if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { + $ca = []; + foreach ($sec['allow_cid'] as $c) { + $ca[] = '<' . $c . '>'; + } + $cs = implode('|', $ca); + } else { + $cs = '<<>>'; // should be impossible to match + } - if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { - $ca = []; - foreach ($sec['allow_cid'] as $c) { - $ca[] = '<' . $c . '>'; - } - $cs = implode('|',$ca); - } - else { - $cs = '<<>>'; // should be impossible to match - } + if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { + $ga = []; + foreach ($sec['allow_gid'] as $g) { + $ga[] = '<' . $g . '>'; + } + $gs = implode('|', $ga); + } else { + $gs = '<<>>'; // should be impossible to match + } - if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { - $ga = []; - foreach ($sec['allow_gid'] as $g) { - $ga[] = '<' . $g . '>'; - } - $gs = implode('|',$ga); - } - else { - $gs = '<<>>'; // should be impossible to match - } + // This function is often called without an $owner_id in places where this could not be + // determined in advance. The ACL fields will usually not contain the original author or owner + // so we will also check for author_xchan and owner_xchan to account for this ACL deficiency. - // This function is often called without an $owner_id in places where this could not be - // determined in advance. The ACL fields will usually not contain the original author or owner - // so we will also check for author_xchan and owner_xchan to account for this ACL deficiency. - - $regexop = db_getfunc('REGEXP'); - $sql = sprintf( - " AND ( author_xchan = '%s' OR owner_xchan = '%s' OR + $regexop = db_getfunc('REGEXP'); + $sql = sprintf( + " AND ( author_xchan = '%s' OR owner_xchan = '%s' OR (( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s') AND ( allow_cid $regexop '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 )) ))) ", - dbesc($observer), - dbesc($observer), - dbesc($cs), - dbesc($gs), - dbesc($cs), - dbesc($gs) - ); - } - } + dbesc($observer), + dbesc($observer), + dbesc($cs), + dbesc($gs), + dbesc($cs), + dbesc($gs) + ); + } + } - return $sql; + return $sql; } /** @@ -533,53 +553,50 @@ function item_permissions_sql($owner_id, $remote_observer = null) { * @return string additional SQL where statement */ -function public_permissions_sql($observer_hash) { +function public_permissions_sql($observer_hash) +{ - $owner_id = 0; + $owner_id = 0; - if ($observer_hash) { + if ($observer_hash) { + $sec = get_security_ids($owner_id, $observer_hash); - $sec = get_security_ids($owner_id,$observer_hash); + if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { + $ca = []; + foreach ($sec['allow_cid'] as $c) { + $ca[] = '<' . $c . '>'; + } + $cs = implode('|', $ca); + } else { + $cs = '<<>>'; // should be impossible to match + } - if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) { - $ca = []; - foreach ($sec['allow_cid'] as $c) { - $ca[] = '<' . $c . '>'; - } - $cs = implode('|',$ca); - } - else { - $cs = '<<>>'; // should be impossible to match - } + if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { + $ga = []; + foreach ($sec['allow_gid'] as $g) { + $ga[] = '<' . $g . '>'; + } + $gs = implode('|', $ga); + } else { + $gs = '<<>>'; // should be impossible to match + } - if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) { - $ga = []; - foreach ($sec['allow_gid'] as $g) { - $ga[] = '<' . $g . '>'; - } - $gs = implode('|',$ga); - } - else { - $gs = '<<>>'; // should be impossible to match - } - - $regexop = db_getfunc('REGEXP'); - $sql = sprintf( - " AND ( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s') + $regexop = db_getfunc('REGEXP'); + $sql = sprintf( + " AND ( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s') AND ( allow_cid $regexop '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0) ) ) ", - dbesc($cs), - dbesc($gs), - dbesc($cs), - dbesc($gs) - ); - } - else { - $sql = " and item_private = 0 "; - } + dbesc($cs), + dbesc($gs), + dbesc($cs), + dbesc($gs) + ); + } else { + $sql = " and item_private = 0 "; + } - return $sql; + return $sql; } /* @@ -593,133 +610,147 @@ function public_permissions_sql($observer_hash) { * Actually, important actions should not be triggered by Links / GET-Requests at all, but somethimes they still are, * so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types). */ -function get_form_security_token($typename = '') { +function get_form_security_token($typename = '') +{ - $timestamp = time(); - $sec_hash = hash('whirlpool', App::$observer['xchan_guid'] . ((local_channel()) ? App::$channel['channel_prvkey'] : '') . session_id() . $timestamp . $typename); + $timestamp = time(); + $sec_hash = hash('whirlpool', App::$observer['xchan_guid'] . ((local_channel()) ? App::$channel['channel_prvkey'] : '') . session_id() . $timestamp . $typename); - return $timestamp . '.' . $sec_hash; + return $timestamp . '.' . $sec_hash; } -function check_form_security_token($typename = '', $formname = 'form_security_token') { - if (!x($_REQUEST, $formname)) return false; - $hash = $_REQUEST[$formname]; +function check_form_security_token($typename = '', $formname = 'form_security_token') +{ + if (!x($_REQUEST, $formname)) { + return false; + } + $hash = $_REQUEST[$formname]; - $max_livetime = 10800; // 3 hours + $max_livetime = 10800; // 3 hours - $x = explode('.', $hash); - if (time() > (IntVal($x[0]) + $max_livetime)) return false; + $x = explode('.', $hash); + if (time() > (IntVal($x[0]) + $max_livetime)) { + return false; + } - $sec_hash = hash('whirlpool', App::$observer['xchan_guid'] . ((local_channel()) ? App::$channel['channel_prvkey'] : '') . session_id() . $x[0] . $typename); + $sec_hash = hash('whirlpool', App::$observer['xchan_guid'] . ((local_channel()) ? App::$channel['channel_prvkey'] : '') . session_id() . $x[0] . $typename); - return ($sec_hash == $x[1]); + return ($sec_hash == $x[1]); } -function check_form_security_std_err_msg() { - return t('The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it.') . EOL; +function check_form_security_std_err_msg() +{ + return t('The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it.') . EOL; } -function check_form_security_token_redirectOnErr($err_redirect, $typename = '', $formname = 'form_security_token') { - if (!check_form_security_token($typename, $formname)) { - logger('check_form_security_token failed: user ' . App::$observer['xchan_name'] . ' - form element ' . $typename); - logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA); - notice( check_form_security_std_err_msg() ); - goaway(z_root() . $err_redirect ); - } +function check_form_security_token_redirectOnErr($err_redirect, $typename = '', $formname = 'form_security_token') +{ + if (!check_form_security_token($typename, $formname)) { + logger('check_form_security_token failed: user ' . App::$observer['xchan_name'] . ' - form element ' . $typename); + logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA); + notice(check_form_security_std_err_msg()); + goaway(z_root() . $err_redirect); + } } -function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'form_security_token') { - if (!check_form_security_token($typename, $formname)) { - logger('check_form_security_token failed: user ' . App::$observer['xchan_name'] . ' - form element ' . $typename); - logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA); - header('HTTP/1.1 403 Forbidden'); - killme(); - } +function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'form_security_token') +{ + if (!check_form_security_token($typename, $formname)) { + logger('check_form_security_token failed: user ' . App::$observer['xchan_name'] . ' - form element ' . $typename); + logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA); + header('HTTP/1.1 403 Forbidden'); + killme(); + } } // Returns an array of group hash id's on this entire site (across all channels) that this connection is a member of. // var $contact_id = xchan_hash of connection -function init_groups_visitor($contact_id) { - $groups = []; +function init_groups_visitor($contact_id) +{ + $groups = []; - // physical groups this channel is a member of + // physical groups this channel is a member of - $r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan = '%s' ", - dbesc($contact_id) - ); - if($r) { - foreach($r as $rr) - $groups[] = $rr['hash']; - } - return $groups; + $r = q( + "SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan = '%s' ", + dbesc($contact_id) + ); + if ($r) { + foreach ($r as $rr) { + $groups[] = $rr['hash']; + } + } + return $groups; } -function get_security_ids($channel_id, $ob_hash) { +function get_security_ids($channel_id, $ob_hash) +{ - $ret = [ - 'channel_id' => [], - 'allow_cid' => [], - 'allow_gid' => [] - ]; + $ret = [ + 'channel_id' => [], + 'allow_cid' => [], + 'allow_gid' => [] + ]; - if($channel_id) { - $ch = q("select channel_hash from channel where channel_id = %d", - intval($channel_id) - ); - if($ch) { - $ret['channel_id'][] = $ch[0]['channel_hash']; - } - } + if ($channel_id) { + $ch = q( + "select channel_hash from channel where channel_id = %d", + intval($channel_id) + ); + if ($ch) { + $ret['channel_id'][] = $ch[0]['channel_hash']; + } + } - $groups = []; + $groups = []; - $x = q("select * from xchan where xchan_hash = '%s'", - dbesc($ob_hash) - ); + $x = q( + "select * from xchan where xchan_hash = '%s'", + dbesc($ob_hash) + ); - if ($x) { + if ($x) { + // include xchans for all zot-like networks - // include xchans for all zot-like networks + $xchans = q( + "select xchan_hash, xchan_network from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ", + dbesc($ob_hash), + dbesc($x[0]['xchan_guid']), + dbesc($x[0]['xchan_pubkey']) + ); - $xchans = q("select xchan_hash, xchan_network from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ", - dbesc($ob_hash), - dbesc($x[0]['xchan_guid']), - dbesc($x[0]['xchan_pubkey']) - ); + if ($xchans) { + $ret['allow_cid'] = ids_to_array($xchans, 'xchan_hash'); + $hashes = ids_to_querystr($xchans, 'xchan_hash', true); - if ($xchans) { - $ret['allow_cid'] = ids_to_array($xchans,'xchan_hash'); - $hashes = ids_to_querystr($xchans,'xchan_hash',true); + // physical groups this identity is a member of - // physical groups this identity is a member of + $r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan in ( " . protect_sprintf($hashes) . " ) "); + if ($r) { + foreach ($r as $rv) { + $groups[] = $rv['hash']; + } + } - $r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan in ( " . protect_sprintf($hashes) . " ) "); - if($r) { - foreach ($r as $rv) { - $groups[] = $rv['hash']; - } - } + // virtual groups this identity is a member of - // virtual groups this identity is a member of + $r = q("select channel_hash from channel left join abook on channel_id = abook_channel where abook_xchan in ( " . protect_sprintf($hashes) . " ) and abook_self = 0 and abook_pending = 0 and abook_archived = 0 "); + if ($r) { + foreach ($r as $rv) { + $groups[] = 'connections:' . $rv['channel_hash']; + if ($xchans[0]['xchan_network'] === 'zot6') { + $groups[] = 'zot:' . $rv['channel_hash']; + } + if ($xchans[0]['xchan_network'] === 'activitypub') { + $groups[] = 'activitypub:' . $rv['channel_hash']; + } + } + } - $r = q("select channel_hash from channel left join abook on channel_id = abook_channel where abook_xchan in ( " . protect_sprintf($hashes) . " ) and abook_self = 0 and abook_pending = 0 and abook_archived = 0 "); - if ($r) { - foreach ($r as $rv) { - $groups[] = 'connections:' . $rv['channel_hash']; - if ($xchans[0]['xchan_network'] === 'zot6') { - $groups[] = 'zot:' . $rv['channel_hash']; - } - if ($xchans[0]['xchan_network'] === 'activitypub') { - $groups[] = 'activitypub:' . $rv['channel_hash']; - } - } - } + $ret['allow_gid'] = $groups; + } + } - $ret['allow_gid'] = $groups; - } - } - - return $ret; + return $ret; } - diff --git a/include/sharedwithme.php b/include/sharedwithme.php index b342f51d5..570b201e4 100644 --- a/include/sharedwithme.php +++ b/include/sharedwithme.php @@ -1,32 +1,30 @@ $max) { - break; - } + if (! $r) { + q( + "insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 0 ) ", + dbesc($xchan), + dbesc($hash), + intval(0), + dbesc(''), + dbesc(''), + dbesc(datetime_convert()) + ); + } else { + q( + "update xlink set xlink_updated = '%s' where xlink_id = %d", + dbesc(datetime_convert()), + intval($r[0]['xlink_id']) + ); + } - } - logger("poco_load: loaded $total entries",LOGGER_DEBUG); - - q("delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", - dbesc($xchan), - db_utcnow(), db_quoteinterval('7 DAY') - ); + $total++; + if ($total > $max) { + break; + } + } + logger("poco_load: loaded $total entries", LOGGER_DEBUG); + q( + "delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", + dbesc($xchan), + db_utcnow(), + db_quoteinterval('7 DAY') + ); } -function ap_poco_load($xchan) { +function ap_poco_load($xchan) +{ - $max = intval(get_config('system','max_imported_follow', MAX_IMPORTED_FOLLOW)); - if (! intval($max)) { - return; - } - - - if($xchan) { - $cl = get_xconfig($xchan,'activitypub','collections'); - if (is_array($cl) && $cl) { - $url = ((array_key_exists('following',$cl)) ? $cl['following'] : ''); - } - else { - return false; - } - } - - if (! $url) { - logger('ap_poco_load: no url'); - return; - } - - $obj = new ASCollection($url, '', 0, $max); - - $friends = $obj->get(); - - if (! $friends) { - return; - } - - foreach($friends as $entry) { - - $hash = EMPTY_STR; - - $x = q("select xchan_hash from xchan where (xchan_hash = '%s' or xchan_url = '%s') order by xchan_network desc limit 1", - dbesc($entry), - dbesc($entry) - ); + $max = intval(get_config('system', 'max_imported_follow', MAX_IMPORTED_FOLLOW)); + if (! intval($max)) { + return; + } - if ($x) { - $hash = $x[0]['xchan_hash']; - } - else { + if ($xchan) { + $cl = get_xconfig($xchan, 'activitypub', 'collections'); + if (is_array($cl) && $cl) { + $url = ((array_key_exists('following', $cl)) ? $cl['following'] : ''); + } else { + return false; + } + } - // We've never seen this person before. Import them. + if (! $url) { + logger('ap_poco_load: no url'); + return; + } - $wf = discover_by_webbie($entry); - if ($wf) { - $x = q("select xchan_hash from xchan where (xchan_hash = '%s' or xchan_url = '%s') order by xchan_network desc limit 1", - dbesc($wf), - dbesc($wf) - ); - if ($x) { - $hash = $x[0]['xchan_hash']; - } - } - } + $obj = new ASCollection($url, '', 0, $max); - if (! $hash) { - continue; - } + $friends = $obj->get(); - $total ++; + if (! $friends) { + return; + } - $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 0 limit 1", - dbesc($xchan), - dbesc($hash) - ); + foreach ($friends as $entry) { + $hash = EMPTY_STR; - if(! $r) { - q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 0 ) ", - dbesc($xchan), - dbesc($hash), - intval(0), - dbesc(''), - dbesc(''), - dbesc(datetime_convert()) - ); - } - else { - q("update xlink set xlink_updated = '%s' where xlink_id = %d", - dbesc(datetime_convert()), - intval($r[0]['xlink_id']) - ); - } - } + $x = q( + "select xchan_hash from xchan where (xchan_hash = '%s' or xchan_url = '%s') order by xchan_network desc limit 1", + dbesc($entry), + dbesc($entry) + ); - logger("ap_poco_load: loaded $total entries", LOGGER_DEBUG); - q("delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", - dbesc($xchan), - db_utcnow(), - db_quoteinterval('7 DAY') - ); + if ($x) { + $hash = $x[0]['xchan_hash']; + } else { + // We've never seen this person before. Import them. - return true; + $wf = discover_by_webbie($entry); + if ($wf) { + $x = q( + "select xchan_hash from xchan where (xchan_hash = '%s' or xchan_url = '%s') order by xchan_network desc limit 1", + dbesc($wf), + dbesc($wf) + ); + if ($x) { + $hash = $x[0]['xchan_hash']; + } + } + } + + if (! $hash) { + continue; + } + + $total++; + + $r = q( + "select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 0 limit 1", + dbesc($xchan), + dbesc($hash) + ); + + if (! $r) { + q( + "insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 0 ) ", + dbesc($xchan), + dbesc($hash), + intval(0), + dbesc(''), + dbesc(''), + dbesc(datetime_convert()) + ); + } else { + q( + "update xlink set xlink_updated = '%s' where xlink_id = %d", + dbesc(datetime_convert()), + intval($r[0]['xlink_id']) + ); + } + } + + logger("ap_poco_load: loaded $total entries", LOGGER_DEBUG); + + q( + "delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", + dbesc($xchan), + db_utcnow(), + db_quoteinterval('7 DAY') + ); + + return true; } -function count_common_friends($uid,$xchan) { +function count_common_friends($uid, $xchan) +{ - $r = q("SELECT count(xlink_id) as total from xlink where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in + $r = q( + "SELECT count(xlink_id) as total from xlink where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_self = 0 )", - dbesc($xchan), - dbesc($xchan), - intval($uid) - ); + dbesc($xchan), + dbesc($xchan), + intval($uid) + ); - if($r) - return $r[0]['total']; - return 0; + if ($r) { + return $r[0]['total']; + } + return 0; } -function common_friends($uid,$xchan,$start = 0,$limit=100000000,$shuffle = false) { +function common_friends($uid, $xchan, $start = 0, $limit = 100000000, $shuffle = false) +{ - $rand = db_getfunc('rand'); - if($shuffle) - $sql_extra = " order by $rand "; - else - $sql_extra = " order by xchan_name asc "; + $rand = db_getfunc('rand'); + if ($shuffle) { + $sql_extra = " order by $rand "; + } else { + $sql_extra = " order by xchan_name asc "; + } - $r = q("SELECT * from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in + $r = q( + "SELECT * from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_self = 0 ) $sql_extra limit %d offset %d", - dbesc($xchan), - dbesc($xchan), - intval($uid), - intval($limit), - intval($start) - ); + dbesc($xchan), + dbesc($xchan), + intval($uid), + intval($limit), + intval($start) + ); - return $r; + return $r; } -function suggestion_query($uid, $myxchan, $start = 0, $limit = 120) { +function suggestion_query($uid, $myxchan, $start = 0, $limit = 120) +{ - if ((! $uid) || (! $myxchan)) { - return []; - } + if ((! $uid) || (! $myxchan)) { + return []; + } - $r1 = q("SELECT count(xlink_xchan) as total, xchan.* from xchan + $r1 = q( + "SELECT count(xlink_xchan) as total, xchan.* from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan in ( select abook_xchan from abook where abook_channel = %d ) and not xlink_link in ( select abook_xchan from abook where abook_channel = %d ) @@ -388,18 +410,19 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 120) { and xchan_deleted = 0 and xlink_static = 0 group by xchan_hash order by total desc limit %d offset %d ", - intval($uid), - intval($uid), - intval($uid), - intval($limit), - intval($start) - ); + intval($uid), + intval($uid), + intval($uid), + intval($limit), + intval($start) + ); - if (! $r1) { - $r1 = []; - } + if (! $r1) { + $r1 = []; + } - $r2 = q("SELECT count(xtag_hash) as total, xchan.* from xchan + $r2 = q( + "SELECT count(xtag_hash) as total, xchan.* from xchan left join xtag on xtag_hash = xchan_hash where xtag_hash != '%s' and not xtag_hash in ( select abook_xchan from abook where abook_channel = %d ) @@ -408,238 +431,261 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 120) { and xchan_hidden = 0 and xchan_deleted = 0 group by xchan_hash order by total desc limit %d offset %d ", - dbesc($myxchan), - intval($uid), - dbesc($myxchan), - intval($uid), - intval($limit), - intval($start) - ); + dbesc($myxchan), + intval($uid), + dbesc($myxchan), + intval($uid), + intval($limit), + intval($start) + ); - if (! $r2) { - $r2 = []; - } + if (! $r2) { + $r2 = []; + } - foreach ($r2 as $r) { - $found = false; - for ($x = 0; $x < count($r1); $x ++) { - if ($r['xchan_hash'] === $r1[$x]['xchan_hash']) { - $r1[$x]['total'] = intval($r1[$x]['total']) + intval($r['total']); - $found = true; - continue; - } - } - if (! $found) { - $r1[] = $r; - } - } + foreach ($r2 as $r) { + $found = false; + for ($x = 0; $x < count($r1); $x++) { + if ($r['xchan_hash'] === $r1[$x]['xchan_hash']) { + $r1[$x]['total'] = intval($r1[$x]['total']) + intval($r['total']); + $found = true; + continue; + } + } + if (! $found) { + $r1[] = $r; + } + } - usort($r1,'socgraph_total_sort'); - return ($r1); + usort($r1, 'socgraph_total_sort'); + return ($r1); } -function socgraph_total_sort($a,$b) { - if ($a['total'] === $b['total']) { - return 0; - } - - return((intval($a['total']) < intval($b['total'])) ? 1 : -1 ); +function socgraph_total_sort($a, $b) +{ + if ($a['total'] === $b['total']) { + return 0; + } + + return((intval($a['total']) < intval($b['total'])) ? 1 : -1 ); } -function poco() { +function poco() +{ - $system_mode = false; + $system_mode = false; - if(observer_prohibited()) { - logger('mod_poco: block_public'); - http_status_exit(401); - } + if (observer_prohibited()) { + logger('mod_poco: block_public'); + http_status_exit(401); + } - $observer = App::get_observer(); + $observer = App::get_observer(); - if(argc() > 1) { - $user = notags(trim(argv(1))); - } - if(! (isset($user) && $user)) { - $c = q("select * from pconfig where cat = 'system' and k = 'suggestme' and v = '1'"); - if(! $c) { - logger('mod_poco: system mode. No candidates.', LOGGER_DEBUG); - http_status_exit(404); - } - $system_mode = true; - } + if (argc() > 1) { + $user = notags(trim(argv(1))); + } + if (! (isset($user) && $user)) { + $c = q("select * from pconfig where cat = 'system' and k = 'suggestme' and v = '1'"); + if (! $c) { + logger('mod_poco: system mode. No candidates.', LOGGER_DEBUG); + http_status_exit(404); + } + $system_mode = true; + } - $format = ((isset($_REQUEST['format']) && $_REQUEST['format']) ? $_REQUEST['format'] : 'json'); + $format = ((isset($_REQUEST['format']) && $_REQUEST['format']) ? $_REQUEST['format'] : 'json'); - $justme = false; + $justme = false; - if(argc() > 2 && argv(2) === '@me') - $justme = true; - if(argc() > 3) { - if(argv(3) === '@all') - $justme = false; - elseif(argv(3) === '@self') - $justme = true; - } - if(argc() > 4 && intval(argv(4)) && $justme == false) - $cid = intval(argv(4)); + if (argc() > 2 && argv(2) === '@me') { + $justme = true; + } + if (argc() > 3) { + if (argv(3) === '@all') { + $justme = false; + } elseif (argv(3) === '@self') { + $justme = true; + } + } + if (argc() > 4 && intval(argv(4)) && $justme == false) { + $cid = intval(argv(4)); + } - if(! $system_mode) { + if (! $system_mode) { + $r = q( + "SELECT channel_id from channel where channel_address = '%s' limit 1", + dbesc($user) + ); + if (! $r) { + logger('mod_poco: user mode. Account not found. ' . $user); + http_status_exit(404); + } - $r = q("SELECT channel_id from channel where channel_address = '%s' limit 1", - dbesc($user) - ); - if(! $r) { - logger('mod_poco: user mode. Account not found. ' . $user); - http_status_exit(404); - } + $channel_id = $r[0]['channel_id']; + $ohash = (($observer) ? $observer['xchan_hash'] : ''); - $channel_id = $r[0]['channel_id']; - $ohash = (($observer) ? $observer['xchan_hash'] : ''); + if (! perm_is_allowed($channel_id, $ohash, 'view_contacts')) { + logger('mod_poco: user mode. Permission denied for ' . $ohash . ' user: ' . $user); + http_status_exit(401); + } + } - if(! perm_is_allowed($channel_id,$ohash,'view_contacts')) { - logger('mod_poco: user mode. Permission denied for ' . $ohash . ' user: ' . $user); - http_status_exit(401); - } + if (isset($justme) && $justme) { + $sql_extra = " and abook_self = 1 "; + } else { + $sql_extra = " and abook_self = 0 "; + } - } + if (isset($cid) && $cid) { + $sql_extra = sprintf(" and abook_id = %d and abook_archived = 0 and abook_hidden = 0 and abook_pending = 0 ", intval($cid)); + } - if(isset($justme) && $justme) - $sql_extra = " and abook_self = 1 "; - else - $sql_extra = " and abook_self = 0 "; - - if(isset($cid) && $cid) - $sql_extra = sprintf(" and abook_id = %d and abook_archived = 0 and abook_hidden = 0 and abook_pending = 0 ",intval($cid)); - - if(isset($system_mode) && $system_mode) { - $r = q("SELECT count(*) as total from abook where abook_self = 1 + if (isset($system_mode) && $system_mode) { + $r = q("SELECT count(*) as total from abook where abook_self = 1 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') "); - } - else { - $r = q("SELECT count(*) as total from abook where abook_channel = %d + } else { + $r = q( + "SELECT count(*) as total from abook where abook_channel = %d $sql_extra ", - intval($channel_id) - ); - $rooms = q("select * from menu_item where ( mitem_flags & " . intval(MENU_ITEM_CHATROOM) . " ) > 0 and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and mitem_channel_id = %d", - intval($channel_id) - ); - } - if($r) - $totalResults = intval($r[0]['total']); - else - $totalResults = 0; + intval($channel_id) + ); + $rooms = q( + "select * from menu_item where ( mitem_flags & " . intval(MENU_ITEM_CHATROOM) . " ) > 0 and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and mitem_channel_id = %d", + intval($channel_id) + ); + } + if ($r) { + $totalResults = intval($r[0]['total']); + } else { + $totalResults = 0; + } - $startIndex = ((isset($_GET['startIndex'])) ? intval($_GET['startIndex']) : 0); - if($startIndex < 0) - $startIndex = 0; + $startIndex = ((isset($_GET['startIndex'])) ? intval($_GET['startIndex']) : 0); + if ($startIndex < 0) { + $startIndex = 0; + } - $itemsPerPage = ((isset($_GET['count']) && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults); + $itemsPerPage = ((isset($_GET['count']) && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults); - if($system_mode) { - $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_self = 1 + if ($system_mode) { + $r = q( + "SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_self = 1 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') limit %d offset %d ", - intval($itemsPerPage), - intval($startIndex) - ); - } else { - $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d + intval($itemsPerPage), + intval($startIndex) + ); + } else { + $r = q( + "SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $sql_extra LIMIT %d OFFSET %d", - intval($channel_id), - intval($itemsPerPage), - intval($startIndex) - ); - } + intval($channel_id), + intval($itemsPerPage), + intval($startIndex) + ); + } - $ret = []; - if(x($_GET,'sorted')) - $ret['sorted'] = 'false'; - if(x($_GET,'filtered')) - $ret['filtered'] = 'false'; - if(x($_GET,'updatedSince')) - $ret['updateSince'] = 'false'; + $ret = []; + if (x($_GET, 'sorted')) { + $ret['sorted'] = 'false'; + } + if (x($_GET, 'filtered')) { + $ret['filtered'] = 'false'; + } + if (x($_GET, 'updatedSince')) { + $ret['updateSince'] = 'false'; + } - $ret['startIndex'] = (string) $startIndex; - $ret['itemsPerPage'] = (string) $itemsPerPage; - $ret['totalResults'] = (string) $totalResults; + $ret['startIndex'] = (string) $startIndex; + $ret['itemsPerPage'] = (string) $itemsPerPage; + $ret['totalResults'] = (string) $totalResults; - if($rooms) { - $ret['chatrooms'] = []; - foreach($rooms as $room) { - $ret['chatrooms'][] = array('url' => $room['mitem_link'], 'desc' => $room['mitem_desc']); - } - } + if ($rooms) { + $ret['chatrooms'] = []; + foreach ($rooms as $room) { + $ret['chatrooms'][] = array('url' => $room['mitem_link'], 'desc' => $room['mitem_desc']); + } + } - $ret['entry'] = []; + $ret['entry'] = []; - $fields_ret = array( - 'id' => false, - 'guid' => false, - 'guid_sig' => false, - 'hash' => false, - 'displayName' => false, - 'urls' => false, - 'preferredUsername' => false, - 'photos' => false, - 'rating' => false - ); + $fields_ret = array( + 'id' => false, + 'guid' => false, + 'guid_sig' => false, + 'hash' => false, + 'displayName' => false, + 'urls' => false, + 'preferredUsername' => false, + 'photos' => false, + 'rating' => false + ); - if((! x($_GET,'fields')) || ($_GET['fields'] === '@all')) { - foreach($fields_ret as $k => $v) - $fields_ret[$k] = true; - } else { - $fields_req = explode(',',$_GET['fields']); - foreach($fields_req as $f) - $fields_ret[trim($f)] = true; - } + if ((! x($_GET, 'fields')) || ($_GET['fields'] === '@all')) { + foreach ($fields_ret as $k => $v) { + $fields_ret[$k] = true; + } + } else { + $fields_req = explode(',', $_GET['fields']); + foreach ($fields_req as $f) { + $fields_ret[trim($f)] = true; + } + } - if(is_array($r)) { - if(count($r)) { - foreach($r as $rr) { - $entry = []; - if($fields_ret['id']) - $entry['id'] = $rr['abook_id']; - if($fields_ret['guid']) - $entry['guid'] = $rr['xchan_guid']; - if($fields_ret['guid_sig']) - $entry['guid_sig'] = $rr['xchan_guid_sig']; - if($fields_ret['hash']) - $entry['hash'] = $rr['xchan_hash']; + if (is_array($r)) { + if (count($r)) { + foreach ($r as $rr) { + $entry = []; + if ($fields_ret['id']) { + $entry['id'] = $rr['abook_id']; + } + if ($fields_ret['guid']) { + $entry['guid'] = $rr['xchan_guid']; + } + if ($fields_ret['guid_sig']) { + $entry['guid_sig'] = $rr['xchan_guid_sig']; + } + if ($fields_ret['hash']) { + $entry['hash'] = $rr['xchan_hash']; + } - if($fields_ret['displayName']) - $entry['displayName'] = $rr['xchan_name']; - if($fields_ret['urls']) { - $entry['urls'] = array(array('value' => $rr['xchan_url'], 'type' => 'profile')); - $network = $rr['xchan_network']; - if($rr['xchan_addr']) - $entry['urls'][] = array('value' => 'acct:' . $rr['xchan_addr'], 'type' => $network); - } - if($fields_ret['preferredUsername']) - $entry['preferredUsername'] = substr($rr['xchan_addr'],0,strpos($rr['xchan_addr'],'@')); - if($fields_ret['photos']) - $entry['photos'] = array(array('value' => $rr['xchan_photo_l'], 'mimetype' => $rr['xchan_photo_mimetype'], 'type' => 'profile')); - $ret['entry'][] = $entry; - } - } - else - $ret['entry'][] = []; - } - else - http_status_exit(500); - - if($format === 'xml') { - header('Content-type: text/xml'); - echo replace_macros(get_markup_template('poco_xml.tpl'),array_xmlify(array('$response' => $ret))); - http_status_exit(500); - } - if($format === 'json') { - header('Content-type: application/json'); - echo json_encode($ret); - killme(); - } - else - http_status_exit(500); + if ($fields_ret['displayName']) { + $entry['displayName'] = $rr['xchan_name']; + } + if ($fields_ret['urls']) { + $entry['urls'] = array(array('value' => $rr['xchan_url'], 'type' => 'profile')); + $network = $rr['xchan_network']; + if ($rr['xchan_addr']) { + $entry['urls'][] = array('value' => 'acct:' . $rr['xchan_addr'], 'type' => $network); + } + } + if ($fields_ret['preferredUsername']) { + $entry['preferredUsername'] = substr($rr['xchan_addr'], 0, strpos($rr['xchan_addr'], '@')); + } + if ($fields_ret['photos']) { + $entry['photos'] = array(array('value' => $rr['xchan_photo_l'], 'mimetype' => $rr['xchan_photo_mimetype'], 'type' => 'profile')); + } + $ret['entry'][] = $entry; + } + } else { + $ret['entry'][] = []; + } + } else { + http_status_exit(500); + } + if ($format === 'xml') { + header('Content-type: text/xml'); + echo replace_macros(get_markup_template('poco_xml.tpl'), array_xmlify(array('$response' => $ret))); + http_status_exit(500); + } + if ($format === 'json') { + header('Content-type: application/json'); + echo json_encode($ret); + killme(); + } else { + http_status_exit(500); + } } diff --git a/include/statistics_fns.php b/include/statistics_fns.php index f3ae6a71e..363d08268 100644 --- a/include/statistics_fns.php +++ b/include/statistics_fns.php @@ -1,58 +1,66 @@ %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('6 MONTH') - ); - if($r) { - set_config('system','channels_active_halfyear_stat',count($r)); - } - else { - set_config('system','channels_active_halfyear_stat','0'); - } + db_utcnow(), + db_quoteinterval('6 MONTH') + ); + if ($r) { + set_config('system', 'channels_active_halfyear_stat', count($r)); + } else { + set_config('system', 'channels_active_halfyear_stat', '0'); + } } -function update_channels_active_monthly_stat() { - $r = q("select channel_id from channel left join account on account_id = channel_account_id +function update_channels_active_monthly_stat() +{ + $r = q( + "select channel_id from channel left join account on account_id = channel_account_id where account_flags = 0 and channel_active > %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('1 MONTH') - ); - if($r) { - set_config('system','channels_active_monthly_stat',count($r)); - } - else { - set_config('system','channels_active_monthly_stat','0'); - } + db_utcnow(), + db_quoteinterval('1 MONTH') + ); + if ($r) { + set_config('system', 'channels_active_monthly_stat', count($r)); + } else { + set_config('system', 'channels_active_monthly_stat', '0'); + } } -function update_local_posts_stat() { - $posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 and id = parent"); - if (is_array($posts)) { - $local_posts_stat = intval($posts[0]["local_posts"]); - set_config('system','local_posts_stat',$local_posts_stat); - } else { - set_config('system','local_posts_stat',0); - } +function update_local_posts_stat() +{ + $posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 and id = parent"); + if (is_array($posts)) { + $local_posts_stat = intval($posts[0]["local_posts"]); + set_config('system', 'local_posts_stat', $local_posts_stat); + } else { + set_config('system', 'local_posts_stat', 0); + } } -function update_local_comments_stat() { - $posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 and id != parent"); - if (!is_array($posts)) +function update_local_comments_stat() +{ + $posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 and id != parent"); + if (!is_array($posts)) { $local_posts = 0; - else + } else { $local_posts = $posts[0]["local_posts"]; + } - set_config('system','local_comments_stat', $local_posts); -} \ No newline at end of file + set_config('system', 'local_comments_stat', $local_posts); +} diff --git a/include/system_unavailable.php b/include/system_unavailable.php index 9b92eae36..8c99a33ef 100644 --- a/include/system_unavailable.php +++ b/include/system_unavailable.php @@ -2,9 +2,10 @@ require_once("include/network.php"); -function system_down() { - http_status(503, 'Service Unavailable'); - echo <<< EOT +function system_down() +{ + http_status(503, 'Service Unavailable'); + echo <<< EOT System Unavailable @@ -13,5 +14,4 @@ Apologies but this site is unavailable at the moment. Please try again later. EOT; - -} \ No newline at end of file +} diff --git a/include/taxonomy.php b/include/taxonomy.php index 230e4cfcb..549e021a2 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -1,689 +1,755 @@ -','[',']'),array('%3c','%3e','%5b','%5d'),$s); +function file_tag_encode($s) +{ + return str_replace(array('<','>','[',']'), array('%3c','%3e','%5b','%5d'), $s); } -function file_tag_decode($s) { - return str_replace(array('%3c','%3e','%5b','%5d'),array('<','>','[',']'),$s); +function file_tag_decode($s) +{ + return str_replace(array('%3c','%3e','%5b','%5d'), array('<','>','[',']'), $s); } -function file_tag_file_query($table,$s,$type = 'file') { +function file_tag_file_query($table, $s, $type = 'file') +{ - if($type == 'file') - $termtype = TERM_FILE; - else - $termtype = TERM_CATEGORY; + if ($type == 'file') { + $termtype = TERM_FILE; + } else { + $termtype = TERM_CATEGORY; + } - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", - intval($termtype), - protect_sprintf(dbesc($s)) - ); + return sprintf( + " AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + intval($termtype), + protect_sprintf(dbesc($s)) + ); } -function term_query($table,$s,$type = TERM_UNKNOWN, $type2 = '') { +function term_query($table, $s, $type = TERM_UNKNOWN, $type2 = '') +{ - if($type2) { - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype in (%d, %d) and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", - intval($type), - intval($type2), - protect_sprintf(dbesc($s)) - ); - } - else { - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", - intval($type), - protect_sprintf(dbesc($s)) - ); - } + if ($type2) { + return sprintf( + " AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype in (%d, %d) and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + intval($type), + intval($type2), + protect_sprintf(dbesc($s)) + ); + } else { + return sprintf( + " AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + intval($type), + protect_sprintf(dbesc($s)) + ); + } } -function term_item_parent_query($uid,$table,$s,$type = TERM_UNKNOWN, $type2 = '') { +function term_item_parent_query($uid, $table, $s, $type = TERM_UNKNOWN, $type2 = '') +{ - // Allow asterisks for wildcard search - // In theory this means '%' will also do a wildcard search, but there appear to be multiple escape - // issues with '%' in term names and trying to fix this with '\\%' here did not help. - // Ideally I think we want '*' to indicate wildcards and allow '%' literally in names, but that is being - // left for another developer on another day. + // Allow asterisks for wildcard search + // In theory this means '%' will also do a wildcard search, but there appear to be multiple escape + // issues with '%' in term names and trying to fix this with '\\%' here did not help. + // Ideally I think we want '*' to indicate wildcards and allow '%' literally in names, but that is being + // left for another developer on another day. - $s = str_replace('*','%',$s); + $s = str_replace('*', '%', $s); - if($type2) { - $r = q("select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", - intval($type), - intval($type2), - dbesc($s), - intval($uid), - dbesc(ACTIVITY_UPDATE) - ); - } - else { - $r = q("select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", - intval($type), - dbesc($s), - intval($uid), - dbesc(ACTIVITY_UPDATE) - ); - } + if ($type2) { + $r = q( + "select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", + intval($type), + intval($type2), + dbesc($s), + intval($uid), + dbesc(ACTIVITY_UPDATE) + ); + } else { + $r = q( + "select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", + intval($type), + dbesc($s), + intval($uid), + dbesc(ACTIVITY_UPDATE) + ); + } - if($r) { - $str = ''; - foreach($r as $rv) { - if($str) - $str .= ','; - $str .= intval($rv['parent']); - } - return " AND " . (($table) ? dbesc($table) . '.' : '') . "id in ( $str ) "; - } - return " AND false "; + if ($r) { + $str = ''; + foreach ($r as $rv) { + if ($str) { + $str .= ','; + } + $str .= intval($rv['parent']); + } + return " AND " . (($table) ? dbesc($table) . '.' : '') . "id in ( $str ) "; + } + return " AND false "; } -function store_item_tag($uid,$iid,$otype,$type,$term,$url = '') { - if(! $term) - return false; +function store_item_tag($uid, $iid, $otype, $type, $term, $url = '') +{ + if (! $term) { + return false; + } - $r = q("select * from term + $r = q( + "select * from term where uid = %d and oid = %d and otype = %d and ttype = %d and term = '%s' and url = '%s' ", - intval($uid), - intval($iid), - intval($otype), - intval($type), - dbesc($term), - dbesc($url) - ); - if($r) - return false; + intval($uid), + intval($iid), + intval($otype), + intval($type), + dbesc($term), + dbesc($url) + ); + if ($r) { + return false; + } - $r = q("insert into term (uid, oid, otype, ttype, term, url) + $r = q( + "insert into term (uid, oid, otype, ttype, term, url) values( %d, %d, %d, %d, '%s', '%s') ", - intval($uid), - intval($iid), - intval($otype), - intval($type), - dbesc($term), - dbesc($url) - ); + intval($uid), + intval($iid), + intval($otype), + intval($type), + dbesc($term), + dbesc($url) + ); - return $r; + return $r; } -function get_terms_oftype($arr,$type) { - $ret = []; - if(! (is_array($arr) && count($arr))) - return $ret; +function get_terms_oftype($arr, $type) +{ + $ret = []; + if (! (is_array($arr) && count($arr))) { + return $ret; + } - if(! is_array($type)) - $type = array($type); + if (! is_array($type)) { + $type = array($type); + } - foreach($type as $t) - foreach($arr as $x) - if($x['ttype'] == $t) - $ret[] = $x; + foreach ($type as $t) { + foreach ($arr as $x) { + if ($x['ttype'] == $t) { + $ret[] = $x; + } + } + } - return $ret; + return $ret; } -function format_term_for_display($term) { - $s = ''; - if(($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) - $s .= '#'; - elseif($term['ttype'] == TERM_FORUM) - $s .= '!'; - elseif($term['ttype'] == TERM_MENTION) - $s .= '@'; - else - return $s; +function format_term_for_display($term) +{ + $s = ''; + if (($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) { + $s .= '#'; + } elseif ($term['ttype'] == TERM_FORUM) { + $s .= '!'; + } elseif ($term['ttype'] == TERM_MENTION) { + $s .= '@'; + } else { + return $s; + } - if($term['url']) - $s .= '' . htmlspecialchars($term['term'], ENT_COMPAT,'UTF-8') . ''; - else - $s .= htmlspecialchars($term['term'], ENT_COMPAT,'UTF-8'); - return $s; + if ($term['url']) { + $s .= '' . htmlspecialchars($term['term'], ENT_COMPAT, 'UTF-8') . ''; + } else { + $s .= htmlspecialchars($term['term'], ENT_COMPAT, 'UTF-8'); + } + return $s; } // Tag cloud functions - need to be adpated to this database format -function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) { +function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) +{ - require_once('include/security.php'); + require_once('include/security.php'); - if(! perm_is_allowed($uid,get_observer_hash(),'view_stream')) - return []; - - - $item_normal = item_normal(); - $sql_options = item_permissions_sql($uid); - $count = intval($count); - - if($flags) { - if($flags === 'wall') - $sql_options .= " and item_wall = 1 "; - } - - if($authors) { - if(! is_array($authors)) - $authors = array($authors); - - $sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") "; - } - - if($owner) { - $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; - } - - // Fetch tags - $r = q("select term, count(term) as total from term left join item on term.oid = item.id - where term.uid = %d and term.ttype = %d - and otype = %d and item_type = %d - $sql_options $item_normal - group by term order by total desc %s", - intval($uid), - intval($type), - intval(TERM_OBJ_POST), - intval($restrict), - ((intval($count)) ? "limit $count" : '') - ); - - - if(! $r) - return []; - - return Zotlabs\Text\Tagadelic::calc($r); - -} - - - -function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) { - - require_once('include/security.php'); - - if(! perm_is_allowed($uid,get_observer_hash(),'view_pages')) - return []; - - $item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 - and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' "; - - $sql_options = item_permissions_sql($uid); - $count = intval($count); - - if($flags) { - if($flags === 'wall') - $sql_options .= " and item_wall = 1 "; - } - - if($authors) { - if(! is_array($authors)) - $authors = array($authors); - - $sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") "; - } - - if($owner) { - $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; - } - - - // Fetch tags - - $r = q("select term, count(term) as total from term left join item on term.oid = item.id - where term.uid = %d and term.ttype = %d - and otype = %d and item_type = %d - $sql_options $item_normal - group by term order by total desc %s", - intval($uid), - intval($type), - intval(TERM_OBJ_POST), - intval(ITEM_TYPE_CARD), - ((intval($count)) ? "limit $count" : '') - ); - - if(! $r) - return []; - - return Zotlabs\Text\Tagadelic::calc($r); - -} - -function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) { - - require_once('include/security.php'); - - if(! perm_is_allowed($uid,get_observer_hash(),'view_pages')) - return []; - - - $item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 - and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' "; - - $sql_options = item_permissions_sql($uid); - $count = intval($count); - - if($flags) { - if($flags === 'wall') - $sql_options .= " and item_wall = 1 "; - } - - if($authors) { - if(! is_array($authors)) - $authors = array($authors); - - $sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") "; - } - - if($owner) { - $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; - } - - - // Fetch tags - $r = q("select term, count(term) as total from term left join item on term.oid = item.id - where term.uid = %d and term.ttype = %d - and otype = %d and item_type = %d - $sql_options $item_normal - group by term order by total desc %s", - intval($uid), - intval($type), - intval(TERM_OBJ_POST), - intval(ITEM_TYPE_ARTICLE), - ((intval($count)) ? "limit $count" : '') - ); - - if(! $r) - return []; - - return Zotlabs\Text\Tagadelic::calc($r); - -} - - - - -function pubtagblock($mode,$limit,$recent = 0,$safemode = 1, $type = TERM_HASHTAG) { - $o = ''; - - $r = pub_tagadelic($mode,$limit,$recent,$safemode,$type); - - $link = z_root() . '/pubstream'; - - if($r) { - $o = '

                    ' . (($recent) ? t('Popular Tags') : t('Tags')) . '

                    '; - foreach($r as $rr) { - $o .= '#'.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } - - return $o; -} - -function pub_tagadelic($mode,$limit,$recent,$safemode,$type) { - - - $item_normal = item_normal(); - $count = intval($limit); - - if (intval($mode) === PUBLIC_STREAM_SITE) { - $uids = " and item_private = 0 and item_wall = 1 "; - } - else { - $sys = get_sys_channel(); - $uids = " and item.uid = " . intval($sys['channel_id']) . " "; - $sql_extra = " and item_private = 0 "; + if (! perm_is_allowed($uid, get_observer_hash(), 'view_stream')) { + return []; } - if ($recent) { - $sql_extra .= " and item.created > '" . datetime_convert('UTC','UTC', 'now - ' . intval($recent) . ' days ') . "' "; - } - if ($safemode) { - $unsafetags = get_config('system','unsafepubtags', [ 'boobs', 'bot', 'rss', 'girl','girls', 'nsfw', 'sexy', 'nude' ]); - if($unsafetags) { - $sql_extra .= " and not term.term in ( " . stringify_array($unsafetags,true) . ") "; - } - } - + $item_normal = item_normal(); + $sql_options = item_permissions_sql($uid); + $count = intval($count); - // Fetch tags - $r = q("select term, count(term) as total from term left join item on term.oid = item.id + if ($flags) { + if ($flags === 'wall') { + $sql_options .= " and item_wall = 1 "; + } + } + + if ($authors) { + if (! is_array($authors)) { + $authors = array($authors); + } + + $sql_options .= " and author_xchan in (" . stringify_array($authors, true) . ") "; + } + + if ($owner) { + $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; + } + + // Fetch tags + $r = q( + "select term, count(term) as total from term left join item on term.oid = item.id + where term.uid = %d and term.ttype = %d + and otype = %d and item_type = %d + $sql_options $item_normal + group by term order by total desc %s", + intval($uid), + intval($type), + intval(TERM_OBJ_POST), + intval($restrict), + ((intval($count)) ? "limit $count" : '') + ); + + + if (! $r) { + return []; + } + + return Zotlabs\Text\Tagadelic::calc($r); +} + + + +function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) +{ + + require_once('include/security.php'); + + if (! perm_is_allowed($uid, get_observer_hash(), 'view_pages')) { + return []; + } + + $item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 + and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' "; + + $sql_options = item_permissions_sql($uid); + $count = intval($count); + + if ($flags) { + if ($flags === 'wall') { + $sql_options .= " and item_wall = 1 "; + } + } + + if ($authors) { + if (! is_array($authors)) { + $authors = array($authors); + } + + $sql_options .= " and author_xchan in (" . stringify_array($authors, true) . ") "; + } + + if ($owner) { + $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; + } + + + // Fetch tags + + $r = q( + "select term, count(term) as total from term left join item on term.oid = item.id + where term.uid = %d and term.ttype = %d + and otype = %d and item_type = %d + $sql_options $item_normal + group by term order by total desc %s", + intval($uid), + intval($type), + intval(TERM_OBJ_POST), + intval(ITEM_TYPE_CARD), + ((intval($count)) ? "limit $count" : '') + ); + + if (! $r) { + return []; + } + + return Zotlabs\Text\Tagadelic::calc($r); +} + +function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) +{ + + require_once('include/security.php'); + + if (! perm_is_allowed($uid, get_observer_hash(), 'view_pages')) { + return []; + } + + + $item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 + and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' "; + + $sql_options = item_permissions_sql($uid); + $count = intval($count); + + if ($flags) { + if ($flags === 'wall') { + $sql_options .= " and item_wall = 1 "; + } + } + + if ($authors) { + if (! is_array($authors)) { + $authors = array($authors); + } + + $sql_options .= " and author_xchan in (" . stringify_array($authors, true) . ") "; + } + + if ($owner) { + $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' "; + } + + + // Fetch tags + $r = q( + "select term, count(term) as total from term left join item on term.oid = item.id + where term.uid = %d and term.ttype = %d + and otype = %d and item_type = %d + $sql_options $item_normal + group by term order by total desc %s", + intval($uid), + intval($type), + intval(TERM_OBJ_POST), + intval(ITEM_TYPE_ARTICLE), + ((intval($count)) ? "limit $count" : '') + ); + + if (! $r) { + return []; + } + + return Zotlabs\Text\Tagadelic::calc($r); +} + + + + +function pubtagblock($mode, $limit, $recent = 0, $safemode = 1, $type = TERM_HASHTAG) +{ + $o = ''; + + $r = pub_tagadelic($mode, $limit, $recent, $safemode, $type); + + $link = z_root() . '/pubstream'; + + if ($r) { + $o = '

                    ' . (($recent) ? t('Popular Tags') : t('Tags')) . '

                    '; + foreach ($r as $rr) { + $o .= '#' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } + + return $o; +} + +function pub_tagadelic($mode, $limit, $recent, $safemode, $type) +{ + + + $item_normal = item_normal(); + $count = intval($limit); + + if (intval($mode) === PUBLIC_STREAM_SITE) { + $uids = " and item_private = 0 and item_wall = 1 "; + } else { + $sys = get_sys_channel(); + $uids = " and item.uid = " . intval($sys['channel_id']) . " "; + $sql_extra = " and item_private = 0 "; + } + + if ($recent) { + $sql_extra .= " and item.created > '" . datetime_convert('UTC', 'UTC', 'now - ' . intval($recent) . ' days ') . "' "; + } + + if ($safemode) { + $unsafetags = get_config('system', 'unsafepubtags', [ 'boobs', 'bot', 'rss', 'girl','girls', 'nsfw', 'sexy', 'nude' ]); + if ($unsafetags) { + $sql_extra .= " and not term.term in ( " . stringify_array($unsafetags, true) . ") "; + } + } + + + // Fetch tags + $r = q( + "select term, count(term) as total from term left join item on term.oid = item.id where term.ttype = %d and otype = %d and item_type = %d $sql_extra $uids $item_normal group by term order by total desc %s", - intval($type), - intval(TERM_OBJ_POST), - intval(ITEM_TYPE_POST), - ((intval($count)) ? "limit $count" : '') - ); - - if (! $r) { - return []; - } - return Zotlabs\Text\Tagadelic::calc($r); + intval($type), + intval(TERM_OBJ_POST), + intval(ITEM_TYPE_POST), + ((intval($count)) ? "limit $count" : '') + ); + if (! $r) { + return []; + } + return Zotlabs\Text\Tagadelic::calc($r); } -function dir_tagadelic($count = 0, $hub = '', $type = 0, $safe = '') { +function dir_tagadelic($count = 0, $hub = '', $type = 0, $safe = '') +{ - $count = intval($count); + $count = intval($count); - $sql_extra = EMPTY_STR; + $sql_extra = EMPTY_STR; - if($type) { - return []; - } + if ($type) { + return []; + } - if($hub) { - $r = q("select xtag_term as term, count(xtag_term) as total from xtag + if ($hub) { + $r = q( + "select xtag_term as term, count(xtag_term) as total from xtag left join hubloc on xtag_hash = hubloc_hash where xtag_flags = 0 and xtag_hash in (select hubloc_hash from hubloc where hubloc_host = '%s' ) $sql_extra group by xtag_term order by total desc %s", - dbesc($hub), - ((intval($count)) ? "limit $count" : '') - ); - } - else { - $r = q("select xtag_term as term, count(xtag_term) as total from xtag left join xchan on xtag_hash = xchan_hash where xtag_flags = 0 + dbesc($hub), + ((intval($count)) ? "limit $count" : '') + ); + } else { + $r = q( + "select xtag_term as term, count(xtag_term) as total from xtag left join xchan on xtag_hash = xchan_hash where xtag_flags = 0 $sql_extra $safe group by xtag_term order by total desc %s", - ((intval($count)) ? "limit $count" : '') - ); - } - if(! $r) - return []; + ((intval($count)) ? "limit $count" : '') + ); + } + if (! $r) { + return []; + } - return Zotlabs\Text\Tagadelic::calc($r); + return Zotlabs\Text\Tagadelic::calc($r); } -function app_tagblock($link,$count = 0) { - $o = ''; +function app_tagblock($link, $count = 0) +{ + $o = ''; - $r = app_tagadelic($count); + $r = app_tagadelic($count); - if($r) { - $o = '

                    ' . t('Categories') . '

                    '; - foreach($r as $rr) { - $o .= ''.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $o = '

                    ' . t('Categories') . '

                    '; + foreach ($r as $rr) { + $o .= '' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } - return $o; + return $o; } -function app_tagadelic($count = 0) { +function app_tagadelic($count = 0) +{ - if(! local_channel()) - return ''; + if (! local_channel()) { + return ''; + } - $count = intval($count); + $count = intval($count); - // Fetch tags - $r = q("select term, count(term) as total from term left join app on term.uid = app_channel where term.uid = %d + // Fetch tags + $r = q( + "select term, count(term) as total from term left join app on term.uid = app_channel where term.uid = %d and term.otype = %d group by term order by total desc %s", - intval(local_channel()), - intval(TERM_OBJ_APP), - ((intval($count)) ? "limit $count" : '') - ); + intval(local_channel()), + intval(TERM_OBJ_APP), + ((intval($count)) ? "limit $count" : '') + ); - if(! $r) - return []; - - return Zotlabs\Text\Tagadelic::calc($r); + if (! $r) { + return []; + } + return Zotlabs\Text\Tagadelic::calc($r); } -function tagblock($link,$uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_HASHTAG) { - $o = ''; +function tagblock($link, $uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) +{ + $o = ''; - $r = tagadelic($uid,$count,$authors,$owner, $flags,$restrict,$type); + $r = tagadelic($uid, $count, $authors, $owner, $flags, $restrict, $type); - if($r) { - $o = '

                    ' . t('Tags') . '

                    '; - foreach($r as $rr) { - $o .= '#'.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $o = '

                    ' . t('Tags') . '

                    '; + foreach ($r as $rr) { + $o .= '#' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } - return $o; + return $o; } -function wtagblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_HASHTAG) { - $o = ''; +function wtagblock($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) +{ + $o = ''; - $r = tagadelic($uid,$count,$authors,$owner, $flags,$restrict,$type); + $r = tagadelic($uid, $count, $authors, $owner, $flags, $restrict, $type); - if($r) { - $c = q("select channel_address from channel where channel_id = %d limit 1", - intval($uid) - ); - - $o = '

                    ' . t('Tags') . '

                    '; - foreach($r as $rr) { - $o .= '#'.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $c = q( + "select channel_address from channel where channel_id = %d limit 1", + intval($uid) + ); - return $o; + $o = '

                    ' . t('Tags') . '

                    '; + foreach ($r as $rr) { + $o .= '#' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } + + return $o; } -function catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_CATEGORY) { - $o = ''; +function catblock($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) +{ + $o = ''; - if(! Apps::system_app_installed($uid,'Categories')) { - return $o; - } + if (! Apps::system_app_installed($uid, 'Categories')) { + return $o; + } - $r = tagadelic($uid,$count,$authors,$owner,$flags,$restrict,$type); + $r = tagadelic($uid, $count, $authors, $owner, $flags, $restrict, $type); - if($r) { - $c = q("select channel_address from channel where channel_id = %d limit 1", - intval($uid) - ); - - $o = '

                    ' . t('Categories') . '

                    '; - foreach($r as $rr) { - $o .= ''.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $c = q( + "select channel_address from channel where channel_id = %d limit 1", + intval($uid) + ); - return $o; + $o = '

                    ' . t('Categories') . '

                    '; + foreach ($r as $rr) { + $o .= '' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } + + return $o; } -function card_catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_CATEGORY) { - $o = ''; +function card_catblock($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) +{ + $o = ''; - $r = card_tagadelic($uid,$count,$authors,$owner,$flags,$restrict,$type); + $r = card_tagadelic($uid, $count, $authors, $owner, $flags, $restrict, $type); - if($r) { - $c = q("select channel_address from channel where channel_id = %d limit 1", - intval($uid) - ); - - $o = '

                    ' . t('Categories') . '

                    '; - foreach($r as $rr) { - $o .= ''.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $c = q( + "select channel_address from channel where channel_id = %d limit 1", + intval($uid) + ); - return $o; + $o = '

                    ' . t('Categories') . '

                    '; + foreach ($r as $rr) { + $o .= '' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } + + return $o; } -function article_catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_CATEGORY) { - $o = ''; +function article_catblock($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) +{ + $o = ''; - $r = article_tagadelic($uid,$count,$authors,$owner,$flags,$restrict,$type); + $r = article_tagadelic($uid, $count, $authors, $owner, $flags, $restrict, $type); - if($r) { - $c = q("select channel_address from channel where channel_id = %d limit 1", - intval($uid) - ); - - $o = '

                    ' . t('Categories') . '

                    '; - foreach($r as $rr) { - $o .= ''.$rr[0].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $c = q( + "select channel_address from channel where channel_id = %d limit 1", + intval($uid) + ); - return $o; + $o = '

                    ' . t('Categories') . '

                    '; + foreach ($r as $rr) { + $o .= '' . $rr[0] . ' ' . "\r\n"; + } + $o .= '
                    '; + } + + return $o; } -function dir_tagblock($link,$r) { - $o = ''; +function dir_tagblock($link, $r) +{ + $o = ''; - $observer = get_observer_hash(); + $observer = get_observer_hash(); - if(! $r) - $r = App::$data['directory_keywords']; + if (! $r) { + $r = App::$data['directory_keywords']; + } - if($r) { - $o = '

                    ' . t('Keywords') . '

                    '; - foreach($r as $rr) { - $o .= ''.$rr['term'].' ' . "\r\n"; - } - $o .= '
                    '; - } + if ($r) { + $o = '

                    ' . t('Keywords') . '

                    '; + foreach ($r as $rr) { + $o .= '' . $rr['term'] . ' ' . "\r\n"; + } + $o .= '
                    '; + } - return $o; + return $o; } - /** - * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" - * We use the first person form when creating an activity, but the third person for use in activities - * FIXME: There is no accounting for verb gender for languages where this is significant. We may eventually - * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module. - */ + /** + * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" + * We use the first person form when creating an activity, but the third person for use in activities + * FIXME: There is no accounting for verb gender for languages where this is significant. We may eventually + * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module. + */ -function obj_verbs() { - $verbs = array( - 'has' => array( t('have'), t('has')), - 'wants' => array( t('want'), t('wants')), - 'likes' => array( t('like'), t('likes')), - 'dislikes' => array( t('dislike'), t('dislikes')), - ); +function obj_verbs() +{ + $verbs = array( + 'has' => array( t('have'), t('has')), + 'wants' => array( t('want'), t('wants')), + 'likes' => array( t('like'), t('likes')), + 'dislikes' => array( t('dislike'), t('dislikes')), + ); - $arr = array('verbs' => $verbs); - call_hooks('obj_verbs', $arr); + $arr = array('verbs' => $verbs); + call_hooks('obj_verbs', $arr); - return $arr['verbs']; + return $arr['verbs']; } -function obj_verb_selector($current = '') { - $verbs = obj_verbs(); - $o = ''; +function obj_verb_selector($current = '') +{ + $verbs = obj_verbs(); + $o = ''; - return $o; + return $o; } -function get_things($profile_hash,$uid) { +function get_things($profile_hash, $uid) +{ - $sql_extra = (($profile_hash) ? " and obj_page = '" . $profile_hash . "' " : ''); + $sql_extra = (($profile_hash) ? " and obj_page = '" . $profile_hash . "' " : ''); - $r = q("select * from obj where obj_channel = %d and obj_type = %d $sql_extra order by obj_verb, obj_term", - intval($uid), - intval(TERM_OBJ_THING) - ); + $r = q( + "select * from obj where obj_channel = %d and obj_type = %d $sql_extra order by obj_verb, obj_term", + intval($uid), + intval(TERM_OBJ_THING) + ); - $things = $sorted_things = null; + $things = $sorted_things = null; - $profile_hashes = []; + $profile_hashes = []; - if($r) { + if ($r) { + // if no profile_hash was specified (display on profile page mode), match each of the things to a profile name + // (list all my things mode). This is harder than it sounds. - // if no profile_hash was specified (display on profile page mode), match each of the things to a profile name - // (list all my things mode). This is harder than it sounds. + foreach ($r as $rr) { + $rr['profile_name'] = ''; + if (! in_array($rr['obj_obj'], $profile_hashes)) { + $profile_hashes[] = $rr['obj_obj']; + } + } + if (! $profile_hash) { + $exp = stringify_array($profile_hashes, true); + $p = q("select profile_guid as hash, profile_name as name from profile where profile_guid in ( $exp ) "); + if ($p) { + foreach ($r as $rr) { + foreach ($p as $pp) { + if ($rr['obj_page'] == $pp['hash']) { + $rr['profile_name'] == $pp['name']; + } + } + } + } + } - foreach($r as $rr) { - $rr['profile_name'] = ''; - if(! in_array($rr['obj_obj'],$profile_hashes)) - $profile_hashes[] = $rr['obj_obj']; - } - if(! $profile_hash) { - $exp = stringify_array($profile_hashes,true); - $p = q("select profile_guid as hash, profile_name as name from profile where profile_guid in ( $exp ) "); - if($p) { - foreach($r as $rr) { - foreach($p as $pp) { - if($rr['obj_page'] == $pp['hash']) { - $rr['profile_name'] == $pp['name']; - } - } - } - } - } + $things = []; - $things = []; + // Use the system obj_verbs array as a sort key, since we don't really + // want an alphabetic sort. To change the order, use a plugin to + // alter the obj_verbs() array or alter it in code. Unknown verbs come + // after the known ones - in no particular order. - // Use the system obj_verbs array as a sort key, since we don't really - // want an alphabetic sort. To change the order, use a plugin to - // alter the obj_verbs() array or alter it in code. Unknown verbs come - // after the known ones - in no particular order. - - $v = obj_verbs(); - foreach($v as $k => $foo) - $things[$k] = null; - foreach($r as $rr) { - - $l = q("select xchan_name, xchan_photo_s, xchan_url from likes left join xchan on liker = xchan_hash where + $v = obj_verbs(); + foreach ($v as $k => $foo) { + $things[$k] = null; + } + foreach ($r as $rr) { + $l = q( + "select xchan_name, xchan_photo_s, xchan_url from likes left join xchan on liker = xchan_hash where target_type = '%s' and target_id = '%s' and channel_id = %d", - dbesc(ACTIVITY_OBJ_THING), - dbesc($rr['obj_obj']), - intval($uid) - ); + dbesc(ACTIVITY_OBJ_THING), + dbesc($rr['obj_obj']), + intval($uid) + ); - for($x = 0; $x < count($l); $x ++) { - $l[$x]['xchan_url'] = zid($l[$x]['xchan_url']); - $l[$x]['xchan_photo_s'] = zid($l[$x]['xchan_photo_s']); - } - if(! $things[$rr['obj_verb']]) - $things[$rr['obj_verb']] = []; + for ($x = 0; $x < count($l); $x++) { + $l[$x]['xchan_url'] = zid($l[$x]['xchan_url']); + $l[$x]['xchan_photo_s'] = zid($l[$x]['xchan_photo_s']); + } + if (! $things[$rr['obj_verb']]) { + $things[$rr['obj_verb']] = []; + } - $things[$rr['obj_verb']][] = array('term' => $rr['obj_term'],'url' => $rr['obj_url'],'img' => $rr['obj_imgurl'], 'editurl' => z_root() . '/thing/' . $rr['obj_obj'], 'profile' => $rr['profile_name'],'term_hash' => $rr['obj_obj'], 'likes' => $l,'like_count' => count($l),'like_label' => tt('Like','Likes',count($l),'noun')); - } - $sorted_things = []; - if($things) { - foreach($things as $k => $v) { - if(is_array($things[$k])) { - $sorted_things[$k] = $v; - } - } - } - } + $things[$rr['obj_verb']][] = array('term' => $rr['obj_term'],'url' => $rr['obj_url'],'img' => $rr['obj_imgurl'], 'editurl' => z_root() . '/thing/' . $rr['obj_obj'], 'profile' => $rr['profile_name'],'term_hash' => $rr['obj_obj'], 'likes' => $l,'like_count' => count($l),'like_label' => tt('Like', 'Likes', count($l), 'noun')); + } + $sorted_things = []; + if ($things) { + foreach ($things as $k => $v) { + if (is_array($things[$k])) { + $sorted_things[$k] = $v; + } + } + } + } //logger('things: ' . print_r($sorted_things,true)); - return $sorted_things; + return $sorted_things; } diff --git a/include/text.php b/include/text.php index af3a5d398..cfa16fb57 100644 --- a/include/text.php +++ b/include/text.php @@ -1,8 +1,9 @@ $s, - 'params' => $r - ]; +function replace_macros($s, $r) +{ + $arr = [ + 'template' => $s, + 'params' => $r + ]; - /** - * @hooks replace_macros - * * \e string \b template - * * \e array \b params - */ + /** + * @hooks replace_macros + * * \e string \b template + * * \e array \b params + */ - call_hooks('replace_macros', $arr); + call_hooks('replace_macros', $arr); - $t = App::template_engine(); + $t = App::template_engine(); - try { - $output = $t->replace_macros($arr['template'], $arr['params']); - } - catch (Exception $e) { - btlogger("Unable to render template: " . $e->getMessage()); - $output = "

                    ERROR: there was an error creating the output.

                    "; - } + try { + $output = $t->replace_macros($arr['template'], $arr['params']); + } catch (Exception $e) { + btlogger("Unable to render template: " . $e->getMessage()); + $output = "

                    ERROR: there was an error creating the output.

                    "; + } - return $output; + return $output; } /** @@ -67,15 +66,16 @@ function replace_macros($s, $r) { */ -define('RANDOM_STRING_HEX', 0x00 ); -define('RANDOM_STRING_TEXT', 0x01 ); +define('RANDOM_STRING_HEX', 0x00); +define('RANDOM_STRING_TEXT', 0x01); -function random_string($size = 64, $type = RANDOM_STRING_HEX) { - // generate a bit of entropy and run it through the whirlpool - $s = hash('whirlpool', (string) rand() . uniqid(rand(),true) . (string) rand(),(($type == RANDOM_STRING_TEXT) ? true : false)); - $s = (($type == RANDOM_STRING_TEXT) ? str_replace("\n","",base64url_encode($s,true)) : $s); +function random_string($size = 64, $type = RANDOM_STRING_HEX) +{ + // generate a bit of entropy and run it through the whirlpool + $s = hash('whirlpool', (string) rand() . uniqid(rand(), true) . (string) rand(), (($type == RANDOM_STRING_TEXT) ? true : false)); + $s = (($type == RANDOM_STRING_TEXT) ? str_replace("\n", "", base64url_encode($s, true)) : $s); - return(substr($s, 0, $size)); + return(substr($s, 0, $size)); } /** @@ -86,8 +86,9 @@ function random_string($size = 64, $type = RANDOM_STRING_HEX) { * @return string Filtered string * */ -function notags($string) { - return(str_replace(array("<",">"), array('[',']'), $string)); +function notags($string) +{ + return(str_replace(array("<",">"), array('[',']'), $string)); } @@ -99,40 +100,46 @@ function notags($string) { * * @return string */ -function escape_tags($string) { - return(htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false)); +function escape_tags($string) +{ + return(htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false)); } -function z_input_filter($s, $type = 'text/bbcode', $allow_code = false) { +function z_input_filter($s, $type = 'text/bbcode', $allow_code = false) +{ - if (in_array($type, [ 'text/bbcode', 'text/x-multicode' ])) { - return (multicode_purify($s)); - } - if($type == 'text/plain') - return escape_tags($s); - if($type == 'application/x-pdl') - return escape_tags($s); + if (in_array($type, [ 'text/bbcode', 'text/x-multicode' ])) { + return (multicode_purify($s)); + } + if ($type == 'text/plain') { + return escape_tags($s); + } + if ($type == 'application/x-pdl') { + return escape_tags($s); + } - if(App::$is_sys) { - return $s; - } + if (App::$is_sys) { + return $s; + } - if($allow_code) { - if($type === 'text/markdown') - return htmlspecialchars($s,ENT_QUOTES); - return $s; - } + if ($allow_code) { + if ($type === 'text/markdown') { + return htmlspecialchars($s, ENT_QUOTES); + } + return $s; + } - if($type === 'text/markdown') { - $x = new MarkdownSoap($s); - return $x->clean(); - } + if ($type === 'text/markdown') { + $x = new MarkdownSoap($s); + return $x->clean(); + } - if($type === 'text/html') - return purify_html($s); + if ($type === 'text/html') { + return purify_html($s); + } - return escape_tags($s); + return escape_tags($s); } @@ -148,177 +155,178 @@ function z_input_filter($s, $type = 'text/bbcode', $allow_code = false) { * @param bool $allow_position allow CSS position * @return string standards compliant filtered HTML */ -function purify_html($s, $opts = []) { +function purify_html($s, $opts = []) +{ - $config = HTMLPurifier_Config::createDefault(); - $config->set('Cache.DefinitionImpl', null); - $config->set('Attr.EnableID', true); + $config = HTMLPurifier_Config::createDefault(); + $config->set('Cache.DefinitionImpl', null); + $config->set('Attr.EnableID', true); - // disable Unicode version of RTL over-ride - $s = str_replace([ '‮', '‮', html_entity_decode('‮', ENT_QUOTES,'UTF-8') ],[ '','','' ],$s); + // disable Unicode version of RTL over-ride + $s = str_replace([ '‮', '‮', html_entity_decode('‮', ENT_QUOTES, 'UTF-8') ], [ '','','' ], $s); - // This will escape invalid tags in the output instead of removing. - // This is necessary for mixed format (text+bbcode+html+markdown) messages or - // some angle brackets in plaintext may get stripped if they look like an HTML tag - - if (in_array('escape',$opts)) { - $config->set('Core.EscapeInvalidChildren', true); - $config->set('Core.EscapeInvalidTags', true); - } + // This will escape invalid tags in the output instead of removing. + // This is necessary for mixed format (text+bbcode+html+markdown) messages or + // some angle brackets in plaintext may get stripped if they look like an HTML tag - // If enabled, target=blank attributes are added to all links. - //$config->set('HTML.TargetBlank', true); - //$config->set('Attr.AllowedFrameTargets', ['_blank', '_self', '_parent', '_top']); - // restore old behavior of HTMLPurifier < 4.8, only used when targets allowed at all - // do not add rel="noreferrer" to all links with target attributes - //$config->set('HTML.TargetNoreferrer', false); - // do not add noopener rel attributes to links which have a target attribute associated with them - //$config->set('HTML.TargetNoopener', false); + if (in_array('escape', $opts)) { + $config->set('Core.EscapeInvalidChildren', true); + $config->set('Core.EscapeInvalidTags', true); + } - //Allow some custom data- attributes used by built-in libs. - //In this way members which do not have allowcode set can still use the built-in js libs in webpages to some extent. + // If enabled, target=blank attributes are added to all links. + //$config->set('HTML.TargetBlank', true); + //$config->set('Attr.AllowedFrameTargets', ['_blank', '_self', '_parent', '_top']); + // restore old behavior of HTMLPurifier < 4.8, only used when targets allowed at all + // do not add rel="noreferrer" to all links with target attributes + //$config->set('HTML.TargetNoreferrer', false); + // do not add noopener rel attributes to links which have a target attribute associated with them + //$config->set('HTML.TargetNoopener', false); - $def = $config->getHTMLDefinition(true); + //Allow some custom data- attributes used by built-in libs. + //In this way members which do not have allowcode set can still use the built-in js libs in webpages to some extent. - //data- attributes used by the foundation library + $def = $config->getHTMLDefinition(true); - // f6 navigation + //data- attributes used by the foundation library - //dropdown menu - $def->info_global_attr['data-dropdown-menu'] = new HTMLPurifier_AttrDef_Text(); - //drilldown menu - $def->info_global_attr['data-drilldown'] = new HTMLPurifier_AttrDef_Text(); - //accordion menu - $def->info_global_attr['data-accordion-menu'] = new HTMLPurifier_AttrDef_Text(); - //responsive navigation - $def->info_global_attr['data-responsive-menu'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-responsive-toggle'] = new HTMLPurifier_AttrDef_Text(); - //magellan - $def->info_global_attr['data-magellan'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-magellan-target'] = new HTMLPurifier_AttrDef_Text(); + // f6 navigation - // f6 containers + //dropdown menu + $def->info_global_attr['data-dropdown-menu'] = new HTMLPurifier_AttrDef_Text(); + //drilldown menu + $def->info_global_attr['data-drilldown'] = new HTMLPurifier_AttrDef_Text(); + //accordion menu + $def->info_global_attr['data-accordion-menu'] = new HTMLPurifier_AttrDef_Text(); + //responsive navigation + $def->info_global_attr['data-responsive-menu'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-responsive-toggle'] = new HTMLPurifier_AttrDef_Text(); + //magellan + $def->info_global_attr['data-magellan'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-magellan-target'] = new HTMLPurifier_AttrDef_Text(); - //accordion - $def->info_global_attr['data-accordion'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-accordion-item'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-tab-content'] = new HTMLPurifier_AttrDef_Text(); - //dropdown - $def->info_global_attr['data-dropdown'] = new HTMLPurifier_AttrDef_Text(); - //off-canvas - $def->info_global_attr['data-off-canvas-wrapper'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-off-canvas'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-off-canvas-content'] = new HTMLPurifier_AttrDef_Text(); - //reveal - $def->info_global_attr['data-reveal'] = new HTMLPurifier_AttrDef_Text(); - //tabs - $def->info_global_attr['data-tabs'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-tabs-content'] = new HTMLPurifier_AttrDef_Text(); + // f6 containers - // f6 media + //accordion + $def->info_global_attr['data-accordion'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-accordion-item'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-tab-content'] = new HTMLPurifier_AttrDef_Text(); + //dropdown + $def->info_global_attr['data-dropdown'] = new HTMLPurifier_AttrDef_Text(); + //off-canvas + $def->info_global_attr['data-off-canvas-wrapper'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-off-canvas'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-off-canvas-content'] = new HTMLPurifier_AttrDef_Text(); + //reveal + $def->info_global_attr['data-reveal'] = new HTMLPurifier_AttrDef_Text(); + //tabs + $def->info_global_attr['data-tabs'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-tabs-content'] = new HTMLPurifier_AttrDef_Text(); - //orbit - $def->info_global_attr['data-orbit'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-slide'] = new HTMLPurifier_AttrDef_Text(); - //tooltip - $def->info_global_attr['data-tooltip'] = new HTMLPurifier_AttrDef_Text(); + // f6 media - // f6 plugins + //orbit + $def->info_global_attr['data-orbit'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-slide'] = new HTMLPurifier_AttrDef_Text(); + //tooltip + $def->info_global_attr['data-tooltip'] = new HTMLPurifier_AttrDef_Text(); - //abide - the use is pointless since we can't do anything with forms + // f6 plugins - //equalizer - $def->info_global_attr['data-equalizer'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-equalizer-watch'] = new HTMLPurifier_AttrDef_Text(); + //abide - the use is pointless since we can't do anything with forms - //interchange - potentially dangerous since it can load content + //equalizer + $def->info_global_attr['data-equalizer'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-equalizer-watch'] = new HTMLPurifier_AttrDef_Text(); - //toggler - $def->info_global_attr['data-toggler'] = new HTMLPurifier_AttrDef_Text(); + //interchange - potentially dangerous since it can load content - //sticky - $def->info_global_attr['data-sticky'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-sticky-container'] = new HTMLPurifier_AttrDef_Text(); + //toggler + $def->info_global_attr['data-toggler'] = new HTMLPurifier_AttrDef_Text(); - // f6 common + //sticky + $def->info_global_attr['data-sticky'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-sticky-container'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-options'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-toggle'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-close'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-open'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-position'] = new HTMLPurifier_AttrDef_Text(); + // f6 common + + $def->info_global_attr['data-options'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-toggle'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-close'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-open'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-position'] = new HTMLPurifier_AttrDef_Text(); - //data- attributes used by the bootstrap library - $def->info_global_attr['data-dismiss'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-target'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-toggle'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-backdrop'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-keyboard'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-show'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-spy'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-offset'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-animation'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-container'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-delay'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-placement'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-title'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-content'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-parent'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-ride'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-slide-to'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-slide'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-interval'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-pause'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-wrap'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-offset-top'] = new HTMLPurifier_AttrDef_Text(); - $def->info_global_attr['data-offset-bottom'] = new HTMLPurifier_AttrDef_Text(); + //data- attributes used by the bootstrap library + $def->info_global_attr['data-dismiss'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-target'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-toggle'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-backdrop'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-keyboard'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-show'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-spy'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-offset'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-animation'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-container'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-delay'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-placement'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-title'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-content'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-parent'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-ride'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-slide-to'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-slide'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-interval'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-pause'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-wrap'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-offset-top'] = new HTMLPurifier_AttrDef_Text(); + $def->info_global_attr['data-offset-bottom'] = new HTMLPurifier_AttrDef_Text(); - //some html5 elements - //Block - $def->addElement('section', 'Block', 'Flow', 'Common'); - $def->addElement('nav', 'Block', 'Flow', 'Common'); - $def->addElement('article', 'Block', 'Flow', 'Common'); - $def->addElement('aside', 'Block', 'Flow', 'Common'); - $def->addElement('header', 'Block', 'Flow', 'Common'); - $def->addElement('footer', 'Block', 'Flow', 'Common'); - //Inline - $def->addElement('button', 'Inline', 'Inline', 'Common'); - $def->addElement('mark', 'Inline', 'Inline', 'Common'); + //some html5 elements + //Block + $def->addElement('section', 'Block', 'Flow', 'Common'); + $def->addElement('nav', 'Block', 'Flow', 'Common'); + $def->addElement('article', 'Block', 'Flow', 'Common'); + $def->addElement('aside', 'Block', 'Flow', 'Common'); + $def->addElement('header', 'Block', 'Flow', 'Common'); + $def->addElement('footer', 'Block', 'Flow', 'Common'); + //Inline + $def->addElement('button', 'Inline', 'Inline', 'Common'); + $def->addElement('mark', 'Inline', 'Inline', 'Common'); - if(in_array('allow_position', $opts)) { - $cssDefinition = $config->getCSSDefinition(); + if (in_array('allow_position', $opts)) { + $cssDefinition = $config->getCSSDefinition(); - $cssDefinition->info['position'] = new HTMLPurifier_AttrDef_Enum(array('absolute', 'fixed', 'relative', 'static', 'inherit'), false); + $cssDefinition->info['position'] = new HTMLPurifier_AttrDef_Enum(array('absolute', 'fixed', 'relative', 'static', 'inherit'), false); - $cssDefinition->info['left'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); + $cssDefinition->info['left'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); - $cssDefinition->info['right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); + $cssDefinition->info['right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); - $cssDefinition->info['top'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); + $cssDefinition->info['top'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); - $cssDefinition->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); - } + $cssDefinition->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); + } - $purifier = new HTMLPurifier($config); + $purifier = new HTMLPurifier($config); - return $purifier->purify($s); + return $purifier->purify($s); } @@ -334,76 +342,82 @@ function purify_html($s, $opts = []) { * @param int $len max length of generated string * @return string Genereated random, but usually pronounceable string */ -function autoname($len) { +function autoname($len) +{ - if ($len <= 0) - return ''; + if ($len <= 0) { + return ''; + } - $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u'); - if (mt_rand(0, 5) == 4) - $vowels[] = 'y'; + $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u'); + if (mt_rand(0, 5) == 4) { + $vowels[] = 'y'; + } - $cons = array( - 'b','bl','br', - 'c','ch','cl','cr', - 'd','dr', - 'f','fl','fr', - 'g','gh','gl','gr', - 'h', - 'j', - 'k','kh','kl','kr', - 'l', - 'm', - 'n', - 'p','ph','pl','pr', - 'qu', - 'r','rh', - 's','sc','sh','sm','sp','st', - 't','th','tr', - 'v', - 'w','wh', - 'x', - 'z','zh' - ); + $cons = array( + 'b','bl','br', + 'c','ch','cl','cr', + 'd','dr', + 'f','fl','fr', + 'g','gh','gl','gr', + 'h', + 'j', + 'k','kh','kl','kr', + 'l', + 'm', + 'n', + 'p','ph','pl','pr', + 'qu', + 'r','rh', + 's','sc','sh','sm','sp','st', + 't','th','tr', + 'v', + 'w','wh', + 'x', + 'z','zh' + ); - $midcons = array('ck','ct','gn','ld','lf','lm','lt','mb','mm', 'mn','mp', - 'nd','ng','nk','nt','rn','rp','rt'); + $midcons = array('ck','ct','gn','ld','lf','lm','lt','mb','mm', 'mn','mp', + 'nd','ng','nk','nt','rn','rp','rt'); - // avoid these consonant pairs at the end of the string - $noend = array('bl', 'br', 'cl','cr','dr','fl','fr','gl','gr', - 'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh'); + // avoid these consonant pairs at the end of the string + $noend = array('bl', 'br', 'cl','cr','dr','fl','fr','gl','gr', + 'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh'); - $start = mt_rand(0, 2); - if ($start == 0) - $table = $vowels; - else - $table = $cons; + $start = mt_rand(0, 2); + if ($start == 0) { + $table = $vowels; + } else { + $table = $cons; + } - $word = ''; + $word = ''; - for ($x = 0; $x < $len; $x ++) { - $r = mt_rand(0, count($table) - 1); - $word .= $table[$r]; + for ($x = 0; $x < $len; $x++) { + $r = mt_rand(0, count($table) - 1); + $word .= $table[$r]; - if ($table == $vowels) - $table = array_merge($cons, $midcons); - else - $table = $vowels; - } + if ($table == $vowels) { + $table = array_merge($cons, $midcons); + } else { + $table = $vowels; + } + } - $word = substr($word, 0, $len); + $word = substr($word, 0, $len); - foreach ($noend as $noe) { - if ((strlen($word) > 2) && (substr($word, -2) == $noe)) { - $word = substr($word, 0, -1); - break; - } - } - // avoid the letter 'q' as it does not make a very good word ending - if (substr($word, -1) == 'q') - $word = substr($word, 0, -1); + foreach ($noend as $noe) { + if ((strlen($word) > 2) && (substr($word, -2) == $noe)) { + $word = substr($word, 0, -1); + break; + } + } + // avoid the letter 'q' as it does not make a very good word ending + if (substr($word, -1) == 'q') { + $word = substr($word, 0, -1); + } - return $word; + return $word; } @@ -413,50 +427,50 @@ function autoname($len) { * @param string $str * @return string Escaped text. */ -function xmlify($str) { - $buffer = ''; +function xmlify($str) +{ + $buffer = ''; - if(is_array($str)) { + if (is_array($str)) { + // allow to fall through so we ge a PHP error, as the log statement will + // probably get lost in the noise unless we're specifically looking for it. - // allow to fall through so we ge a PHP error, as the log statement will - // probably get lost in the noise unless we're specifically looking for it. + btlogger('xmlify called with array: ' . print_r($str, true), LOGGER_NORMAL, LOG_WARNING); + } - btlogger('xmlify called with array: ' . print_r($str,true), LOGGER_NORMAL, LOG_WARNING); - } + $len = mb_strlen($str); + for ($x = 0; $x < $len; $x++) { + $char = mb_substr($str, $x, 1); - $len = mb_strlen($str); - for($x = 0; $x < $len; $x ++) { - $char = mb_substr($str,$x,1); + switch ($char) { + case "\r": + break; + case "&": + $buffer .= '&'; + break; + case "'": + $buffer .= '''; + break; + case "\"": + $buffer .= '"'; + break; + case '<': + $buffer .= '<'; + break; + case '>': + $buffer .= '>'; + break; + case "\n": + $buffer .= "\n"; + break; + default: + $buffer .= $char; + break; + } + } + $buffer = trim($buffer); - switch( $char ) { - case "\r" : - break; - case "&" : - $buffer .= '&'; - break; - case "'" : - $buffer .= '''; - break; - case "\"" : - $buffer .= '"'; - break; - case '<' : - $buffer .= '<'; - break; - case '>' : - $buffer .= '>'; - break; - case "\n" : - $buffer .= "\n"; - break; - default : - $buffer .= $char; - break; - } - } - $buffer = trim($buffer); - - return($buffer); + return($buffer); } /** @@ -468,11 +482,12 @@ function xmlify($str) { * * @return string */ -function unxmlify($s) { - $ret = str_replace('&', '&', $s); - $ret = str_replace(array('<', '>', '"', '''), array('<', '>', '"', "'"), $ret); +function unxmlify($s) +{ + $ret = str_replace('&', '&', $s); + $ret = str_replace(array('<', '>', '"', '''), array('<', '>', '"', "'"), $ret); - return $ret; + return $ret; } /** @@ -489,85 +504,92 @@ function unxmlify($s) { * * @param App &$a */ -function paginate(&$a) { - $o = ''; - $stripped = preg_replace('/(&page=[0-9]*)/','',App::$query_string); +function paginate(&$a) +{ + $o = ''; + $stripped = preg_replace('/(&page=[0-9]*)/', '', App::$query_string); -// $stripped = preg_replace('/&zid=(.*?)([\?&]|$)/ism','',$stripped); +// $stripped = preg_replace('/&zid=(.*?)([\?&]|$)/ism','',$stripped); - $stripped = str_replace('q=','',$stripped); - $stripped = trim($stripped,'/'); - $pagenum = App::$pager['page']; - $url = z_root() . '/' . $stripped; + $stripped = str_replace('q=', '', $stripped); + $stripped = trim($stripped, '/'); + $pagenum = App::$pager['page']; + $url = z_root() . '/' . $stripped; - if(App::$pager['total'] > App::$pager['itemspage']) { - $o .= '
                    '; - if(App::$pager['page'] != 1) - $o .= ''."' . t('prev') . ' '; + if (App::$pager['total'] > App::$pager['itemspage']) { + $o .= '
                    '; + if (App::$pager['page'] != 1) { + $o .= '' . "' . t('prev') . ' '; + } - $o .= "" . t('first') . " "; + $o .= "" . t('first') . " "; - $numpages = App::$pager['total'] / App::$pager['itemspage']; + $numpages = App::$pager['total'] / App::$pager['itemspage']; - $numstart = 1; - $numstop = $numpages; + $numstart = 1; + $numstop = $numpages; - if($numpages > 14) { - $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); - $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); - } + if ($numpages > 14) { + $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); + $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); + } - for($i = $numstart; $i <= $numstop; $i++){ - if($i == App::$pager['page']) - $o .= ''.(($i < 10) ? ' '.$i : $i); - else - $o .= "".(($i < 10) ? ' '.$i : $i).""; - $o .= ' '; - } + for ($i = $numstart; $i <= $numstop; $i++) { + if ($i == App::$pager['page']) { + $o .= '' . (($i < 10) ? ' ' . $i : $i); + } else { + $o .= "" . (($i < 10) ? ' ' . $i : $i) . ""; + } + $o .= ' '; + } - if((App::$pager['total'] % App::$pager['itemspage']) != 0) { - if($i == App::$pager['page']) - $o .= ''.(($i < 10) ? ' '.$i : $i); - else - $o .= "".(($i < 10) ? ' '.$i : $i).""; - $o .= ' '; - } + if ((App::$pager['total'] % App::$pager['itemspage']) != 0) { + if ($i == App::$pager['page']) { + $o .= '' . (($i < 10) ? ' ' . $i : $i); + } else { + $o .= "" . (($i < 10) ? ' ' . $i : $i) . ""; + } + $o .= ' '; + } - $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages); - $o .= "" . t('last') . " "; + $lastpage = (($numpages > intval($numpages)) ? intval($numpages) + 1 : $numpages); + $o .= "" . t('last') . " "; - if((App::$pager['total'] - (App::$pager['itemspage'] * App::$pager['page'])) > 0) - $o .= ''."' . t('next') . ''; - $o .= '
                    '."\r\n"; - } + if ((App::$pager['total'] - (App::$pager['itemspage'] * App::$pager['page'])) > 0) { + $o .= '' . "' . t('next') . ''; + } + $o .= '
                    ' . "\r\n"; + } - return $o; + return $o; } -function alt_pager($i, $more = '', $less = '') { +function alt_pager($i, $more = '', $less = '') +{ - if(! $more) - $more = t('older'); - if(! $less) - $less = t('newer'); + if (! $more) { + $more = t('older'); + } + if (! $less) { + $less = t('newer'); + } - $stripped = preg_replace('/(&page=[0-9]*)/','',App::$query_string); - $stripped = str_replace('q=','',$stripped); - $stripped = trim($stripped,'/'); - //$pagenum = App::$pager['page']; - $url = z_root() . '/' . $stripped; - - return replace_macros(get_markup_template('alt_pager.tpl'), array( - '$has_less' => ((App::$pager['page'] > 1) ? true : false), - '$has_more' => (($i > 0 && $i >= App::$pager['itemspage']) ? true : false), - '$less' => $less, - '$more' => $more, - '$url' => $url, - '$prevpage' => App::$pager['page'] - 1, - '$nextpage' => App::$pager['page'] + 1, - )); + $stripped = preg_replace('/(&page=[0-9]*)/', '', App::$query_string); + $stripped = str_replace('q=', '', $stripped); + $stripped = trim($stripped, '/'); + //$pagenum = App::$pager['page']; + $url = z_root() . '/' . $stripped; + return replace_macros(get_markup_template('alt_pager.tpl'), array( + '$has_less' => ((App::$pager['page'] > 1) ? true : false), + '$has_more' => (($i > 0 && $i >= App::$pager['itemspage']) ? true : false), + '$less' => $less, + '$more' => $more, + '$url' => $url, + '$prevpage' => App::$pager['page'] - 1, + '$nextpage' => App::$pager['page'] + 1, + )); } @@ -578,17 +600,18 @@ function alt_pager($i, $more = '', $less = '') { * * @return string a unique id */ -function item_message_id() { +function item_message_id() +{ - try { - $hash = Uuid::uuid4()->toString(); - } catch (UnsatisfiedDependencyException $e) { - $hash = random_string(48); - } + try { + $hash = Uuid::uuid4()->toString(); + } catch (UnsatisfiedDependencyException $e) { + $hash = random_string(48); + } - $mid = z_root() . '/item/' . $hash; + $mid = z_root() . '/item/' . $hash; - return $mid; + return $mid; } /** @@ -598,32 +621,34 @@ function item_message_id() { * * @return string a unique hash */ -function photo_new_resource() { +function photo_new_resource() +{ - try { - $hash = Uuid::uuid4()->toString(); - } catch (UnsatisfiedDependencyException $e) { - $hash = random_string(48); - } + try { + $hash = Uuid::uuid4()->toString(); + } catch (UnsatisfiedDependencyException $e) { + $hash = random_string(48); + } - return $hash; + return $hash; } // provide psuedo random token (string) consisting entirely of US-ASCII letters/numbers // and with possibly variable length -function new_token($minlen = 36,$maxlen = 48) { +function new_token($minlen = 36, $maxlen = 48) +{ - $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; - $str = EMPTY_STR; + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; + $str = EMPTY_STR; - $len = (($minlen === $maxlen) ? $minlen : mt_rand($minlen,$maxlen)); + $len = (($minlen === $maxlen) ? $minlen : mt_rand($minlen, $maxlen)); - for($a = 0; $a < $len; $a ++) { - $str .= $chars[mt_rand(0,62)]; - } - return $str; + for ($a = 0; $a < $len; $a++) { + $str .= $chars[mt_rand(0, 62)]; + } + return $str; } /** @@ -631,15 +656,16 @@ function new_token($minlen = 36,$maxlen = 48) { * * @return string */ -function new_uuid() { +function new_uuid() +{ - try { - $hash = Uuid::uuid4()->toString(); - } catch (UnsatisfiedDependencyException $e) { - $hash = random_string(48); - } + try { + $hash = Uuid::uuid4()->toString(); + } catch (UnsatisfiedDependencyException $e) { + $hash = random_string(48); + } - return $hash; + return $hash; } /** @@ -659,14 +685,16 @@ function new_uuid() { * @param string $s attribute you are looking for * @return bool true if found */ -function attribute_contains($attr, $s) { - // remove quotes - $attr = str_replace([ '"',"'" ],['',''],$attr); - $a = explode(' ', $attr); - if($a && in_array($s, $a)) - return true; +function attribute_contains($attr, $s) +{ + // remove quotes + $attr = str_replace([ '"',"'" ], ['',''], $attr); + $a = explode(' ', $attr); + if ($a && in_array($s, $a)) { + return true; + } - return false; + return false; } /** @@ -686,42 +714,47 @@ function attribute_contains($attr, $s) { * @param int $level A log level * @param int $priority - compatible with syslog */ -function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) { +function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) +{ - if(App::$module == 'setup' && is_writable('install.log')) { - $debugging = true; - $logfile = 'install.log'; - $loglevel = LOGGER_ALL; - } - else { - $debugging = get_config('system', 'debugging'); - $loglevel = intval(get_config('system', 'loglevel')); - $logfile = get_config('system', 'logfile'); - } + if (App::$module == 'setup' && is_writable('install.log')) { + $debugging = true; + $logfile = 'install.log'; + $loglevel = LOGGER_ALL; + } else { + $debugging = get_config('system', 'debugging'); + $loglevel = intval(get_config('system', 'loglevel')); + $logfile = get_config('system', 'logfile'); + } - if((! $debugging) || (! $logfile) || ($level > $loglevel)) - return; + if ((! $debugging) || (! $logfile) || ($level > $loglevel)) { + return; + } - $where = ''; + $where = ''; - $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); - $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; - $s = datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . logid() . ':' . $where . $msg . PHP_EOL; - $pluginfo = array('filename' => $logfile, 'loglevel' => $level, 'message' => $s,'priority' => $priority, 'logged' => false); + $s = datetime_convert('UTC', 'UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . logid() . ':' . $where . $msg . PHP_EOL; + $pluginfo = array('filename' => $logfile, 'loglevel' => $level, 'message' => $s,'priority' => $priority, 'logged' => false); - if(! (App::$module == 'setup')) - call_hooks('logger',$pluginfo); + if (! (App::$module == 'setup')) { + call_hooks('logger', $pluginfo); + } - if(! $pluginfo['logged']) - @file_put_contents($pluginfo['filename'], $pluginfo['message'], FILE_APPEND); + if (! $pluginfo['logged']) { + @file_put_contents($pluginfo['filename'], $pluginfo['message'], FILE_APPEND); + } } -function logid() { - $x = session_id(); - if(! $x) - $x = getmypid(); - return substr(hash('whirlpool',$x),0,10); +function logid() +{ + $x = session_id(); + if (! $x) { + $x = getmypid(); + } + return substr(hash('whirlpool', $x), 0, 10); } /** @@ -732,48 +765,52 @@ function logid() { * @param int $level A log level * @param int $priority - compatible with syslog */ -function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) { +function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) +{ - if(! defined('BTLOGGER_DEBUG_FILE')) - define('BTLOGGER_DEBUG_FILE','btlogger.out'); + if (! defined('BTLOGGER_DEBUG_FILE')) { + define('BTLOGGER_DEBUG_FILE', 'btlogger.out'); + } - logger($msg, $level, $priority); + logger($msg, $level, $priority); - if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) { - $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); - $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; - $s = datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . logid() . ':' . $where . $msg . PHP_EOL; - @file_put_contents(BTLOGGER_DEBUG_FILE, $s, FILE_APPEND); - } + if (file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) { + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; + $s = datetime_convert('UTC', 'UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . logid() . ':' . $where . $msg . PHP_EOL; + @file_put_contents(BTLOGGER_DEBUG_FILE, $s, FILE_APPEND); + } - $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - if($stack) { - for($x = 1; $x < count($stack); $x ++) { - $s = 'stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()'; - logger($s,$level, $priority); + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + if ($stack) { + for ($x = 1; $x < count($stack); $x++) { + $s = 'stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()'; + logger($s, $level, $priority); - if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) { - @file_put_contents(BTLOGGER_DEBUG_FILE, $s . PHP_EOL, FILE_APPEND); - } - } - } + if (file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) { + @file_put_contents(BTLOGGER_DEBUG_FILE, $s . PHP_EOL, FILE_APPEND); + } + } + } } -function log_priority_str($priority) { - $parr = array( - LOG_EMERG => 'LOG_EMERG', - LOG_ALERT => 'LOG_ALERT', - LOG_CRIT => 'LOG_CRIT', - LOG_ERR => 'LOG_ERR', - LOG_WARNING => 'LOG_WARNING', - LOG_NOTICE => 'LOG_NOTICE', - LOG_INFO => 'LOG_INFO', - LOG_DEBUG => 'LOG_DEBUG' - ); +function log_priority_str($priority) +{ + $parr = array( + LOG_EMERG => 'LOG_EMERG', + LOG_ALERT => 'LOG_ALERT', + LOG_CRIT => 'LOG_CRIT', + LOG_ERR => 'LOG_ERR', + LOG_WARNING => 'LOG_WARNING', + LOG_NOTICE => 'LOG_NOTICE', + LOG_INFO => 'LOG_INFO', + LOG_DEBUG => 'LOG_DEBUG' + ); - if($parr[$priority]) - return $parr[$priority]; - return 'LOG_UNDEFINED'; + if ($parr[$priority]) { + return $parr[$priority]; + } + return 'LOG_UNDEFINED'; } /** @@ -791,49 +828,56 @@ function log_priority_str($priority) { * @param string $msg Message to log * @param int $level A log level. */ -function dlogger($msg, $level = 0) { +function dlogger($msg, $level = 0) +{ - // turn off logger in install mode + // turn off logger in install mode - if(App::$module == 'setup') - return; + if (App::$module == 'setup') { + return; + } - $debugging = get_config('system','debugging'); - $loglevel = intval(get_config('system','loglevel')); - $logfile = get_config('system','dlogfile'); + $debugging = get_config('system', 'debugging'); + $loglevel = intval(get_config('system', 'loglevel')); + $logfile = get_config('system', 'dlogfile'); - if((! $debugging) || (! $logfile) || ($level > $loglevel)) - return; + if ((! $debugging) || (! $logfile) || ($level > $loglevel)) { + return; + } - $where = ''; + $where = ''; - $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); - $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; - @file_put_contents($logfile, datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . logid() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND); + @file_put_contents($logfile, datetime_convert('UTC', 'UTC', 'now', ATOM_TIME) . ':' . logid() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND); } -function profiler($t1,$t2,$label) { - if(file_exists('profiler.out') && $t1 && t2) - @file_put_contents('profiler.out', sprintf('%01.4f %s',$t2 - $t1,$label) . PHP_EOL, FILE_APPEND); +function profiler($t1, $t2, $label) +{ + if (file_exists('profiler.out') && $t1 && t2) { + @file_put_contents('profiler.out', sprintf('%01.4f %s', $t2 - $t1, $label) . PHP_EOL, FILE_APPEND); + } } -function activity_match($haystack,$needle) { +function activity_match($haystack, $needle) +{ - if(! is_array($needle)) - $needle = [ $needle ]; + if (! is_array($needle)) { + $needle = [ $needle ]; + } - if($needle) { - foreach($needle as $n) { - if(($haystack === $n) || (strtolower(basename($n)) === strtolower(basename($haystack)))) { - return true; - } - } - } - return false; + if ($needle) { + foreach ($needle as $n) { + if (($haystack === $n) || (strtolower(basename($n)) === strtolower(basename($haystack)))) { + return true; + } + } + } + return false; } /** @@ -847,97 +891,105 @@ function activity_match($haystack,$needle) { * @param string $s * @return Returns array of tags found, or empty array. */ -function get_tags($s) { - $ret = []; - $match = []; +function get_tags($s) +{ + $ret = []; + $match = []; - // ignore anything in a code or svg block or HTML tag + // ignore anything in a code or svg block or HTML tag - $s = preg_replace('/\[code(.*?)\](.*?)\[\/code\]/sm','',$s); - $s = preg_replace('/\<(.*?)\>/sm','',$s); - $s = preg_replace('/\[svg(.*?)\](.*?)\[\/svg\]/sm','',$s); + $s = preg_replace('/\[code(.*?)\](.*?)\[\/code\]/sm', '', $s); + $s = preg_replace('/\<(.*?)\>/sm', '', $s); + $s = preg_replace('/\[svg(.*?)\](.*?)\[\/svg\]/sm', '', $s); - // ignore anything in [style= ] - $s = preg_replace('/\[style=(.*?)\]/sm','',$s); + // ignore anything in [style= ] + $s = preg_replace('/\[style=(.*?)\]/sm', '', $s); - // ignore anything in [color= ], because it may contain color codes which are mistaken for tags - $s = preg_replace('/\[color=(.*?)\]/sm','',$s); + // ignore anything in [color= ], because it may contain color codes which are mistaken for tags + $s = preg_replace('/\[color=(.*?)\]/sm', '', $s); - // skip anchors in URL - $s = preg_replace('/\[url=(.*?)\]/sm','',$s); + // skip anchors in URL + $s = preg_replace('/\[url=(.*?)\]/sm', '', $s); - // match any double quoted tags + // match any double quoted tags - if(preg_match_all('/([@#\!]\"\;.*?\"\;)/',$s,$match)) { - foreach($match[1] as $mtch) { - $ret[] = $mtch; - } - } + if (preg_match_all('/([@#\!]\"\;.*?\"\;)/', $s, $match)) { + foreach ($match[1] as $mtch) { + $ret[] = $mtch; + } + } - // match any unescaped double quoted tags (rare) - - if(preg_match_all('/([@#\!]\".*?\")/',$s,$match)) { - foreach($match[1] as $mtch) { - $ret[] = $mtch; - } - } + // match any unescaped double quoted tags (rare) - // match bracket mentions + if (preg_match_all('/([@#\!]\".*?\")/', $s, $match)) { + foreach ($match[1] as $mtch) { + $ret[] = $mtch; + } + } - if(preg_match_all('/([@!]\!?\{.*?\})/',$s,$match)) { - foreach($match[1] as $mtch) { - $ret[] = $mtch; - } - } + // match bracket mentions - // Pull out single word tags. These can be @nickname, @first_last - // and #hash tags. + if (preg_match_all('/([@!]\!?\{.*?\})/', $s, $match)) { + foreach ($match[1] as $mtch) { + $ret[] = $mtch; + } + } - if(preg_match_all('/(? $a['total']) ? 1 : (-1)); +function total_sort($a, $b) +{ + if ($a['total'] == $b['total']) { + return 0; + } + return(($b['total'] > $a['total']) ? 1 : (-1)); } @@ -947,56 +999,63 @@ function total_sort($a,$b) { * @param string $s * @return string */ -function qp($s) { - return str_replace ("%", "=", rawurlencode($s)); +function qp($s) +{ + return str_replace("%", "=", rawurlencode($s)); } -function chanlink_hash($s) { - return z_root() . '/chanview?f=&hash=' . urlencode($s); +function chanlink_hash($s) +{ + return z_root() . '/chanview?f=&hash=' . urlencode($s); } -function chanlink_url($s) { - return z_root() . '/chanview?f=&url=' . urlencode($s); +function chanlink_url($s) +{ + return z_root() . '/chanview?f=&url=' . urlencode($s); } -function chanlink_cid($d) { - return z_root() . '/chanview?f=&cid=' . intval($d); +function chanlink_cid($d) +{ + return z_root() . '/chanview?f=&cid=' . intval($d); } -function magiclink_url($observer,$myaddr,$url) { - return (($observer) - ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($url) . '&addr=' . $myaddr - : $url - ); +function magiclink_url($observer, $myaddr, $url) +{ + return (($observer) + ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($url) . '&addr=' . $myaddr + : $url + ); } -function search($s,$id='search-box',$url='/search',$save = false) { +function search($s, $id = 'search-box', $url = '/search', $save = false) +{ - return replace_macros(get_markup_template('searchbox.tpl'),array( - '$s' => $s, - '$id' => $id, - '$action_url' => z_root() . $url, - '$search_label' => t('Search'), - '$save_label' => t('Save'), - '$savedsearch' => feature_enabled(local_channel(),'savedsearch') - )); + return replace_macros(get_markup_template('searchbox.tpl'), array( + '$s' => $s, + '$id' => $id, + '$action_url' => z_root() . $url, + '$search_label' => t('Search'), + '$save_label' => t('Save'), + '$savedsearch' => feature_enabled(local_channel(), 'savedsearch') + )); } -function searchbox($s,$id='search-box',$url='/search',$save = false) { - return replace_macros(get_markup_template('searchbox.tpl'),array( - '$s' => $s, - '$id' => $id, - '$action_url' => z_root() . '/' . $url, - '$search_label' => t('Search'), - '$save_label' => t('Save'), - '$savedsearch' => ($save && feature_enabled(local_channel(),'savedsearch')) - )); +function searchbox($s, $id = 'search-box', $url = '/search', $save = false) +{ + return replace_macros(get_markup_template('searchbox.tpl'), array( + '$s' => $s, + '$id' => $id, + '$action_url' => z_root() . '/' . $url, + '$search_label' => t('Search'), + '$save_label' => t('Save'), + '$savedsearch' => ($save && feature_enabled(local_channel(), 'savedsearch')) + )); } /** @@ -1006,15 +1065,16 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) { * @param bool $me (optional) default false * @return string */ -function linkify($s, $me = false) { - $rel = 'nofollow noopener'; - if ($me) { - $rel .= ' me'; - } - $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/u", '$1', $s); - $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$s); +function linkify($s, $me = false) +{ + $rel = 'nofollow noopener'; + if ($me) { + $rel .= ' me'; + } + $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/u", '$1', $s); + $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $s); - return($s); + return($s); } /** @@ -1027,83 +1087,83 @@ function linkify($s, $me = false) { * @param string $s * @returns string */ -function sslify($s, $cache_enable = true) { +function sslify($s, $cache_enable = true) +{ - if (! $cache_enable) { + if (! $cache_enable) { + // we're fetching an old item and we are no longer + // caching photos for it. Remove any existing cached photos. + // Cron_weekly tasks will also remove these, but if the cache + // entry was updated recently they might not get removed for + // another couple of months. - // we're fetching an old item and we are no longer - // caching photos for it. Remove any existing cached photos. - // Cron_weekly tasks will also remove these, but if the cache - // entry was updated recently they might not get removed for - // another couple of months. - - uncache($s); - } + uncache($s); + } - if ((! $cache_enable) || (! intval(get_config('system','cache_images', 1)))) { + if ((! $cache_enable) || (! intval(get_config('system', 'cache_images', 1)))) { + // if caching is prevented for whatever reason, proxy any non-SSL photos - // if caching is prevented for whatever reason, proxy any non-SSL photos + if (strpos(z_root(), 'https:') === false) { + return $s; + } - if (strpos(z_root(),'https:') === false) { - return $s; - } + // we'll only sslify img tags because media files will probably choke. - // we'll only sslify img tags because media files will probably choke. + $pattern = "/\/"; - $pattern = "/\/"; + $matches = null; + $cnt = preg_match_all($pattern, $s, $matches, PREG_SET_ORDER); + if ($cnt) { + foreach ($matches as $match) { + $filename = basename(parse_url($match[2], PHP_URL_PATH)); + $s = str_replace($match[2], z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($match[2]), $s); + } + } + return $s; + } - $matches = null; - $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $match) { - $filename = basename( parse_url($match[2], PHP_URL_PATH) ); - $s = str_replace($match[2],z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($match[2]),$s); - } - } - return $s; - } + $pattern = "/\/ism"; - $pattern = "/\/ism"; - - $matches = null; - $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $match) { - // For access controlled photos using OpenWebAuth, remove any zid attributes. - // This will cache a publicly available image but will not cache a protected one. - $clean = strip_zids(strip_query_param($match[2],'f')); - $cached = Img_cache::check($clean,'cache/img'); - if ($cached) { - // $file = Img_cache::get_filename($clean,'cache/img'); - // @fixme getimagesize and replace height/width/alt in image tag - $s = str_replace($match[2],z_root() . '/ca/' . basename(Img_cache::get_filename($clean,'cache/img')) . '?url=' . urlencode($clean),$s); - } - } - } + $matches = null; + $cnt = preg_match_all($pattern, $s, $matches, PREG_SET_ORDER); + if ($cnt) { + foreach ($matches as $match) { + // For access controlled photos using OpenWebAuth, remove any zid attributes. + // This will cache a publicly available image but will not cache a protected one. + $clean = strip_zids(strip_query_param($match[2], 'f')); + $cached = Img_cache::check($clean, 'cache/img'); + if ($cached) { + // $file = Img_cache::get_filename($clean,'cache/img'); + // @fixme getimagesize and replace height/width/alt in image tag + $s = str_replace($match[2], z_root() . '/ca/' . basename(Img_cache::get_filename($clean, 'cache/img')) . '?url=' . urlencode($clean), $s); + } + } + } - return $s; + return $s; } // clean out the image cache -function uncache($s) { +function uncache($s) +{ - $pattern = "/\/ism"; - - $matches = null; - $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $match) { - // repeat the filename generation procedure we used when creating the cache entry - $clean = strip_zids(strip_query_param($match[2],'f')); - $file = Img_cache::get_filename($clean,'cache/img'); - if (file_exists($file)) { - unlink($file); - } - } - } + $pattern = "/\/ism"; - return $s; + $matches = null; + $cnt = preg_match_all($pattern, $s, $matches, PREG_SET_ORDER); + if ($cnt) { + foreach ($matches as $match) { + // repeat the filename generation procedure we used when creating the cache entry + $clean = strip_zids(strip_query_param($match[2], 'f')); + $file = Img_cache::get_filename($clean, 'cache/img'); + if (file_exists($file)) { + unlink($file); + } + } + } + + return $s; } @@ -1115,29 +1175,30 @@ function uncache($s) { * * \e index is present tense verb * * \e value is array containing past tense verb, translation of present, translation of past */ -function get_poke_verbs() { - if (get_config('system', 'poke_basic')) { - $arr = array( - 'poke' => array('poked', t('poke'), t('poked')), - ); - } else { - $arr = array( - 'poke' => array( 'poked', t('poke'), t('poked')), - 'ping' => array( 'pinged', t('ping'), t('pinged')), - 'prod' => array( 'prodded', t('prod'), t('prodded')), - 'slap' => array( 'slapped', t('slap'), t('slapped')), - 'finger' => array( 'fingered', t('finger'), t('fingered')), - 'rebuff' => array( 'rebuffed', t('rebuff'), t('rebuffed')), - ); +function get_poke_verbs() +{ + if (get_config('system', 'poke_basic')) { + $arr = array( + 'poke' => array('poked', t('poke'), t('poked')), + ); + } else { + $arr = array( + 'poke' => array( 'poked', t('poke'), t('poked')), + 'ping' => array( 'pinged', t('ping'), t('pinged')), + 'prod' => array( 'prodded', t('prod'), t('prodded')), + 'slap' => array( 'slapped', t('slap'), t('slapped')), + 'finger' => array( 'fingered', t('finger'), t('fingered')), + 'rebuff' => array( 'rebuffed', t('rebuff'), t('rebuffed')), + ); - /** - * @hooks poke_verbs - * * \e array associative array with another array as value - */ - call_hooks('poke_verbs', $arr); - } + /** + * @hooks poke_verbs + * * \e array associative array with another array as value + */ + call_hooks('poke_verbs', $arr); + } - return $arr; + return $arr; } /** @@ -1147,39 +1208,40 @@ function get_poke_verbs() { * * \e index is the verb * * \e value is the translated verb */ -function get_mood_verbs() { +function get_mood_verbs() +{ - $arr = [ - 'happy' => t('happy'), - 'sad' => t('sad'), - 'mellow' => t('mellow'), - 'tired' => t('tired'), - 'perky' => t('perky'), - 'angry' => t('angry'), - 'stupefied' => t('stupefied'), - 'puzzled' => t('puzzled'), - 'interested' => t('interested'), - 'bitter' => t('bitter'), - 'cheerful' => t('cheerful'), - 'alive' => t('alive'), - 'annoyed' => t('annoyed'), - 'anxious' => t('anxious'), - 'cranky' => t('cranky'), - 'disturbed' => t('disturbed'), - 'frustrated' => t('frustrated'), - 'depressed' => t('depressed'), - 'motivated' => t('motivated'), - 'relaxed' => t('relaxed'), - 'surprised' => t('surprised'), - ]; + $arr = [ + 'happy' => t('happy'), + 'sad' => t('sad'), + 'mellow' => t('mellow'), + 'tired' => t('tired'), + 'perky' => t('perky'), + 'angry' => t('angry'), + 'stupefied' => t('stupefied'), + 'puzzled' => t('puzzled'), + 'interested' => t('interested'), + 'bitter' => t('bitter'), + 'cheerful' => t('cheerful'), + 'alive' => t('alive'), + 'annoyed' => t('annoyed'), + 'anxious' => t('anxious'), + 'cranky' => t('cranky'), + 'disturbed' => t('disturbed'), + 'frustrated' => t('frustrated'), + 'depressed' => t('depressed'), + 'motivated' => t('motivated'), + 'relaxed' => t('relaxed'), + 'surprised' => t('surprised'), + ]; - /** - * @hooks mood_verbs - * * \e array associative array with mood verbs - */ - call_hooks('mood_verbs', $arr); + /** + * @hooks mood_verbs + * * \e array associative array with mood verbs + */ + call_hooks('mood_verbs', $arr); - return $arr; + return $arr; } /** @@ -1187,85 +1249,87 @@ function get_mood_verbs() { * * @return Returns array with keys 'texts' and 'icons' */ -function list_smilies($default_only = false) { +function list_smilies($default_only = false) +{ - $texts = array( - '<3', - '</3', - ':-)', - ';-)', - ':-(', - ':-P', - ':-p', - ':-"', - ':-"', - ':-x', - ':-X', - ':-D', - '8-|', - '8-O', - ':-O', - '\\o/', - 'o.O', - 'O.o', - 'o_O', - 'O_o', - ":'(", - ":-!", - ":-/", - ":-[", - "8-)", - ':beer', - ':homebrew', - ':coffee', - ':facepalm', - ':like', - ':dislike' - ); + $texts = array( + '<3', + '</3', + ':-)', + ';-)', + ':-(', + ':-P', + ':-p', + ':-"', + ':-"', + ':-x', + ':-X', + ':-D', + '8-|', + '8-O', + ':-O', + '\\o/', + 'o.O', + 'O.o', + 'o_O', + 'O_o', + ":'(", + ":-!", + ":-/", + ":-[", + "8-)", + ':beer', + ':homebrew', + ':coffee', + ':facepalm', + ':like', + ':dislike' + ); - $icons = array( - '<3', - '</3', - ':-)', - ';-)', - ':-(', - ':-P', - ':-p', - ':-\', - ':-\', - ':-x', - ':-X', - ':-D', - '8-|', - '8-O', - ':-O', - '\\o/', - 'o.O', - 'O.o', - 'o_O', - 'O_o', - ':\'(', - ':-!', - ':-/', - ':-[', - '8-)', - ':beer', - ':homebrew', - ':coffee', - ':facepalm', - ':like', - ':dislike' + $icons = array( + '<3', + '</3', + ':-)', + ';-)', + ':-(', + ':-P', + ':-p', + ':-\', + ':-\', + ':-x', + ':-X', + ':-D', + '8-|', + '8-O', + ':-O', + '\\o/', + 'o.O', + 'O.o', + 'o_O', + 'O_o', + ':\'(', + ':-!', + ':-/', + ':-[', + '8-)', + ':beer', + ':homebrew', + ':coffee', + ':facepalm', + ':like', + ':dislike' - ); + ); - $params = array('texts' => $texts, 'icons' => $icons); + $params = array('texts' => $texts, 'icons' => $icons); - if($default_only) - return $params; + if ($default_only) { + return $params; + } - call_hooks('smilie', $params); + call_hooks('smilie', $params); - return $params; + return $params; } /** @@ -1283,33 +1347,37 @@ function list_smilies($default_only = false) { * @param bool $sample (optional) default false * @return string */ -function smilies($s, $sample = false) { +function smilies($s, $sample = false) +{ - if(intval(get_config('system', 'no_smilies')) - || (local_channel() && intval(get_pconfig(local_channel(), 'system', 'no_smilies')))) - return $s; + if ( + intval(get_config('system', 'no_smilies')) + || (local_channel() && intval(get_pconfig(local_channel(), 'system', 'no_smilies'))) + ) { + return $s; + } - $s = preg_replace_callback('{<(pre|code)>.*?}ism', 'smile_shield', $s); - $s = preg_replace_callback('/<[a-z]+ .*?>/ism', 'smile_shield', $s); + $s = preg_replace_callback('{<(pre|code)>.*?}ism', 'smile_shield', $s); + $s = preg_replace_callback('/<[a-z]+ .*?>/ism', 'smile_shield', $s); - $params = list_smilies(); - $params['string'] = $s; + $params = list_smilies(); + $params['string'] = $s; - if ($sample) { - $s = '
                    '; - for ($x = 0; $x < count($params['texts']); $x ++) { - $s .= '
                    ' . $params['texts'][$x] . '
                    ' . $params['icons'][$x] . '
                    '; - } - } else { - $params['string'] = preg_replace_callback('/<(3+)/','preg_heart',$params['string']); - $s = str_replace($params['texts'],$params['icons'],$params['string']); - } + if ($sample) { + $s = '
                    '; + for ($x = 0; $x < count($params['texts']); $x++) { + $s .= '
                    ' . $params['texts'][$x] . '
                    ' . $params['icons'][$x] . '
                    '; + } + } else { + $params['string'] = preg_replace_callback('/<(3+)/', 'preg_heart', $params['string']); + $s = str_replace($params['texts'], $params['icons'], $params['string']); + } - $s = preg_replace_callback('//ism', 'smile_unshield', $s); + $s = preg_replace_callback('//ism', 'smile_unshield', $s); - return $s; + return $s; } /** @@ -1318,12 +1386,14 @@ function smilies($s, $sample = false) { * @param array $m * @return string */ -function smile_shield($m) { - return ''; +function smile_shield($m) +{ + return ''; } -function smile_unshield($m) { - return base64special_decode($m[1]); +function smile_unshield($m) +{ + return base64special_decode($m[1]); } /** @@ -1331,32 +1401,40 @@ function smile_unshield($m) { * * @param array $x */ -function preg_heart($x) { +function preg_heart($x) +{ - if (strlen($x[1]) == 1) - return $x[0]; + if (strlen($x[1]) == 1) { + return $x[0]; + } - $t = ''; - for($cnt = 0; $cnt < strlen($x[1]); $cnt ++) - $t .= '<​3'; + $t = ''; + for ($cnt = 0; $cnt < strlen($x[1]); $cnt++) { + $t .= '<​3'; + } - $r = str_replace($x[0],$t,$x[0]); + $r = str_replace($x[0], $t, $x[0]); - return $r; + return $r; } -function day_translate($s) { - $ret = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'), - array( t('Monday'), t('Tuesday'), t('Wednesday'), t('Thursday'), t('Friday'), t('Saturday'), t('Sunday')), - $s); +function day_translate($s) +{ + $ret = str_replace( + array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'), + array( t('Monday'), t('Tuesday'), t('Wednesday'), t('Thursday'), t('Friday'), t('Saturday'), t('Sunday')), + $s + ); - $ret = str_replace(array('January','February','March','April','May','June','July','August','September','October','November','December'), - array( t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December')), - $ret); + $ret = str_replace( + array('January','February','March','April','May','June','July','August','September','October','November','December'), + array( t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December')), + $ret + ); - return $ret; + return $ret; } /** @@ -1365,10 +1443,11 @@ function day_translate($s) { * @param string $url * @return string */ -function normalise_link($url) { - $ret = str_replace(array('https:', '//www.'), array('http:', '//'), $url); +function normalise_link($url) +{ + $ret = str_replace(array('https:', '//www.'), array('http:', '//'), $url); - return(rtrim($ret, '/')); + return(rtrim($ret, '/')); } /** @@ -1384,127 +1463,134 @@ function normalise_link($url) { * @param string $b * @return true if the URLs match, otherwise false */ -function link_compare($a, $b) { - if (strcasecmp(normalise_link($a), normalise_link($b)) === 0) - return true; +function link_compare($a, $b) +{ + if (strcasecmp(normalise_link($a), normalise_link($b)) === 0) { + return true; + } - return false; + return false; } // Given an item array, convert the body element from bbcode to html and add smilie icons. // If attach is true, also add icons for item attachments -function unobscure(&$item) { - return; +function unobscure(&$item) +{ + return; } -function unobscure_mail(&$item) { - if(array_key_exists('mail_obscured',$item) && intval($item['mail_obscured'])) { - if($item['title']) - $item['title'] = base64url_decode(str_rot47($item['title'])); - if($item['body']) - $item['body'] = base64url_decode(str_rot47($item['body'])); - } +function unobscure_mail(&$item) +{ + if (array_key_exists('mail_obscured', $item) && intval($item['mail_obscured'])) { + if ($item['title']) { + $item['title'] = base64url_decode(str_rot47($item['title'])); + } + if ($item['body']) { + $item['body'] = base64url_decode(str_rot47($item['body'])); + } + } } -function theme_attachments(&$item) { +function theme_attachments(&$item) +{ - $s = EMPTY_STR; + $s = EMPTY_STR; - $arr = json_decode($item['attach'],true); + $arr = json_decode($item['attach'], true); - if (is_array($arr) && count($arr)) { - $attaches = []; - foreach ($arr as $r) { + if (is_array($arr) && count($arr)) { + $attaches = []; + foreach ($arr as $r) { + $label = EMPTY_STR; + $icon = getIconFromType($r['type']); - $label = EMPTY_STR; - $icon = getIconFromType($r['type']); - - if (isset($r['title']) && $r['title']) { - $label = urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')); - } + if (isset($r['title']) && $r['title']) { + $label = urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')); + } - if (isset($r['name']) && $r['name']) { - $label = urldecode(htmlspecialchars($r['name'], ENT_COMPAT, 'UTF-8')); - } + if (isset($r['name']) && $r['name']) { + $label = urldecode(htmlspecialchars($r['name'], ENT_COMPAT, 'UTF-8')); + } - if (isset($r['href']) && $r['href']) { - $m = parse_url($r['href']); - } - if (! $label) { - if (isset($r['href']) && $r['href']) { - if (isset($m) && $m && $m['path']) { - $label = basename($m['path']); - } - } - } + if (isset($r['href']) && $r['href']) { + $m = parse_url($r['href']); + } + if (! $label) { + if (isset($r['href']) && $r['href']) { + if (isset($m) && $m && $m['path']) { + $label = basename($m['path']); + } + } + } - // some feeds provide an attachment where title is an empty space - if (! trim($label)) { - $label = t('Unknown Attachment'); - } + // some feeds provide an attachment where title is an empty space + if (! trim($label)) { + $label = t('Unknown Attachment'); + } - $title = t('Size') . ' ' . ((isset($r['length']) && $r['length']) ? userReadableSize($r['length']) : t('unknown')); + $title = t('Size') . ' ' . ((isset($r['length']) && $r['length']) ? userReadableSize($r['length']) : t('unknown')); - if (! (isset($r['href']))) { - continue; - } + if (! (isset($r['href']))) { + continue; + } - if (isset($m) && $m && $m['scheme'] === 'data') { - continue; - } + if (isset($m) && $m && $m['scheme'] === 'data') { + continue; + } - if (is_foreigner($item['author_xchan'])) { - $url = $r['href']; - } - else { - $url = z_root() . '/magic?f=&owa=1&hash=' . $item['author_xchan'] . '&bdest=' . bin2hex($r['href'] . ((isset($r['revision']) ? '/' . $r['revision'] : ''))); - } - $attaches[] = [ - 'label' => $label, - 'url' => $url, - 'icon' => $icon, - 'title' => $title - ]; - } + if (is_foreigner($item['author_xchan'])) { + $url = $r['href']; + } else { + $url = z_root() . '/magic?f=&owa=1&hash=' . $item['author_xchan'] . '&bdest=' . bin2hex($r['href'] . ((isset($r['revision']) ? '/' . $r['revision'] : ''))); + } + $attaches[] = [ + 'label' => $label, + 'url' => $url, + 'icon' => $icon, + 'title' => $title + ]; + } - $s = replace_macros(get_markup_template('item_attach.tpl'), [ - '$attaches' => $attaches - ]); - } + $s = replace_macros(get_markup_template('item_attach.tpl'), [ + '$attaches' => $attaches + ]); + } - return $s; + return $s; } -function format_categories(&$item,$writeable) { +function format_categories(&$item, $writeable) +{ - $s = EMPTY_STR; + $s = EMPTY_STR; - if (! (isset($item['term']) && $item['term'])) { - return $s; - } + if (! (isset($item['term']) && $item['term'])) { + return $s; + } - $terms = get_terms_oftype($item['term'],TERM_CATEGORY); - if($terms) { - $categories = []; - foreach($terms as $t) { - $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; - if(! trim($term)) - continue; - $removelink = (($writeable) ? z_root() . '/filerm/' . $item['id'] . '?f=&cat=' . urlencode($t['term']) : ''); - $categories[] = array('term' => $term, 'writeable' => $writeable, 'removelink' => $removelink, 'url' => zid($t['url'])); - } + $terms = get_terms_oftype($item['term'], TERM_CATEGORY); + if ($terms) { + $categories = []; + foreach ($terms as $t) { + $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; + if (! trim($term)) { + continue; + } + $removelink = (($writeable) ? z_root() . '/filerm/' . $item['id'] . '?f=&cat=' . urlencode($t['term']) : ''); + $categories[] = array('term' => $term, 'writeable' => $writeable, 'removelink' => $removelink, 'url' => zid($t['url'])); + } - $s = replace_macros(get_markup_template('item_categories.tpl'),array( - '$remove' => t('remove category'), - '$categories' => $categories - )); - } + $s = replace_macros(get_markup_template('item_categories.tpl'), array( + '$remove' => t('remove category'), + '$categories' => $categories + )); + } - return $s; + return $s; } /** @@ -1514,464 +1600,468 @@ function format_categories(&$item,$writeable) { * @return string HTML link of hashtag */ -function format_hashtags(&$item) { - $s = ''; +function format_hashtags(&$item) +{ + $s = ''; - if (! isset($item['term'])) { - return $s; - } + if (! isset($item['term'])) { + return $s; + } - $terms = get_terms_oftype($item['term'], array(TERM_HASHTAG,TERM_COMMUNITYTAG)); - if($terms) { - foreach($terms as $t) { - $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; - if(! trim($term)) - continue; + $terms = get_terms_oftype($item['term'], array(TERM_HASHTAG,TERM_COMMUNITYTAG)); + if ($terms) { + foreach ($terms as $t) { + $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; + if (! trim($term)) { + continue; + } - // Pleroma uses example.com/tags/xxx in the taglist but example.com/tag/xxx in the body. Possibly a bug because one of these leads to - // an error page, but it messes up our detection of whether the tag was already present in the body. - - if($t['url'] && ((stripos($item['body'], $t['url']) !== false) || (stripos($item['body'], str_replace('/tags/','/tag/',$t['url']))))) { - continue; - } - if($s) - $s .= ' '; + // Pleroma uses example.com/tags/xxx in the taglist but example.com/tag/xxx in the body. Possibly a bug because one of these leads to + // an error page, but it messes up our detection of whether the tag was already present in the body. - $s .= ' ' . $term . ''; - } - } + if ($t['url'] && ((stripos($item['body'], $t['url']) !== false) || (stripos($item['body'], str_replace('/tags/', '/tag/', $t['url']))))) { + continue; + } + if ($s) { + $s .= ' '; + } - return $s; + $s .= ' ' . $term . ''; + } + } + + return $s; } -function format_mentions(&$item) { - $s = EMPTY_STR; +function format_mentions(&$item) +{ + $s = EMPTY_STR; - $pref = intval(PConfig::Get($item['uid'],'system','tag_username',Config::Get('system','tag_username',false))); + $pref = intval(PConfig::Get($item['uid'], 'system', 'tag_username', Config::Get('system', 'tag_username', false))); - // hide "auto mentions" by default - this hidden pref let's you display them. + // hide "auto mentions" by default - this hidden pref let's you display them. - $show = intval(PConfig::Get($item['uid'],'system','show_auto_mentions',false)); - if ((! $show) && (! $item['resource_type'])) { - return $s; - } + $show = intval(PConfig::Get($item['uid'], 'system', 'show_auto_mentions', false)); + if ((! $show) && (! $item['resource_type'])) { + return $s; + } - if ($pref === 127) { - return $s; - } + if ($pref === 127) { + return $s; + } - if (! (isset($item['term']) && is_array($item['term']) && $item['term'])) { - return $s; - } - $terms = get_terms_oftype($item['term'],TERM_MENTION); - if($terms) { - foreach($terms as $t) { + if (! (isset($item['term']) && is_array($item['term']) && $item['term'])) { + return $s; + } + $terms = get_terms_oftype($item['term'], TERM_MENTION); + if ($terms) { + foreach ($terms as $t) { + $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; + if (! trim($term)) { + continue; + } - $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; - if(! trim($term)) - continue; + if ($t['url'] && stripos($item['body'], $t['url']) !== false) { + continue; + } - if($t['url'] && stripos($item['body'], $t['url']) !== false) - continue; + // some platforms put the identity url into href rather than the profile url. Accept either form. + $x = q( + "select * from xchan where xchan_url = '%s' or xchan_hash = '%s' limit 1", + dbesc($t['url']), + dbesc($t['url']) + ); + if ($x) { + switch ($pref) { + case 0: + $txt = $x[0]['xchan_name']; + break; + case 1: + $txt = (($x[0]['xchan_addr']) ? $x[0]['xchan_addr'] : $x[0]['xchan_name']); + break; + case 2: + default; + if ($x[0]['xchan_addr']) { + $txt = sprintf(t('%1$s (%2$s)'), $x[0]['xchan_name'], $x[0]['xchan_addr']); + } else { + $txt = $x[0]['xchan_name']; + } + break; + } + } - // some platforms put the identity url into href rather than the profile url. Accept either form. - $x = q("select * from xchan where xchan_url = '%s' or xchan_hash = '%s' limit 1", - dbesc($t['url']), - dbesc($t['url']) - ); - if ($x) { - switch ($pref) { - case 0: - $txt = $x[0]['xchan_name']; - break; - case 1: - $txt = (($x[0]['xchan_addr']) ? $x[0]['xchan_addr'] : $x[0]['xchan_name']); - break; - case 2: - default; - if ($x[0]['xchan_addr']) { - $txt = sprintf( t('%1$s (%2$s)'), $x[0]['xchan_name'], $x[0]['xchan_addr']); - } - else { - $txt = $x[0]['xchan_name']; - } - break; - } - } - - if ($s) { - $s .= ' '; - } - $s .= ' ' . $txt . ''; - } - } + if ($s) { + $s .= ' '; + } + $s .= ' ' . $txt . ''; + } + } - return $s; + return $s; } -function format_filer(&$item) { - $s = EMPTY_STR; +function format_filer(&$item) +{ + $s = EMPTY_STR; - if (! (isset($item['term']) && $item['term'])) { - return $s; - } + if (! (isset($item['term']) && $item['term'])) { + return $s; + } - $terms = get_terms_oftype($item['term'],TERM_FILE); - if($terms) { - $categories = []; - foreach($terms as $t) { - $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; - if(! trim($term)) - continue; - $removelink = z_root() . '/filerm/' . $item['id'] . '?f=&term=' . urlencode($t['term']); - $categories[] = array('term' => $term, 'removelink' => $removelink); - } + $terms = get_terms_oftype($item['term'], TERM_FILE); + if ($terms) { + $categories = []; + foreach ($terms as $t) { + $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; + if (! trim($term)) { + continue; + } + $removelink = z_root() . '/filerm/' . $item['id'] . '?f=&term=' . urlencode($t['term']); + $categories[] = array('term' => $term, 'removelink' => $removelink); + } - $s = replace_macros(get_markup_template('item_filer.tpl'),array( - '$remove' => t('remove from file'), - '$categories' => $categories - )); - } + $s = replace_macros(get_markup_template('item_filer.tpl'), array( + '$remove' => t('remove from file'), + '$categories' => $categories + )); + } - return $s; + return $s; } -function generate_map($coord) { +function generate_map($coord) +{ - $coord = str_replace(array(',','/',' '),array(' ',' ',' '),trim($coord)); + $coord = str_replace(array(',','/',' '), array(' ',' ',' '), trim($coord)); - - $zoom = ((strpos($coord,'?z=') !== false) ? substr($coord,strpos($coord,'?z=')+3) : 0); - if ($zoom) { - $coord = substr($coord,0,strpos($coord,'?')); - } - else { - $zoom = 16; - } + $zoom = ((strpos($coord, '?z=') !== false) ? substr($coord, strpos($coord, '?z=') + 3) : 0); - $arr = [ - 'lat' => trim(substr($coord, 0, strpos($coord, ' '))), - 'lon' => trim(substr($coord, strpos($coord, ' ')+1)), - 'zoom' => $zoom, - 'html' => '' - ]; + if ($zoom) { + $coord = substr($coord, 0, strpos($coord, '?')); + } else { + $zoom = 16; + } - /** - * @hooks generate_map - * * \e string \b lat - * * \e string \b lon - * * \e string \b html the parsed HTML to return - */ - call_hooks('generate_map', $arr); + $arr = [ + 'lat' => trim(substr($coord, 0, strpos($coord, ' '))), + 'lon' => trim(substr($coord, strpos($coord, ' ') + 1)), + 'zoom' => $zoom, + 'html' => '' + ]; - return (($arr['html']) ? $arr['html'] : $coord); + /** + * @hooks generate_map + * * \e string \b lat + * * \e string \b lon + * * \e string \b html the parsed HTML to return + */ + call_hooks('generate_map', $arr); + + return (($arr['html']) ? $arr['html'] : $coord); } -function generate_named_map($location) { - $arr = [ - 'location' => $location, - 'html' => '' - ]; +function generate_named_map($location) +{ + $arr = [ + 'location' => $location, + 'html' => '' + ]; - /** - * @hooks generate_named_map - * * \e string \b location - * * \e string \b html the parsed HTML to return - */ - call_hooks('generate_named_map', $arr); + /** + * @hooks generate_named_map + * * \e string \b location + * * \e string \b html the parsed HTML to return + */ + call_hooks('generate_named_map', $arr); - return (($arr['html']) ? $arr['html'] : $location); + return (($arr['html']) ? $arr['html'] : $location); } -function prepare_body(&$item,$attach = false,$opts = false) { +function prepare_body(&$item, $attach = false, $opts = false) +{ - call_hooks('prepare_body_init', $item); + call_hooks('prepare_body_init', $item); - $censored = ((($item['author']['abook_censor'] || $item['owner']['abook_censor'] || $item['author']['xchan_selfcensored'] || $item['owner']['xchan_selfcensored'] || $item['author']['xchan_censored'] || $item['owner']['xchan_censored'] || intval($item['item_nsfw'])) && (get_safemode())) - ? true - : false - ); + $censored = ((($item['author']['abook_censor'] || $item['owner']['abook_censor'] || $item['author']['xchan_selfcensored'] || $item['owner']['xchan_selfcensored'] || $item['author']['xchan_censored'] || $item['owner']['xchan_censored'] || intval($item['item_nsfw'])) && (get_safemode())) + ? true + : false + ); - if ($censored) { - if (! $opts) { - $opts = []; - } - $opts['censored'] = true; - } - - $s = ''; - $photo = ''; + if ($censored) { + if (! $opts) { + $opts = []; + } + $opts['censored'] = true; + } - $is_photo = ((($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) ? true : false); + $s = ''; + $photo = ''; - if ($is_photo && ! $censored) { + $is_photo = ((($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) ? true : false); - $object = json_decode($item['obj'],true); - $ptr = null; + if ($is_photo && ! $censored) { + $object = json_decode($item['obj'], true); + $ptr = null; - if (is_array($object) && array_key_exists('url',$object) && is_array($object['url'])) { - if (array_key_exists(0,$object['url'])) { - foreach ($object['url'] as $link) { - if(array_key_exists('width',$link) && $link['width'] >= 640 && $link['width'] <= 1024) { - $ptr = $link; - } - } - if (! $ptr) { - $ptr = $object['url'][0]; - } - } - else { - $ptr = $object['url']; - } + if (is_array($object) && array_key_exists('url', $object) && is_array($object['url'])) { + if (array_key_exists(0, $object['url'])) { + foreach ($object['url'] as $link) { + if (array_key_exists('width', $link) && $link['width'] >= 640 && $link['width'] <= 1024) { + $ptr = $link; + } + } + if (! $ptr) { + $ptr = $object['url'][0]; + } + } else { + $ptr = $object['url']; + } - // if original photo width is > 640px make it a cover photo - if ($ptr) { - $alt_text = ' alt="' . ((isset($ptr['summary']) && $ptr['summary']) ? htmlspecialchars($ptr['summary'], ENT_QUOTES, 'UTF-8') : t('Image/photo')) . '"'; - $title_text = ' title="' . ((isset($ptr['summary']) && $ptr['summary']) ? htmlspecialchars($ptr['summary'], ENT_QUOTES, 'UTF-8') : t('Image/photo')) . '"'; + // if original photo width is > 640px make it a cover photo + if ($ptr) { + $alt_text = ' alt="' . ((isset($ptr['summary']) && $ptr['summary']) ? htmlspecialchars($ptr['summary'], ENT_QUOTES, 'UTF-8') : t('Image/photo')) . '"'; + $title_text = ' title="' . ((isset($ptr['summary']) && $ptr['summary']) ? htmlspecialchars($ptr['summary'], ENT_QUOTES, 'UTF-8') : t('Image/photo')) . '"'; - if (array_key_exists('width',$ptr) && $ptr['width'] > 640) { - $photo = ''; - } - else { - $item['body'] = '[zmg' . $alt_text . ']' . $ptr['href'] . '[/zmg]' . "\n\n" . $item['body']; - } - } - } - } + if (array_key_exists('width', $ptr) && $ptr['width'] > 640) { + $photo = ''; + } else { + $item['body'] = '[zmg' . $alt_text . ']' . $ptr['href'] . '[/zmg]' . "\n\n" . $item['body']; + } + } + } + } - if($item['item_obscured']) { - $s .= prepare_binary($item); - } - else { - if($item['summary']) { - // 8203 is a zero-width space so as not to trigger a markdown link if the summary starts with parentheses - $s .= prepare_text('[summary]​' . $item['summary'] . '[/summary]​' . $item['body'],$item['mimetype'],$opts); - } - else { - if ($item['html']) { - $s .= smilies($item['html']); - } - else { - $s .= prepare_text($item['body'],$item['mimetype'], $opts); - } - } - } + if ($item['item_obscured']) { + $s .= prepare_binary($item); + } else { + if ($item['summary']) { + // 8203 is a zero-width space so as not to trigger a markdown link if the summary starts with parentheses + $s .= prepare_text('[summary]​' . $item['summary'] . '[/summary]​' . $item['body'], $item['mimetype'], $opts); + } else { + if ($item['html']) { + $s .= smilies($item['html']); + } else { + $s .= prepare_text($item['body'], $item['mimetype'], $opts); + } + } + } - $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ 'Create','Update' ])) ? format_poll($item, $s, $opts) : false); - if ($poll) { - $s = $poll; - } + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'], [ 'Create','Update' ])) ? format_poll($item, $s, $opts) : false); + if ($poll) { + $s = $poll; + } - $e = trim($item['body']); - $em = Emoji\is_single_emoji($e) || mb_strlen($e) === 1; - if ($em) { - $s = '' . trim($item['body']) . ''; - } + $e = trim($item['body']); + $em = Emoji\is_single_emoji($e) || mb_strlen($e) === 1; + if ($em) { + $s = '' . trim($item['body']) . ''; + } - $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false); + $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false); - // This is not the most pleasant UI element possible, but this is difficult to add to one of the templates. - // Eventually we may wish to add/remove to/from calendar in the message title area but it will take a chunk - // of code re-factoring to make that happen. + // This is not the most pleasant UI element possible, but this is difficult to add to one of the templates. + // Eventually we may wish to add/remove to/from calendar in the message title area but it will take a chunk + // of code re-factoring to make that happen. - if(is_array($event) && $event['header'] && $item['resource_id']) { - $event['header'] .= '' . ' ' . t('Added to your calendar'); - } + if (is_array($event) && $event['header'] && $item['resource_id']) { + $event['header'] .= '' . ' ' . t('Added to your calendar'); + } - $prep_arr = array( - 'item' => $item, - 'html' => $event ? $event['content'] : $s, - 'event' => ((is_array($event)) ? $event['header'] : EMPTY_STR), - 'photo' => $photo - ); + $prep_arr = array( + 'item' => $item, + 'html' => $event ? $event['content'] : $s, + 'event' => ((is_array($event)) ? $event['header'] : EMPTY_STR), + 'photo' => $photo + ); - call_hooks('prepare_body', $prep_arr); + call_hooks('prepare_body', $prep_arr); - $s = $prep_arr['html']; - $photo = $prep_arr['photo']; - $event = $prep_arr['event']; + $s = $prep_arr['html']; + $photo = $prep_arr['photo']; + $event = $prep_arr['event']; - if(! $attach) { - return $s; - } + if (! $attach) { + return $s; + } - if(strpos($s,'
                    ') !== false && $item['coord']) { - $x = generate_map(trim($item['coord'])); - if($x) { - $s = preg_replace('/\
                    /','$0' . $x,$s); - } - } + if (strpos($s, '
                    ') !== false && $item['coord']) { + $x = generate_map(trim($item['coord'])); + if ($x) { + $s = preg_replace('/\
                    /', '$0' . $x, $s); + } + } - $attachments = theme_attachments($item); + $attachments = theme_attachments($item); - $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); + $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); - $tags = format_hashtags($item); + $tags = format_hashtags($item); - $mentions = format_mentions($item); + $mentions = format_mentions($item); - $categories = format_categories($item,$writeable); + $categories = format_categories($item, $writeable); - if(local_channel() == $item['uid']) - $filer = format_filer($item); + if (local_channel() == $item['uid']) { + $filer = format_filer($item); + } - // Caching photos can use absurd amounts of space. - // Don't cache photos if somebody is just browsing the stream to the - // beginning of time. This optimises performance for viewing things created - // recently. Also catch an explicit expiration of 0 or "no cache". + // Caching photos can use absurd amounts of space. + // Don't cache photos if somebody is just browsing the stream to the + // beginning of time. This optimises performance for viewing things created + // recently. Also catch an explicit expiration of 0 or "no cache". - $cache_expire = intval(get_config('system', 'default_expire_days')); - if ($cache_expire <= 0) { - $cache_expire = 60; - } - $cache_enable = ((($cache_expire) && ($item['created'] < datetime_convert('UTC','UTC', 'now - ' . $cache_expire . ' days'))) ? false : true); + $cache_expire = intval(get_config('system', 'default_expire_days')); + if ($cache_expire <= 0) { + $cache_expire = 60; + } + $cache_enable = ((($cache_expire) && ($item['created'] < datetime_convert('UTC', 'UTC', 'now - ' . $cache_expire . ' days'))) ? false : true); - // disable Unicode RTL over-ride since it can destroy presentation in some cases, use HTML or CSS instead - $s = str_replace([ '‮', '‮', html_entity_decode('‮', ENT_QUOTES,'UTF-8') ],[ '','','' ],$s); + // disable Unicode RTL over-ride since it can destroy presentation in some cases, use HTML or CSS instead + $s = str_replace([ '‮', '‮', html_entity_decode('‮', ENT_QUOTES, 'UTF-8') ], [ '','','' ], $s); - if($s) - $s = sslify($s, $cache_enable); - if($photo) - $photo = sslify($photo, $cache_enable); - if($event) - $event = sslify($event, $cache_enable); - - $prep_arr = array( - 'item' => $item, - 'photo' => $photo, - 'html' => $s, - 'event' => $event, - 'categories' => $categories, - 'folders' => $filer, - 'tags' => $tags, - 'mentions' => $mentions, - 'attachments' => $attachments - ); + if ($s) { + $s = sslify($s, $cache_enable); + } + if ($photo) { + $photo = sslify($photo, $cache_enable); + } + if ($event) { + $event = sslify($event, $cache_enable); + } - call_hooks('prepare_body_final', $prep_arr); + $prep_arr = array( + 'item' => $item, + 'photo' => $photo, + 'html' => $s, + 'event' => $event, + 'categories' => $categories, + 'folders' => $filer, + 'tags' => $tags, + 'mentions' => $mentions, + 'attachments' => $attachments + ); - unset($prep_arr['item']); + call_hooks('prepare_body_final', $prep_arr); - return $prep_arr; + unset($prep_arr['item']); + + return $prep_arr; } -function separate_img_links($s) { - $x = preg_replace('/\\\<\/a\>/ism', - '
                    ' . t('Link') . '
                    ',$s); +function separate_img_links($s) +{ + $x = preg_replace( + '/\\\<\/a\>/ism', + '
                    ' . t('Link') . '
                    ', + $s + ); - return $x; -} + return $x; +} -function format_poll($item,$s,$opts) { +function format_poll($item, $s, $opts) +{ - if (! is_array($item['obj'])) { - $act = json_decode($item['obj'],true); - } - else { - $act = $item['obj']; - } + if (! is_array($item['obj'])) { + $act = json_decode($item['obj'], true); + } else { + $act = $item['obj']; + } - if (! is_array($act)) { - return EMPTY_STR; - } + if (! is_array($act)) { + return EMPTY_STR; + } - $commentable = can_comment_on_post(((local_channel()) ? get_observer_hash() : EMPTY_STR),$item); + $commentable = can_comment_on_post(((local_channel()) ? get_observer_hash() : EMPTY_STR), $item); - //logger('format_poll: ' . print_r($item,true)); - $activated = ((local_channel() && local_channel() == $item['uid']) ? true : false); - $output = $s . EOL. EOL; + //logger('format_poll: ' . print_r($item,true)); + $activated = ((local_channel() && local_channel() == $item['uid']) ? true : false); + $output = $s . EOL . EOL; - $closed = false; - $closing = false; + $closed = false; + $closing = false; - if ($item['comments_closed'] > NULL_DATE) { - $closing = true; - $t = datetime_convert('UTC',date_default_timezone_get(), $item['comments_closed'], 'Y-m-d H:i'); - $closed = ((datetime_convert() > $item['comments_closed']) ? true : false); - if ($closed) { - $commentable = false; - } - } + if ($item['comments_closed'] > NULL_DATE) { + $closing = true; + $t = datetime_convert('UTC', date_default_timezone_get(), $item['comments_closed'], 'Y-m-d H:i'); + $closed = ((datetime_convert() > $item['comments_closed']) ? true : false); + if ($closed) { + $commentable = false; + } + } - if ($act['type'] === 'Question') { - if ($activated and $commentable) { - $output .= '
                    '; - } - if (array_key_exists('anyOf',$act) && is_array($act['anyOf'])) { - foreach ($act['anyOf'] as $poll) { - if (array_key_exists('name',$poll) && $poll['name']) { - $text = html2plain(purify_html($poll['name']),256); - if (array_path_exists('replies/totalItems',$poll)) { - $total = $poll['replies']['totalItems']; - } - else { - $total = 0; - } - if ($activated && $commentable) { - $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; - } - else { - $output .= $text . ' (' . $total . ')' . EOL; - } - } - } - } - if (array_key_exists('oneOf',$act) && is_array($act['oneOf'])) { - $totalResponses = 0; - foreach ($act['oneOf'] as $poll) { - if (array_path_exists('replies/totalItems',$poll)) { - $totalResponses += intval($poll['replies']['totalItems']); - } - } - foreach ($act['oneOf'] as $poll) { - if (is_array($poll) && array_key_exists('name',$poll) && $poll['name']) { - $text = html2plain(purify_html($poll['name']),256); - if (array_path_exists('replies/totalItems',$poll)) { - $total = $poll['replies']['totalItems']; - } - else { - $total = 0; - } - if ($activated && $commentable) { - $output .= ' ' . $text . '' . ' (' . $total . ')' . (($totalResponses) ? ' ' . intval($total / $totalResponses * 100) . '%' : '') . EOL; - } - else { - $output .= $text . ' (' . $total . ')' . (($totalResponses) ? ' ' . intval($total / $totalResponses * 100) . '%' : '') . EOL; - } - - } - } - } - if ($closed) { - $message = t('Poll has ended.'); - } - elseif ($closing) { - $message = sprintf(t('Poll ends: %1$s (%2$s)'),relative_date($t),$t); - } - $output .= EOL . '
                    ' . $message . '
                    '; + if ($act['type'] === 'Question') { + if ($activated and $commentable) { + $output .= ''; + } + if (array_key_exists('anyOf', $act) && is_array($act['anyOf'])) { + foreach ($act['anyOf'] as $poll) { + if (array_key_exists('name', $poll) && $poll['name']) { + $text = html2plain(purify_html($poll['name']), 256); + if (array_path_exists('replies/totalItems', $poll)) { + $total = $poll['replies']['totalItems']; + } else { + $total = 0; + } + if ($activated && $commentable) { + $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + } else { + $output .= $text . ' (' . $total . ')' . EOL; + } + } + } + } + if (array_key_exists('oneOf', $act) && is_array($act['oneOf'])) { + $totalResponses = 0; + foreach ($act['oneOf'] as $poll) { + if (array_path_exists('replies/totalItems', $poll)) { + $totalResponses += intval($poll['replies']['totalItems']); + } + } + foreach ($act['oneOf'] as $poll) { + if (is_array($poll) && array_key_exists('name', $poll) && $poll['name']) { + $text = html2plain(purify_html($poll['name']), 256); + if (array_path_exists('replies/totalItems', $poll)) { + $total = $poll['replies']['totalItems']; + } else { + $total = 0; + } + if ($activated && $commentable) { + $output .= ' ' . $text . '' . ' (' . $total . ')' . (($totalResponses) ? ' ' . intval($total / $totalResponses * 100) . '%' : '') . EOL; + } else { + $output .= $text . ' (' . $total . ')' . (($totalResponses) ? ' ' . intval($total / $totalResponses * 100) . '%' : '') . EOL; + } + } + } + } + if ($closed) { + $message = t('Poll has ended.'); + } elseif ($closing) { + $message = sprintf(t('Poll ends: %1$s (%2$s)'), relative_date($t), $t); + } + $output .= EOL . '
                    ' . $message . '
                    '; - if ($activated and $commentable) { - $output .= EOL . ''. '
                    '; - } - - - } - return $output; + if ($activated and $commentable) { + $output .= EOL . '' . ''; + } + } + return $output; } -function prepare_binary($item) { - return replace_macros(get_markup_template('item_binary.tpl'), [ - '$download' => t('Download binary/encrypted content'), - '$url' => z_root() . '/viewsrc/' . $item['id'] . '/download' - ]); +function prepare_binary($item) +{ + return replace_macros(get_markup_template('item_binary.tpl'), [ + '$download' => t('Download binary/encrypted content'), + '$url' => z_root() . '/viewsrc/' . $item['id'] . '/download' + ]); } @@ -1984,197 +2074,220 @@ function prepare_binary($item) { * * @return string */ -function prepare_text($text, $content_type = 'text/bbcode', $opts = false) { +function prepare_text($text, $content_type = 'text/bbcode', $opts = false) +{ - switch($content_type) { - case 'text/plain': - $s = escape_tags($text); - break; + switch ($content_type) { + case 'text/plain': + $s = escape_tags($text); + break; - case 'text/html': - $s = $text; - break; + case 'text/html': + $s = $text; + break; - case 'text/markdown': - $text = MarkdownSoap::unescape($text); - $s = MarkdownExtra::defaultTransform($text); - break; + case 'text/markdown': + $text = MarkdownSoap::unescape($text); + $s = MarkdownExtra::defaultTransform($text); + break; - case 'application/x-pdl'; - $s = escape_tags($text); - break; + case 'application/x-pdl'; + $s = escape_tags($text); + break; - // No security checking is done here at display time - so we need to verify - // that the author is allowed to use PHP before storing. We also cannot allow - // importation of PHP text bodies from other sites. Therefore this content - // type is only valid for web pages (and profile details). + // No security checking is done here at display time - so we need to verify + // that the author is allowed to use PHP before storing. We also cannot allow + // importation of PHP text bodies from other sites. Therefore this content + // type is only valid for web pages (and profile details). - // It may be possible to provide a PHP message body which is evaluated on the - // sender's site before sending it elsewhere. In that case we will have a - // different content-type here. + // It may be possible to provide a PHP message body which is evaluated on the + // sender's site before sending it elsewhere. In that case we will have a + // different content-type here. - case 'application/x-php': - ob_start(); - eval($text); - $s = ob_get_contents(); - ob_end_clean(); - break; + case 'application/x-php': + ob_start(); + eval($text); + $s = ob_get_contents(); + ob_end_clean(); + break; - case 'text/bbcode': - case 'text/x-multicode': - case '': - default: - require_once('include/bbcode.php'); + case 'text/bbcode': + case 'text/x-multicode': + case '': + default: + require_once('include/bbcode.php'); - if(stristr($text,'[nosmile]')) - $s = bbcode($text, [ 'cache' => $cache ]); - else - $s = smilies(bbcode($text, ((is_array($opts)) ? $opts : [] ))); + if (stristr($text, '[nosmile]')) { + $s = bbcode($text, [ 'cache' => $cache ]); + } else { + $s = smilies(bbcode($text, ((is_array($opts)) ? $opts : [] ))); + } - $s = zidify_links($s); + $s = zidify_links($s); - break; - } + break; + } //logger('prepare_text: ' . $s); - return $s; + return $s; } -function create_export_photo_body(&$item) { - if(($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) { - $j = json_decode($item['obj'],true); - if($j) { - $item['body'] .= "\n\n" . (($j['source']['content']) ? $j['source']['content'] : $item['content']); - $item['sig'] = ''; - } - } +function create_export_photo_body(&$item) +{ + if (($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) { + $j = json_decode($item['obj'], true); + if ($j) { + $item['body'] .= "\n\n" . (($j['source']['content']) ? $j['source']['content'] : $item['content']); + $item['sig'] = ''; + } + } } -function get_plink($item,$conversation_mode = true) { - if($conversation_mode) - $key = 'plink'; - else - $key = 'llink'; +function get_plink($item, $conversation_mode = true) +{ + if ($conversation_mode) { + $key = 'plink'; + } else { + $key = 'llink'; + } - $zidify = true; + $zidify = true; - if(array_key_exists('author',$item) && $item['author']['xchan_network'] !== 'zot6') - $zidify = false; + if (array_key_exists('author', $item) && $item['author']['xchan_network'] !== 'zot6') { + $zidify = false; + } - if(x($item,$key)) { - return [ - 'href' => (($zidify) ? zid($item[$key]) : $item[$key]), - 'title' => t('Link to Source'), - ]; - } - else { - return false; - } + if (x($item, $key)) { + return [ + 'href' => (($zidify) ? zid($item[$key]) : $item[$key]), + 'title' => t('Link to Source'), + ]; + } else { + return false; + } } -function layout_select($channel_id, $current = '') { - $r = q("select mid, v from item left join iconfig on iconfig.iid = item.id +function layout_select($channel_id, $current = '') +{ + $r = q( + "select mid, v from item left join iconfig on iconfig.iid = item.id where iconfig.cat = 'system' and iconfig.k = 'PDL' and item.uid = %d and item_type = %d ", - intval($channel_id), - intval(ITEM_TYPE_PDL) - ); + intval($channel_id), + intval(ITEM_TYPE_PDL) + ); - if($r) { - $empty_selected = (($current === false) ? ' selected="selected" ' : ''); - $options .= ''; - foreach($r as $rr) { - $selected = (($rr['mid'] == $current) ? ' selected="selected" ' : ''); - $options .= ''; - } - } + if ($r) { + $empty_selected = (($current === false) ? ' selected="selected" ' : ''); + $options .= ''; + foreach ($r as $rr) { + $selected = (($rr['mid'] == $current) ? ' selected="selected" ' : ''); + $options .= ''; + } + } - $o = replace_macros(get_markup_template('field_select_raw.tpl'), array( - '$field' => array('layout_mid', t('Page layout'), $selected, t('You can create your own with the layouts tool'), $options) - )); + $o = replace_macros(get_markup_template('field_select_raw.tpl'), array( + '$field' => array('layout_mid', t('Page layout'), $selected, t('You can create your own with the layouts tool'), $options) + )); - return $o; + return $o; } -function mimetype_select($channel_id, $current = 'text/bbcode', $choices = null, $element = 'mimetype') { +function mimetype_select($channel_id, $current = 'text/bbcode', $choices = null, $element = 'mimetype') +{ - $x = (($choices) ? $choices : [ - 'text/bbcode' => t('BBcode'), - 'text/html' => t('HTML'), - 'text/markdown' => t('Markdown'), - 'text/plain' => t('Text'), - 'application/x-pdl' => t('Comanche Layout') - ]); + $x = (($choices) ? $choices : [ + 'text/bbcode' => t('BBcode'), + 'text/html' => t('HTML'), + 'text/markdown' => t('Markdown'), + 'text/plain' => t('Text'), + 'application/x-pdl' => t('Comanche Layout') + ]); - if((App::$is_sys) || (channel_codeallowed($channel_id) && $channel_id == local_channel())){ - $x['application/x-php'] = t('PHP'); - } + if ((App::$is_sys) || (channel_codeallowed($channel_id) && $channel_id == local_channel())) { + $x['application/x-php'] = t('PHP'); + } - foreach($x as $y => $z) { - $selected = (($y == $current) ? ' selected="selected" ' : ''); - $options .= ''; - } + foreach ($x as $y => $z) { + $selected = (($y == $current) ? ' selected="selected" ' : ''); + $options .= ''; + } - $o = replace_macros(get_markup_template('field_select_raw.tpl'), array( - '$field' => array( $element, t('Page content type'), $selected, '', $options) - )); + $o = replace_macros(get_markup_template('field_select_raw.tpl'), array( + '$field' => array( $element, t('Page content type'), $selected, '', $options) + )); - return $o; + return $o; } -function engr_units_to_bytes ($size_str) { - if(! $size_str) - return $size_str; - switch (substr(trim($size_str), -1)) { - case 'M': case 'm': return (int)$size_str * 1048576; - case 'K': case 'k': return (int)$size_str * 1024; - case 'G': case 'g': return (int)$size_str * 1073741824; - default: return $size_str; - } +function engr_units_to_bytes($size_str) +{ + if (! $size_str) { + return $size_str; + } + switch (substr(trim($size_str), -1)) { + case 'M': + case 'm': + return (int)$size_str * 1048576; + case 'K': + case 'k': + return (int)$size_str * 1024; + case 'G': + case 'g': + return (int)$size_str * 1073741824; + default: + return $size_str; + } } -function base64url_encode($s, $strip_padding = true) { +function base64url_encode($s, $strip_padding = true) +{ - $s = strtr(base64_encode($s),'+/','-_'); + $s = strtr(base64_encode($s), '+/', '-_'); - if($strip_padding) - $s = str_replace('=','',$s); + if ($strip_padding) { + $s = str_replace('=', '', $s); + } - return $s; + return $s; } -function base64url_decode($s) { - if(is_array($s)) { - logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); - return $s; - } - return base64_decode(strtr($s,'-_','+/')); +function base64url_decode($s) +{ + if (is_array($s)) { + logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); + return $s; + } + return base64_decode(strtr($s, '-_', '+/')); } -function base64special_encode($s, $strip_padding = true) { +function base64special_encode($s, $strip_padding = true) +{ - $s = strtr(base64_encode($s),'+/',',.'); + $s = strtr(base64_encode($s), '+/', ',.'); - if($strip_padding) - $s = str_replace('=','',$s); + if ($strip_padding) { + $s = str_replace('=', '', $s); + } - return $s; + return $s; } -function base64special_decode($s) { - if(is_array($s)) { - logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); - return $s; - } - return base64_decode(strtr($s,',.','+/')); +function base64special_decode($s) +{ + if (is_array($s)) { + logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); + return $s; + } + return base64_decode(strtr($s, ',.', '+/')); } /** @@ -2182,269 +2295,295 @@ function base64special_decode($s) { * * @return string */ -function cleardiv() { - return '
                    '; +function cleardiv() +{ + return '
                    '; } -function bb_translate_video($s) { - $arr = array('string' => $s); - call_hooks('bb_translate_video',$arr); - return $arr['string']; +function bb_translate_video($s) +{ + $arr = array('string' => $s); + call_hooks('bb_translate_video', $arr); + return $arr['string']; } -function html2bb_video($s) { - $arr = array('string' => $s); - call_hooks('html2bb_video',$arr); - return $arr['string']; +function html2bb_video($s) +{ + $arr = array('string' => $s); + call_hooks('html2bb_video', $arr); + return $arr['string']; } /** * apply xmlify() to all values of array $val, recursively */ -function array_xmlify($val) { - if (is_bool($val)) return $val?"true":"false"; - if (is_array($val)) return array_map('array_xmlify', $val); - return xmlify((string) $val); +function array_xmlify($val) +{ + if (is_bool($val)) { + return $val ? "true" : "false"; + } + if (is_array($val)) { + return array_map('array_xmlify', $val); + } + return xmlify((string) $val); } -function reltoabs($text, $base) { - if (empty($base)) - return $text; +function reltoabs($text, $base) +{ + if (empty($base)) { + return $text; + } - $base = rtrim($base,'/'); + $base = rtrim($base, '/'); - $base2 = $base . "/"; + $base2 = $base . "/"; - // Replace links - $pattern = "/]*) href=\"(?!http|https|\/)([^\"]*)\"/"; - $replace = " 1900) { - $y = date('Y'); - if($i <= $y+1 && strpos($s,'-') == 4) { - $m = intval(substr($s,5)); - if($m > 0 && $m <= 12) - return true; - } - } +function is_a_date_arg($s) +{ + $i = intval($s); + if ($i > 1900) { + $y = date('Y'); + if ($i <= $y + 1 && strpos($s, '-') == 4) { + $m = intval(substr($s, 5)); + if ($m > 0 && $m <= 12) { + return true; + } + } + } - return false; + return false; } -function legal_webbie($s) { - if(! $s) - return ''; +function legal_webbie($s) +{ + if (! $s) { + return ''; + } - // WARNING: This regex may not work in a federated environment. - // You will probably want something like - // preg_replace('/([^a-z0-9\_])/','',strtolower($s)); + // WARNING: This regex may not work in a federated environment. + // You will probably want something like + // preg_replace('/([^a-z0-9\_])/','',strtolower($s)); - $r = preg_replace('/([^a-z0-9\-\_])/','',strtolower($s)); - - $x = [ 'input' => $s, 'output' => $r ]; - call_hooks('legal_webbie',$x); - return $x['output']; + $r = preg_replace('/([^a-z0-9\-\_])/', '', strtolower($s)); + $x = [ 'input' => $s, 'output' => $r ]; + call_hooks('legal_webbie', $x); + return $x['output']; } -function legal_webbie_text() { +function legal_webbie_text() +{ - // WARNING: This will not work in a federated environment. + // WARNING: This will not work in a federated environment. - $s = t('a-z, 0-9, -, and _ only'); - - $x = [ 'text' => $s ]; - call_hooks('legal_webbie_text',$x); - return $x['text']; + $s = t('a-z, 0-9, -, and _ only'); + $x = [ 'text' => $s ]; + call_hooks('legal_webbie_text', $x); + return $x['text']; } -function check_webbie($arr) { +function check_webbie($arr) +{ - // These names conflict with the CalDAV server - $taken = [ 'principals', 'addressbooks', 'calendars' ]; + // These names conflict with the CalDAV server + $taken = [ 'principals', 'addressbooks', 'calendars' ]; - $reservechan = get_config('system','reserved_channels'); - if(strlen($reservechan)) { - $taken = array_merge($taken,explode(',', $reservechan)); - } + $reservechan = get_config('system', 'reserved_channels'); + if (strlen($reservechan)) { + $taken = array_merge($taken, explode(',', $reservechan)); + } - $str = ''; - if(count($arr)) { - foreach($arr as $x) { - $y = legal_webbie($x); - if(strlen($y)) { - if($str) - $str .= ','; - $str .= "'" . dbesc($y) . "'"; - } - } + $str = ''; + if (count($arr)) { + foreach ($arr as $x) { + $y = legal_webbie($x); + if (strlen($y)) { + if ($str) { + $str .= ','; + } + $str .= "'" . dbesc($y) . "'"; + } + } - if(strlen($str)) { - $r = q("select channel_address from channel where channel_address in ( $str ) "); - if(count($r)) { - foreach($r as $rr) { - $taken[] = $rr['channel_address']; - } - } - foreach($arr as $x) { - $y = legal_webbie($x); - if(! in_array($y,$taken)) { - return $y; - } - } - } - } + if (strlen($str)) { + $r = q("select channel_address from channel where channel_address in ( $str ) "); + if (count($r)) { + foreach ($r as $rr) { + $taken[] = $rr['channel_address']; + } + } + foreach ($arr as $x) { + $y = legal_webbie($x); + if (! in_array($y, $taken)) { + return $y; + } + } + } + } - return ''; + return ''; } -function ids_to_array($arr,$idx = 'id') { - $t = []; - if($arr) { - foreach($arr as $x) { - if(array_key_exists($idx,$x) && strlen($x[$idx]) && (! in_array($x[$idx],$t))) { - $t[] = $x[$idx]; - } - } - } - return($t); +function ids_to_array($arr, $idx = 'id') +{ + $t = []; + if ($arr) { + foreach ($arr as $x) { + if (array_key_exists($idx, $x) && strlen($x[$idx]) && (! in_array($x[$idx], $t))) { + $t[] = $x[$idx]; + } + } + } + return($t); } -function ids_to_querystr($arr,$idx = 'id',$quote = false) { - $t = []; - if($arr) { - foreach($arr as $x) { - if(! in_array($x[$idx],$t)) { - if($quote) - $t[] = "'" . dbesc($x[$idx]) . "'"; - else - $t[] = $x[$idx]; - } - } - } - return(implode(',', $t)); +function ids_to_querystr($arr, $idx = 'id', $quote = false) +{ + $t = []; + if ($arr) { + foreach ($arr as $x) { + if (! in_array($x[$idx], $t)) { + if ($quote) { + $t[] = "'" . dbesc($x[$idx]) . "'"; + } else { + $t[] = $x[$idx]; + } + } + } + } + return(implode(',', $t)); } /** * @brief array_elm_to_str($arr,$elm,$delim = ',') extract unique individual elements from an array of arrays and return them as a string separated by a delimiter - * similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option + * similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option * empty elements (evaluated after trim()) are ignored. * @param $arr array * @param $elm array key to extract from sub-array @@ -2453,24 +2592,26 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) { * @returns string */ -function array_elm_to_str($arr,$elm,$delim = ',',$each = 'trim') { +function array_elm_to_str($arr, $elm, $delim = ',', $each = 'trim') +{ - $tmp = []; - if($arr && is_array($arr)) { - foreach($arr as $x) { - if(is_array($x) && array_key_exists($elm,$x)) { - $z = $each($x[$elm]); - if(($z) && (! in_array($z,$tmp))) { - $tmp[] = $z; - } - } - } - } - return implode($delim,$tmp); + $tmp = []; + if ($arr && is_array($arr)) { + foreach ($arr as $x) { + if (is_array($x) && array_key_exists($elm, $x)) { + $z = $each($x[$elm]); + if (($z) && (! in_array($z, $tmp))) { + $tmp[] = $z; + } + } + } + } + return implode($delim, $tmp); } -function trim_and_unpunify($s) { - return unpunify(trim($s)); +function trim_and_unpunify($s) +{ + return unpunify(trim($s)); } @@ -2486,97 +2627,109 @@ function trim_and_unpunify($s) { * @param bool $abook If true also include the abook info * @param number $effective_uid */ -function xchan_query(&$items, $abook = true, $effective_uid = 0) { - $arr = []; +function xchan_query(&$items, $abook = true, $effective_uid = 0) +{ + $arr = []; - if($items && count($items)) { + if ($items && count($items)) { + if ($effective_uid) { + for ($x = 0; $x < count($items); $x++) { + $items[$x]['real_uid'] = $items[$x]['uid']; + $items[$x]['uid'] = $effective_uid; + } + } - if($effective_uid) { - for($x = 0; $x < count($items); $x ++) { - $items[$x]['real_uid'] = $items[$x]['uid']; - $items[$x]['uid'] = $effective_uid; - } - } - - foreach($items as $item) { - if($item['owner_xchan'] && (! in_array("'" . dbesc($item['owner_xchan']) . "'",$arr))) - $arr[] = "'" . dbesc($item['owner_xchan']) . "'"; - if($item['author_xchan'] && (! in_array("'" . dbesc($item['author_xchan']) . "'",$arr))) - $arr[] = "'" . dbesc($item['author_xchan']) . "'"; - } - } - if(count($arr)) { - if($abook) { - $chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d + foreach ($items as $item) { + if ($item['owner_xchan'] && (! in_array("'" . dbesc($item['owner_xchan']) . "'", $arr))) { + $arr[] = "'" . dbesc($item['owner_xchan']) . "'"; + } + if ($item['author_xchan'] && (! in_array("'" . dbesc($item['author_xchan']) . "'", $arr))) { + $arr[] = "'" . dbesc($item['author_xchan']) . "'"; + } + } + } + if (count($arr)) { + if ($abook) { + $chans = q( + "select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") order by hubloc_primary desc", - intval($item['uid']) - ); - } - else { - $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash + intval($item['uid']) + ); + } else { + $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") order by hubloc_primary desc"); - } - $xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown', 'anon')"); - if(! $chans) - $chans = $xchans; - else - $chans = array_merge($xchans,$chans); - } + } + $xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and xchan_network in ('rss','unknown', 'anon')"); + if (! $chans) { + $chans = $xchans; + } else { + $chans = array_merge($xchans, $chans); + } + } - if($items && count($items) && $chans && count($chans)) { - for($x = 0; $x < count($items); $x ++) { - $items[$x]['owner'] = find_xchan_in_array($items[$x]['owner_xchan'],$chans); - $items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'],$chans); - } - } + if ($items && count($items) && $chans && count($chans)) { + for ($x = 0; $x < count($items); $x++) { + $items[$x]['owner'] = find_xchan_in_array($items[$x]['owner_xchan'], $chans); + $items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'], $chans); + } + } } -function xchan_mail_query(&$item) { - $arr = []; - $chans = null; - if($item) { - if($item['from_xchan'] && (! in_array("'" . dbesc($item['from_xchan']) . "'",$arr))) - $arr[] = "'" . dbesc($item['from_xchan']) . "'"; - if($item['to_xchan'] && (! in_array("'" . dbesc($item['to_xchan']) . "'",$arr))) - $arr[] = "'" . dbesc($item['to_xchan']) . "'"; - } +function xchan_mail_query(&$item) +{ + $arr = []; + $chans = null; + if ($item) { + if ($item['from_xchan'] && (! in_array("'" . dbesc($item['from_xchan']) . "'", $arr))) { + $arr[] = "'" . dbesc($item['from_xchan']) . "'"; + } + if ($item['to_xchan'] && (! in_array("'" . dbesc($item['to_xchan']) . "'", $arr))) { + $arr[] = "'" . dbesc($item['to_xchan']) . "'"; + } + } - if(count($arr)) { - $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash + if (count($arr)) { + $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1"); - } - if($chans) { - $item['from'] = find_xchan_in_array($item['from_xchan'],$chans); - $item['to'] = find_xchan_in_array($item['to_xchan'],$chans); - } + } + if ($chans) { + $item['from'] = find_xchan_in_array($item['from_xchan'], $chans); + $item['to'] = find_xchan_in_array($item['to_xchan'], $chans); + } } -function find_xchan_in_array($xchan,$arr) { - if(count($arr)) { - foreach($arr as $x) { - if($x['xchan_hash'] === $xchan) { - return $x; - } - } - } - return []; +function find_xchan_in_array($xchan, $arr) +{ + if (count($arr)) { + foreach ($arr as $x) { + if ($x['xchan_hash'] === $xchan) { + return $x; + } + } + } + return []; } -function get_rel_link($j,$rel) { - if(is_array($j) && ($j)) - foreach($j as $l) - if(is_array($l) && array_key_exists('rel',$l) && $l['rel'] === $rel && array_key_exists('href',$l)) - return $l['href']; +function get_rel_link($j, $rel) +{ + if (is_array($j) && ($j)) { + foreach ($j as $l) { + if (is_array($l) && array_key_exists('rel', $l) && $l['rel'] === $rel && array_key_exists('href', $l)) { + return $l['href']; + } + } + } - return ''; + return ''; } // Lots of code to write here -function magic_link($s) { - return $s; +function magic_link($s) +{ + return $s; } /** @@ -2585,9 +2738,11 @@ function magic_link($s) { * @param[in,out] array &$arr * @param bool $escape (optional) default false */ -function stringify_array_elms(&$arr, $escape = false) { - for($x = 0; $x < count($arr); $x ++) - $arr[$x] = "'" . (($escape) ? dbesc($arr[$x]) : $arr[$x]) . "'"; +function stringify_array_elms(&$arr, $escape = false) +{ + for ($x = 0; $x < count($arr); $x++) { + $arr[$x] = "'" . (($escape) ? dbesc($arr[$x]) : $arr[$x]) . "'"; + } } @@ -2598,12 +2753,13 @@ function stringify_array_elms(&$arr, $escape = false) { * @param bool $escape (optional) default false * @return string */ -function stringify_array($arr, $escape = false) { - if($arr) { - stringify_array_elms($arr, $escape); - return(implode(',',$arr)); - } - return EMPTY_STR; +function stringify_array($arr, $escape = false) +{ + if ($arr) { + stringify_array_elms($arr, $escape); + return(implode(',', $arr)); + } + return EMPTY_STR; } @@ -2613,58 +2769,59 @@ function stringify_array($arr, $escape = false) { * @param string $json The original JSON string to process. * @return string Indented version of the original JSON string. */ -function jindent($json) { +function jindent($json) +{ - $result = ''; - $pos = 0; - $strLen = strlen($json); - $indentStr = ' '; - $newLine = "\n"; - $prevChar = ''; - $outOfQuotes = true; + $result = ''; + $pos = 0; + $strLen = strlen($json); + $indentStr = ' '; + $newLine = "\n"; + $prevChar = ''; + $outOfQuotes = true; - if (is_array($json)) { - btlogger('is an array', LOGGER_DATA); - $json = json_encode($json,JSON_UNESCAPED_SLASHES); - } + if (is_array($json)) { + btlogger('is an array', LOGGER_DATA); + $json = json_encode($json, JSON_UNESCAPED_SLASHES); + } - for ($i = 0; $i <= $strLen; $i++) { - // Grab the next character in the string. - $char = substr($json, $i, 1); + for ($i = 0; $i <= $strLen; $i++) { + // Grab the next character in the string. + $char = substr($json, $i, 1); - // Are we inside a quoted string? - if ($char == '"' && $prevChar != '\\') { - $outOfQuotes = !$outOfQuotes; - } - // If this character is the end of an element, - // output a new line and indent the next line. - elseif(($char == '}' || $char == ']') && $outOfQuotes) { - $result .= $newLine; - $pos --; - for ($j = 0; $j < $pos; $j++) { - $result .= $indentStr; - } - } + // Are we inside a quoted string? + if ($char == '"' && $prevChar != '\\') { + $outOfQuotes = !$outOfQuotes; + } + // If this character is the end of an element, + // output a new line and indent the next line. + elseif (($char == '}' || $char == ']') && $outOfQuotes) { + $result .= $newLine; + $pos--; + for ($j = 0; $j < $pos; $j++) { + $result .= $indentStr; + } + } - // Add the character to the result string. - $result .= $char; + // Add the character to the result string. + $result .= $char; - // If the last character was the beginning of an element, - // output a new line and indent the next line. - if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) { - $result .= $newLine; - if ($char == '{' || $char == '[') { - $pos ++; - } + // If the last character was the beginning of an element, + // output a new line and indent the next line. + if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) { + $result .= $newLine; + if ($char == '{' || $char == '[') { + $pos++; + } - for ($j = 0; $j < $pos; $j++) { - $result .= $indentStr; - } - } - $prevChar = $char; - } + for ($j = 0; $j < $pos; $j++) { + $result .= $indentStr; + } + } + $prevChar = $char; + } - return $result; + return $result; } /** @@ -2672,28 +2829,29 @@ function jindent($json) { * * @return string with parsed HTML */ -function design_tools() { +function design_tools() +{ - $channel = channelx_by_n(App::$profile['profile_uid']); - $sys = false; + $channel = channelx_by_n(App::$profile['profile_uid']); + $sys = false; - if(App::$is_sys && is_site_admin()) { - require_once('include/channel.php'); - $channel = get_sys_channel(); - $sys = true; - } + if (App::$is_sys && is_site_admin()) { + require_once('include/channel.php'); + $channel = get_sys_channel(); + $sys = true; + } - $who = $channel['channel_address']; + $who = $channel['channel_address']; - return replace_macros(get_markup_template('design_tools.tpl'), array( - '$title' => t('Design Tools'), - '$who' => $who, - '$sys' => $sys, - '$blocks' => t('Blocks'), - '$menus' => t('Menus'), - '$layout' => t('Layouts'), - '$pages' => t('Pages') - )); + return replace_macros(get_markup_template('design_tools.tpl'), array( + '$title' => t('Design Tools'), + '$who' => $who, + '$sys' => $sys, + '$blocks' => t('Blocks'), + '$menus' => t('Menus'), + '$layout' => t('Layouts'), + '$pages' => t('Pages') + )); } /** @@ -2701,35 +2859,36 @@ function design_tools() { * * @return string */ -function website_portation_tools() { +function website_portation_tools() +{ - $channel = App::get_channel(); - $sys = false; + $channel = App::get_channel(); + $sys = false; - if(App::$is_sys && is_site_admin()) { - require_once('include/channel.php'); - $channel = get_sys_channel(); - $sys = true; - } + if (App::$is_sys && is_site_admin()) { + require_once('include/channel.php'); + $channel = get_sys_channel(); + $sys = true; + } - return replace_macros(get_markup_template('website_portation_tools.tpl'), array( - '$title' => t('Import'), - '$import_label' => t('Import website...'), - '$import_placeholder' => t('Select folder to import'), - '$file_upload_text' => t('Import from a zipped folder:'), - '$file_import_text' => t('Import from cloud files:'), - '$desc' => t('/cloud/channel/path/to/folder'), - '$hint' => t('Enter path to website files'), - '$select' => t('Select folder'), - '$export_label' => t('Export website...'), - '$file_download_text' => t('Export to a zip file'), - '$filename_desc' => t('website.zip'), - '$filename_hint' => t('Enter a name for the zip file.'), - '$cloud_export_text' => t('Export to cloud files'), - '$cloud_export_desc' => t('/path/to/export/folder'), - '$cloud_export_hint' => t('Enter a path to a cloud files destination.'), - '$cloud_export_select' => t('Specify folder'), - )); + return replace_macros(get_markup_template('website_portation_tools.tpl'), array( + '$title' => t('Import'), + '$import_label' => t('Import website...'), + '$import_placeholder' => t('Select folder to import'), + '$file_upload_text' => t('Import from a zipped folder:'), + '$file_import_text' => t('Import from cloud files:'), + '$desc' => t('/cloud/channel/path/to/folder'), + '$hint' => t('Enter path to website files'), + '$select' => t('Select folder'), + '$export_label' => t('Export website...'), + '$file_download_text' => t('Export to a zip file'), + '$filename_desc' => t('website.zip'), + '$filename_hint' => t('Enter a name for the zip file.'), + '$cloud_export_text' => t('Export to cloud files'), + '$cloud_export_desc' => t('/path/to/export/folder'), + '$cloud_export_hint' => t('Enter a path to a cloud files destination.'), + '$cloud_export_select' => t('Specify folder'), + )); } /** @@ -2739,12 +2898,14 @@ function website_portation_tools() { * @param array $haystack * @return bool */ -function in_arrayi($needle, $haystack) { - return in_array(strtolower($needle), array_map('strtolower', $haystack)); +function in_arrayi($needle, $haystack) +{ + return in_array(strtolower($needle), array_map('strtolower', $haystack)); } -function normalise_openid($s) { - return trim(str_replace(array('http://','https://'),array('',''),$s),'/'); +function normalise_openid($s) +{ + return trim(str_replace(array('http://','https://'), array('',''), $s), '/'); } /** @@ -2754,26 +2915,27 @@ function normalise_openid($s) { * * @return string with additional URL parameters */ -function extra_query_args() { - $s = ''; - if(count($_GET)) { - foreach($_GET as $k => $v) { - // these are request vars we don't want to duplicate - if(! in_array($k, array('req','f','zid','page','PHPSESSID'))) { - $s .= '&' . $k . '=' . urlencode($v); - } - } - } - if(count($_POST)) { - foreach($_POST as $k => $v) { - // these are request vars we don't want to duplicate - if(! in_array($k, array('req','f','zid','page','PHPSESSID'))) { - $s .= '&' . $k . '=' . urlencode($v); - } - } - } +function extra_query_args() +{ + $s = ''; + if (count($_GET)) { + foreach ($_GET as $k => $v) { + // these are request vars we don't want to duplicate + if (! in_array($k, array('req','f','zid','page','PHPSESSID'))) { + $s .= '&' . $k . '=' . urlencode($v); + } + } + } + if (count($_POST)) { + foreach ($_POST as $k => $v) { + // these are request vars we don't want to duplicate + if (! in_array($k, array('req','f','zid','page','PHPSESSID'))) { + $s .= '&' . $k . '=' . urlencode($v); + } + } + } - return $s; + return $s; } /** @@ -2789,195 +2951,195 @@ function extra_query_args() { * @param bool $in_network default true * @return bool true if replaced, false if not replaced */ -function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) { +function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) +{ - $channel = App::get_channel(); - $replaced = false; - $r = null; - $match = []; + $channel = App::get_channel(); + $replaced = false; + $r = null; + $match = []; - $termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); - $termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype); + $termtype = ((strpos($tag, '#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); + $termtype = ((strpos($tag, '@') === 0) ? TERM_MENTION : $termtype); - // Is it a hashtag of some kind? + // Is it a hashtag of some kind? - if ( in_array($termtype, [ TERM_HASHTAG ] )) { - // if the tag is already replaced... - if((strpos($tag,'[zrl=')) || (strpos($tag,'[url='))) { - // ...do nothing - return $replaced; - } + if (in_array($termtype, [ TERM_HASHTAG ])) { + // if the tag is already replaced... + if ((strpos($tag, '[zrl=')) || (strpos($tag, '[url='))) { + // ...do nothing + return $replaced; + } - if(! $replaced) { + if (! $replaced) { + // double-quoted hashtags: base tag has the htmlentity name only - // double-quoted hashtags: base tag has the htmlentity name only + if ((substr($tag, 0, 7) === '#"') && (substr($tag, -6, 6) === '"')) { + $basetag = substr($tag, 7); + $basetag = substr($basetag, 0, -6); + } elseif ((substr($tag, 0, 2) === '#"') && (substr($tag, -1, 1) === '"')) { + $basetag = substr($tag, 2); + $basetag = substr($basetag, 0, -1); + } else { + $basetag = substr($tag, 1); + } - if((substr($tag,0,7) === '#"') && (substr($tag,-6,6) === '"')) { - $basetag = substr($tag,7); - $basetag = substr($basetag,0,-6); - } - elseif((substr($tag,0,2) === '#"') && (substr($tag,-1,1) === '"')) { - $basetag = substr($tag,2); - $basetag = substr($basetag,0,-1); - } - else - $basetag = substr($tag,1); + // create text for link - // create text for link + $url = z_root() . '/search?tag=' . rawurlencode($basetag); + $newtag = '#[zrl=' . z_root() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]'; - $url = z_root() . '/search?tag=' . rawurlencode($basetag); - $newtag = '#[zrl=' . z_root() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]'; + // replace tag by the link. Make sure to not replace something in the middle of a word - // replace tag by the link. Make sure to not replace something in the middle of a word + $body = preg_replace('/(? $replaced, + 'termtype' => $termtype, + 'term' => $basetag, + 'url' => $url, + 'contact' => [], + 'access_tag' => '', + ]]; + } - $str_tags .= $newtag; - } - return [ [ - 'replaced' => $replaced, - 'termtype' => $termtype, - 'term' => $basetag, - 'url' => $url, - 'contact' => [], - 'access_tag' => '', - ]]; - } + // END hashtags - // END hashtags + // BEGIN mentions - // BEGIN mentions + if (in_array($termtype, [ TERM_MENTION ])) { + // The @! tag will alter permissions - if ( in_array($termtype, [ TERM_MENTION ] )) { + // $in_network is set to false to avoid false positives on posts originating + // on a network which does not implement privacy tags or implements them differently. - // The @! tag will alter permissions + $exclusive = (((strpos(substr($tag, 1), '!') === 0) && $in_network) ? true : false); - // $in_network is set to false to avoid false positives on posts originating - // on a network which does not implement privacy tags or implements them differently. + // is it already replaced? + if (strpos($tag, "[zrl=") || strpos($tag, "[url=")) { + return $replaced; + } - $exclusive = (((strpos(substr($tag,1), '!') === 0) && $in_network) ? true : false); + // get the channel name + // First extract the name or name fragment we are going to replace - // is it already replaced? - if(strpos($tag,"[zrl=") || strpos($tag,"[url=")) - return $replaced; + $name = substr($tag, (($exclusive) ? 2 : 1)); + $newname = $name; // make a copy that we can mess with + $tagcid = 0; - // get the channel name - // First extract the name or name fragment we are going to replace + $r = null; - $name = substr($tag,(($exclusive) ? 2 : 1)); - $newname = $name; // make a copy that we can mess with - $tagcid = 0; + // is it some generated (autocompleted) name? - $r = null; + if (substr($name, 0, 1) === '{' && substr($name, -1, 1) === '}') { + $newname = substr($name, 1); + $newname = substr($newname, 0, -1); - // is it some generated (autocompleted) name? + $r = q( + "select * from xchan where xchan_addr = '%s' or xchan_hash = '%s' or xchan_url = '%s'", + dbesc($newname), + dbesc($newname), + dbesc($newname) + ); + } - if(substr($name,0,1) === '{' && substr($name,-1,1) === '}') { - $newname = substr($name,1); - $newname = substr($newname,0,-1); + if (! $r) { + // look for matching names in the address book - $r = q("select * from xchan where xchan_addr = '%s' or xchan_hash = '%s' or xchan_url = '%s'", - dbesc($newname), - dbesc($newname), - dbesc($newname) - ); - } + // Double quote the entire mentioned term to include special characters + // such as spaces and some punctuation. - if(! $r) { + // We see this after input filtering so quotes have been html entity encoded - // look for matching names in the address book + if ((substr($name, 0, 6) === '"') && (substr($name, -6, 6) === '"')) { + $newname = substr($name, 6); + $newname = substr($newname, 0, -6); + } elseif ((substr($name, 0, 1) === '"') && (substr($name, -1, 1) === '"')) { + $newname = substr($name, 1); + $newname = substr($newname, 0, -1); + } - // Double quote the entire mentioned term to include special characters - // such as spaces and some punctuation. + // select someone from this user's contacts by name - // We see this after input filtering so quotes have been html entity encoded - - if((substr($name,0,6) === '"') && (substr($name,-6,6) === '"')) { - $newname = substr($name,6); - $newname = substr($newname,0,-6); - } - elseif((substr($name,0,1) === '"') && (substr($name,-1,1) === '"')) { - $newname = substr($name,1); - $newname = substr($newname,0,-1); - } - - // select someone from this user's contacts by name - - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_name = '%s' AND abook_channel = %d ", - dbesc($newname), - intval($profile_uid) - ); + dbesc($newname), + intval($profile_uid) + ); - // select anybody by full hubloc_addr + // select anybody by full hubloc_addr - if((! $r) && strpos($newname,'@')) { - $r = q("SELECT * FROM xchan left join hubloc on xchan_hash = hubloc_hash + if ((! $r) && strpos($newname, '@')) { + $r = q( + "SELECT * FROM xchan left join hubloc on xchan_hash = hubloc_hash WHERE hubloc_addr = '%s' ", - dbesc($newname) - ); - } + dbesc($newname) + ); + } - // select someone by attag or nick and the name passed in + // select someone by attag or nick and the name passed in - if(! $r) { - // strip user-supplied wildcards before running a wildcard search - $newname = str_replace('%','',$newname); - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + if (! $r) { + // strip user-supplied wildcards before running a wildcard search + $newname = str_replace('%', '', $newname); + $r = q( + "SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_addr like ('%s') AND abook_channel = %d ", - dbesc(((strpos($newname,'@')) ? $newname : $newname . '@%')), - intval($profile_uid) - ); - } - - } + dbesc(((strpos($newname, '@')) ? $newname : $newname . '@%')), + intval($profile_uid) + ); + } + } $fn_results = []; $access_tag = EMPTY_STR; - // some platforms prefer to mention people by username rather than display name. - // make this a personal choice by the publisher - - $tagpref = intval(PConfig::Get($profile_uid,'system','tag_username',Config::Get('system','tag_username',false))); - + // some platforms prefer to mention people by username rather than display name. + // make this a personal choice by the publisher + + $tagpref = intval(PConfig::Get($profile_uid, 'system', 'tag_username', Config::Get('system', 'tag_username', false))); + // $r is set if we found something - if ($r) { - if (array_key_exists('hubloc_network',$r)) { - $r = [ Libzot::zot_record_preferred($r) ]; - } - else { - $r = [ Libzot::zot_record_preferred($r, 'xchan_network') ]; - } - } + if ($r) { + if (array_key_exists('hubloc_network', $r)) { + $r = [ Libzot::zot_record_preferred($r) ]; + } else { + $r = [ Libzot::zot_record_preferred($r, 'xchan_network') ]; + } + } if ($r) { foreach ($r as $xc) { $profile = $xc['xchan_url']; - // $tagpref - // 0 use display name - // 1 use username@host - // 2 use 'display name (username@host)' - // 127 use display name outbound and don't change inbound - - $newname = $xc['xchan_name']; + // $tagpref + // 0 use display name + // 1 use username@host + // 2 use 'display name (username@host)' + // 127 use display name outbound and don't change inbound - if ($tagpref === 1 && $xc['xchan_addr']) { - $newname = $xc['xchan_addr']; - } - if ($tagpref === 2 && $xc['xchan_addr']) { - $newname = sprintf( t('%1$s (%2$s)'), $xc['xchan_name'], $newname); - } + $newname = $xc['xchan_name']; + + if ($tagpref === 1 && $xc['xchan_addr']) { + $newname = $xc['xchan_addr']; + } + if ($tagpref === 2 && $xc['xchan_addr']) { + $newname = sprintf(t('%1$s (%2$s)'), $xc['xchan_name'], $newname); + } // add the channel's xchan_hash to $access_tag if exclusive if ($exclusive) { $access_tag = 'cid:' . $xc['xchan_hash']; @@ -2985,20 +3147,21 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) // if there is a url for this channel - if(isset($profile)) { + if (isset($profile)) { $replaced = true; //create profile link - $profile = str_replace(',','%2c',$profile); + $profile = str_replace(',', '%2c', $profile); $url = $profile; - $zrl = (($xc['xchan_network'] === 'zot6') ? 'zrl' : 'url'); - $newtag = '@' . (($exclusive) ? '!' : '') . '[' . $zrl . '=' . $profile . ']' . $newname . '[/' . $zrl . ']'; - - $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); + $zrl = (($xc['xchan_network'] === 'zot6') ? 'zrl' : 'url'); + $newtag = '@' . (($exclusive) ? '!' : '') . '[' . $zrl . '=' . $profile . ']' . $newname . '[/' . $zrl . ']'; + + $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); // append tag to str_tags - if(! stristr($str_tags,$newtag)) { - if(strlen($str_tags)) + if (! stristr($str_tags, $newtag)) { + if (strlen($str_tags)) { $str_tags .= ','; + } $str_tags .= $newtag; } } @@ -3012,32 +3175,29 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) 'access_tag' => $access_tag, 'contact' => (($r) ? $xc : []), ]; - - } - - } - else { - + } + } else { // check for a group/collection exclusion tag // note that we aren't setting $replaced even though we're replacing text. // This tag isn't going to get a term attached to it. It's only used for - // access control. + // access control. - if(local_channel() && local_channel() == $profile_uid) { - $grp = AccessList::byname($profile_uid,$name); - if($grp) { - $g = q("select * from pgrp where id = %d and visible = 1 limit 1", + if (local_channel() && local_channel() == $profile_uid) { + $grp = AccessList::byname($profile_uid, $name); + if ($grp) { + $g = q( + "select * from pgrp where id = %d and visible = 1 limit 1", intval($grp) ); - if($g && $exclusive) { - $access_tag .= 'gid:' . $g[0]['hash']; + if ($g && $exclusive) { + $access_tag .= 'gid:' . $g[0]['hash']; } $channel = App::get_channel(); - if($channel) { - $replaced = true; - $newname = $channel['channel_name'] . ' (' . $g[0]['gname'] . ')'; - $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/lists/view/' . $g[0]['hash'] . ']' . $newname . '[/zrl]'; + if ($channel) { + $replaced = true; + $newname = $channel['channel_name'] . ' (' . $g[0]['gname'] . ')'; + $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/lists/view/' . $g[0]['hash'] . ']' . $newname . '[/zrl]'; $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); } } @@ -3045,19 +3205,20 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) // if there is a url for this channel - if(isset($profile)) { + if (isset($profile)) { $replaced = true; //create profile link - $profile = str_replace(',','%2c',$profile); + $profile = str_replace(',', '%2c', $profile); $url = $profile; $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]'; $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); // append tag to str_tags - if(! stristr($str_tags,$newtag)) { - if(strlen($str_tags)) + if (! stristr($str_tags, $newtag)) { + if (strlen($str_tags)) { $str_tags .= ','; + } $str_tags .= $newtag; } } @@ -3074,27 +3235,26 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) } return $fn_results; - } -function linkify_tags(&$body, $uid, $in_network = true) { - $str_tags = EMPTY_STR; - $results = []; +function linkify_tags(&$body, $uid, $in_network = true) +{ + $str_tags = EMPTY_STR; + $results = []; - $tags = get_tags($body); + $tags = get_tags($body); - if(is_array($tags) && count($tags)) { - foreach($tags as $tag) { + if (is_array($tags) && count($tags)) { + foreach ($tags as $tag) { + $success = handle_tag($body, $str_tags, ($uid) ? $uid : App::$profile_uid, $tag, $in_network); - $success = handle_tag($body, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $in_network); + foreach ($success as $handled_tag) { + $results[] = [ 'success' => $handled_tag ]; + } + } + } - foreach($success as $handled_tag) { - $results[] = [ 'success' => $handled_tag ]; - } - } - } - - return $results; + return $results; } /** @@ -3107,77 +3267,77 @@ function linkify_tags(&$body, $uid, $in_network = true) { * @return string * @todo rename to get_icon_from_type() */ -function getIconFromType($type) { - $iconMap = array( - //Folder - t('Collection') => 'fa-folder-o', - 'multipart/mixed' => 'fa-folder-o', //dirs in attach use this mime type - //Common file - 'application/octet-stream' => 'fa-file-o', - //Text - 'text/plain' => 'fa-file-text-o', - 'text/markdown' => 'fa-file-text-o', - 'text/bbcode' => 'fa-file-text-o', - 'text/x-multicode' => 'fa-file-text-o', - 'text/html' => 'fa-file-text-o', - 'application/msword' => 'fa-file-word-o', - 'application/pdf' => 'fa-file-pdf-o', - 'application/vnd.oasis.opendocument.text' => 'fa-file-word-o', - 'application/epub+zip' => 'fa-book', - //Spreadsheet - 'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel-o', - 'application/vnd.ms-excel' => 'fa-file-excel-o', - //Image - 'image/jpeg' => 'fa-picture-o', - 'image/png' => 'fa-picture-o', - 'image/gif' => 'fa-picture-o', - 'image/svg+xml' => 'fa-picture-o', - //Archive - 'application/zip' => 'fa-file-archive-o', - 'application/x-rar-compressed' => 'fa-file-archive-o', - //Audio - 'audio/mpeg' => 'fa-file-audio-o', - 'audio/wav' => 'fa-file-audio-o', - 'application/ogg' => 'fa-file-audio-o', - 'audio/ogg' => 'fa-file-audio-o', - 'audio/webm' => 'fa-file-audio-o', - 'audio/mp4' => 'fa-file-audio-o', - //Video - 'video/quicktime' => 'fa-file-video-o', - 'video/webm' => 'fa-file-video-o', - 'video/mp4' => 'fa-file-video-o', - 'video/x-matroska' => 'fa-file-video-o' - ); +function getIconFromType($type) +{ + $iconMap = array( + //Folder + t('Collection') => 'fa-folder-o', + 'multipart/mixed' => 'fa-folder-o', //dirs in attach use this mime type + //Common file + 'application/octet-stream' => 'fa-file-o', + //Text + 'text/plain' => 'fa-file-text-o', + 'text/markdown' => 'fa-file-text-o', + 'text/bbcode' => 'fa-file-text-o', + 'text/x-multicode' => 'fa-file-text-o', + 'text/html' => 'fa-file-text-o', + 'application/msword' => 'fa-file-word-o', + 'application/pdf' => 'fa-file-pdf-o', + 'application/vnd.oasis.opendocument.text' => 'fa-file-word-o', + 'application/epub+zip' => 'fa-book', + //Spreadsheet + 'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel-o', + 'application/vnd.ms-excel' => 'fa-file-excel-o', + //Image + 'image/jpeg' => 'fa-picture-o', + 'image/png' => 'fa-picture-o', + 'image/gif' => 'fa-picture-o', + 'image/svg+xml' => 'fa-picture-o', + //Archive + 'application/zip' => 'fa-file-archive-o', + 'application/x-rar-compressed' => 'fa-file-archive-o', + //Audio + 'audio/mpeg' => 'fa-file-audio-o', + 'audio/wav' => 'fa-file-audio-o', + 'application/ogg' => 'fa-file-audio-o', + 'audio/ogg' => 'fa-file-audio-o', + 'audio/webm' => 'fa-file-audio-o', + 'audio/mp4' => 'fa-file-audio-o', + //Video + 'video/quicktime' => 'fa-file-video-o', + 'video/webm' => 'fa-file-video-o', + 'video/mp4' => 'fa-file-video-o', + 'video/x-matroska' => 'fa-file-video-o' + ); - $catMap = [ - 'application' => 'fa-file-code-o', - 'multipart' => 'fa-folder', - 'audio' => 'fa-file-audio-o', - 'video' => 'fa-file-video-o', - 'text' => 'fa-file-text-o', - 'image' => 'fa=file-picture-o', - 'message' => 'fa-file-text-o' - ]; + $catMap = [ + 'application' => 'fa-file-code-o', + 'multipart' => 'fa-folder', + 'audio' => 'fa-file-audio-o', + 'video' => 'fa-file-video-o', + 'text' => 'fa-file-text-o', + 'image' => 'fa=file-picture-o', + 'message' => 'fa-file-text-o' + ]; - $iconFromType = ''; + $iconFromType = ''; - if (array_key_exists($type, $iconMap)) { - $iconFromType = $iconMap[$type]; - } - else { - $parts = explode('/',$type); - if($parts[0] && $catMap[$parts[0]]) { - $iconFromType = $catMap[$parts[0]]; - } - } + if (array_key_exists($type, $iconMap)) { + $iconFromType = $iconMap[$type]; + } else { + $parts = explode('/', $type); + if ($parts[0] && $catMap[$parts[0]]) { + $iconFromType = $catMap[$parts[0]]; + } + } - if(! $iconFromType) { - $iconFromType = 'fa-file-o'; - } + if (! $iconFromType) { + $iconFromType = 'fa-file-o'; + } - return $iconFromType; + return $iconFromType; } /** @@ -3187,100 +3347,111 @@ function getIconFromType($type) { * @return string human readable formatted filesize * @todo rename to user_readable_size() */ -function userReadableSize($size) { - $ret = ''; - if (is_numeric($size)) { - $incr = 0; - $k = 1024; - $unit = array('bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); - while (($size / $k) >= 1){ - $incr++; - $size = round($size / $k, 2); - } - $ret = $size . ' ' . $unit[$incr]; - } +function userReadableSize($size) +{ + $ret = ''; + if (is_numeric($size)) { + $incr = 0; + $k = 1024; + $unit = array('bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); + while (($size / $k) >= 1) { + $incr++; + $size = round($size / $k, 2); + } + $ret = $size . ' ' . $unit[$incr]; + } - return $ret; + return $ret; } -function str_rot47($str) { - return strtr($str, - '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', - 'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO'); +function str_rot47($str) +{ + return strtr( + $str, + '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', + 'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO' + ); } -function string_replace($old,$new,&$s) { +function string_replace($old, $new, &$s) +{ - $x = str_replace($old,$new,$s); - $replaced = false; - if($x !== $s) { - $replaced = true; - } - $s = $x; - return $replaced; + $x = str_replace($old, $new, $s); + $replaced = false; + if ($x !== $s) { + $replaced = true; + } + $s = $x; + return $replaced; } -function json_url_replace($old,$new,&$s) { +function json_url_replace($old, $new, &$s) +{ - $old = str_replace('/','\\/',$old); - $new = str_replace('/','\\/',$new); + $old = str_replace('/', '\\/', $old); + $new = str_replace('/', '\\/', $new); - $x = str_replace($old,$new,$s); - $replaced = false; - if($x !== $s) { - $replaced = true; - } - $s = $x; - return $replaced; + $x = str_replace($old, $new, $s); + $replaced = false; + if ($x !== $s) { + $replaced = true; + } + $s = $x; + return $replaced; } -function item_url_replace($channel,&$item,$old,$new,$oldnick = '') { +function item_url_replace($channel, &$item, $old, $new, $oldnick = '') +{ - if($item['attach']) { - json_url_replace($old,$new,$item['attach']); - if($oldnick && ($oldnick !== $channel['channel_address'])) - json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['attach']); - } - if($item['object']) { - json_url_replace($old,$new,$item['object']); - if($oldnick && ($oldnick !== $channel['channel_address'])) - json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['object']); - } - if($item['target']) { - json_url_replace($old,$new,$item['target']); - if($oldnick && ($oldnick !== $channel['channel_address'])) - json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']); - } + if ($item['attach']) { + json_url_replace($old, $new, $item['attach']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + json_url_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['attach']); + } + } + if ($item['object']) { + json_url_replace($old, $new, $item['object']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + json_url_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['object']); + } + } + if ($item['target']) { + json_url_replace($old, $new, $item['target']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + json_url_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['target']); + } + } - $item['body'] = str_replace($old, $new, $item['body']); + $item['body'] = str_replace($old, $new, $item['body']); - if($oldnick && ($oldnick !== $channel['channel_address'])) { - $item['body'] = str_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['body']); - } - - $item['sig'] = Libzot::sign($item['body'],$channel['channel_prvkey']); - $item['item_verified'] = 1; - - $item['plink'] = str_replace($old,$new,$item['plink']); - if($oldnick && ($oldnick !== $channel['channel_address'])) - $item['plink'] = str_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['plink']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + $item['body'] = str_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['body']); + } - $item['llink'] = str_replace($old,$new,$item['llink']); - if($oldnick && ($oldnick !== $channel['channel_address'])) - $item['llink'] = str_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['llink']); + $item['sig'] = Libzot::sign($item['body'], $channel['channel_prvkey']); + $item['item_verified'] = 1; - if($item['term']) { - for($x = 0; $x < count($item['term']); $x ++) { - $item['term'][$x]['url'] = str_replace($old,$new,$item['term'][$x]['url']); - if($oldnick && ($oldnick !== $channel['channel_address'])) { - $item['term'][$x]['url'] = str_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['term'][$x]['url']); - } - } - } + $item['plink'] = str_replace($old, $new, $item['plink']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + $item['plink'] = str_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['plink']); + } + $item['llink'] = str_replace($old, $new, $item['llink']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + $item['llink'] = str_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['llink']); + } + + if ($item['term']) { + for ($x = 0; $x < count($item['term']); $x++) { + $item['term'][$x]['url'] = str_replace($old, $new, $item['term'][$x]['url']); + if ($oldnick && ($oldnick !== $channel['channel_address'])) { + $item['term'][$x]['url'] = str_replace('/' . $oldnick . '/', '/' . $channel['channel_address'] . '/', $item['term'][$x]['url']); + } + } + } } @@ -3289,11 +3460,13 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') { * * @param[in,out] array &$item */ -function sanitise_acl(&$item) { - if (strlen($item)) - $item = '<' . notags(trim(urldecode($item))) . '>'; - else - unset($item); +function sanitise_acl(&$item) +{ + if (strlen($item)) { + $item = '<' . notags(trim(urldecode($item))) . '>'; + } else { + unset($item); + } } /** @@ -3302,20 +3475,22 @@ function sanitise_acl(&$item) { * @param array $p * @return array */ -function perms2str($p) { - $ret = ''; +function perms2str($p) +{ + $ret = ''; - if (is_array($p)) - $tmp = $p; - else - $tmp = explode(',', $p); + if (is_array($p)) { + $tmp = $p; + } else { + $tmp = explode(',', $p); + } - if (is_array($tmp)) { - array_walk($tmp, 'sanitise_acl'); - $ret = implode('', $tmp); - } + if (is_array($tmp)) { + array_walk($tmp, 'sanitise_acl'); + $ret = implode('', $tmp); + } - return $ret; + return $ret; } /** @@ -3327,26 +3502,29 @@ function perms2str($p) { * @param string $s * @return array */ -function expand_acl($s) { - $ret = []; +function expand_acl($s) +{ + $ret = []; - if(strlen($s)) { - $t = str_replace('<','',$s); - $a = explode('>',$t); - foreach($a as $aa) { - if($aa) - $ret[] = $aa; - } - } + if (strlen($s)) { + $t = str_replace('<', '', $s); + $a = explode('>', $t); + foreach ($a as $aa) { + if ($aa) { + $ret[] = $aa; + } + } + } - return $ret; + return $ret; } -function acl2json($s) { - $s = expand_acl($s); - $s = json_encode($s); +function acl2json($s) +{ + $s = expand_acl($s); + $s = json_encode($s); - return $s; + return $s; } /** @@ -3368,31 +3546,33 @@ function acl2json($s) { * @param string $current * @return string HTML code for dropdown */ -function pdl_selector($uid, $current='') { - $o = ''; +function pdl_selector($uid, $current = '') +{ + $o = ''; - $sql_extra = item_permissions_sql($uid); + $sql_extra = item_permissions_sql($uid); - $r = q("select iconfig.*, mid from iconfig left join item on iconfig.iid = item.id + $r = q( + "select iconfig.*, mid from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' $sql_extra order by v asc", - intval($uid) - ); + intval($uid) + ); - $arr = array('channel_id' => $uid, 'current' => $current, 'entries' => $r); - call_hooks('pdl_selector', $arr); + $arr = array('channel_id' => $uid, 'current' => $current, 'entries' => $r); + call_hooks('pdl_selector', $arr); - $entries = $arr['entries']; - $current = $arr['current']; + $entries = $arr['entries']; + $current = $arr['current']; - $o .= ''; + $entries[] = array('title' => t('Default'), 'mid' => ''); + foreach ($entries as $selection) { + $selected = (($selection == $current) ? ' selected="selected" ' : ''); + $o .= ""; + } - $o .= ''; - return $o; + $o .= ''; + return $o; } /** @@ -3406,27 +3586,27 @@ function pdl_selector($uid, $current='') { * @param array $arr multi-dimensional array * @return one-dimensional array */ -function flatten_array_recursive($arr) { +function flatten_array_recursive($arr) +{ - $ret = []; + $ret = []; - if(! ($arr && is_array($arr))) { - return $ret; - } + if (! ($arr && is_array($arr))) { + return $ret; + } - foreach($arr as $a) { - if(is_array($a)) { - $tmp = flatten_array_recursive($a); - if($tmp) { - $ret = array_merge($ret, $tmp); - } - } - elseif(isset($a)) { - $ret[] = $a; - } - } + foreach ($arr as $a) { + if (is_array($a)) { + $tmp = flatten_array_recursive($a); + if ($tmp) { + $ret = array_merge($ret, $tmp); + } + } elseif (isset($a)) { + $ret[] = $a; + } + } - return($ret); + return($ret); } /** @@ -3436,43 +3616,47 @@ function flatten_array_recursive($arr) { * @param string $lang Which language should be highlighted * @return string * Important: The returned text has the text pattern 'http' translated to '%eY9-!' which should be converted back - * after further processing. This was done to prevent oembed links from occurring inside code blocks. + * after further processing. This was done to prevent oembed links from occurring inside code blocks. * See include/bbcode.php */ -function text_highlight($s, $lang, $options) { +function text_highlight($s, $lang, $options) +{ - if($lang === 'js') - $lang = 'javascript'; + if ($lang === 'js') { + $lang = 'javascript'; + } - if($lang === 'json') { - $lang = 'javascript'; - if(! strpos(trim($s), "\n")) - $s = jindent($s); - } + if ($lang === 'json') { + $lang = 'javascript'; + if (! strpos(trim($s), "\n")) { + $s = jindent($s); + } + } - $arr = [ - 'text' => $s, - 'language' => $lang, - 'options' => $options, - 'success' => false - ]; + $arr = [ + 'text' => $s, + 'language' => $lang, + 'options' => $options, + 'success' => false + ]; - /** - * @hooks text_highlight - * * \e string \b text - * * \e string \b language - * * \e boolean \b success default false - */ - call_hooks('text_highlight', $arr); + /** + * @hooks text_highlight + * * \e string \b text + * * \e string \b language + * * \e boolean \b success default false + */ + call_hooks('text_highlight', $arr); - if($arr['success']) - $o = $arr['text']; - else - $o = $s; + if ($arr['success']) { + $o = $arr['text']; + } else { + $o = $s; + } - $o = str_replace('http','%eY9-!',$o); + $o = str_replace('http', '%eY9-!', $o); - return('' . $o . ''); + return('' . $o . ''); } // function to convert multi-dimensional array to xml @@ -3486,26 +3670,28 @@ function text_highlight($s, $lang, $options) { // save as xml file // echo (($xml->asXML('data.xml')) ? 'Your XML file has been generated successfully!' : 'Error generating XML file!'); -function arrtoxml($root_elem,$arr) { - $xml = new SimpleXMLElement('<' . $root_elem . '>', null, false); - array2XML($xml,$arr); +function arrtoxml($root_elem, $arr) +{ + $xml = new SimpleXMLElement('<' . $root_elem . '>', null, false); + array2XML($xml, $arr); - return $xml->asXML(); + return $xml->asXML(); } -function array2XML($obj, $array) { - foreach ($array as $key => $value) { - if(is_numeric($key)) - $key = 'item' . $key; +function array2XML($obj, $array) +{ + foreach ($array as $key => $value) { + if (is_numeric($key)) { + $key = 'item' . $key; + } - if(is_array($value)) { - $node = $obj->addChild($key); - array2XML($node, $value); - } - else { - $obj->addChild($key, htmlspecialchars($value)); - } - } + if (is_array($value)) { + $node = $obj->addChild($key); + array2XML($node, $value); + } else { + $obj->addChild($key, htmlspecialchars($value)); + } + } } /** @@ -3518,177 +3704,193 @@ function array2XML($obj, $array) { * @param array $binary_fields - fields which will be cleansed with dbescbin rather than dbesc; this is critical for postgres * @return bool|PDOStatement */ -function create_table_from_array($table, $arr, $binary_fields = []) { +function create_table_from_array($table, $arr, $binary_fields = []) +{ - if(! ($arr && $table)) - return false; + if (! ($arr && $table)) { + return false; + } - $columns = db_columns($table); + $columns = db_columns($table); - $clean = []; - foreach($arr as $k => $v) { + $clean = []; + foreach ($arr as $k => $v) { + if (! in_array($k, $columns)) { + continue; + } - if(! in_array($k,$columns)) { - continue; - } + $matches = false; + if (preg_match('/([^a-zA-Z0-9\-\_\.])/', $k, $matches)) { + return false; + } + if (in_array($k, $binary_fields)) { + $clean[$k] = dbescbin($v); + } else { + $clean[$k] = dbesc($v); + } + } + $r = dbq("INSERT INTO " . TQUOT . $table . TQUOT . " (" . TQUOT + . implode(TQUOT . ', ' . TQUOT, array_keys($clean)) + . TQUOT . ") VALUES ('" + . implode("', '", array_values($clean)) + . "')"); - $matches = false; - if(preg_match('/([^a-zA-Z0-9\-\_\.])/',$k,$matches)) { - return false; - } - if(in_array($k,$binary_fields)) { - $clean[$k] = dbescbin($v); - } - else { - $clean[$k] = dbesc($v); - } - } - $r = dbq("INSERT INTO " . TQUOT . $table . TQUOT . " (" . TQUOT - . implode(TQUOT . ', ' . TQUOT, array_keys($clean)) - . TQUOT . ") VALUES ('" - . implode("', '", array_values($clean)) - . "')" - ); - - return $r; + return $r; } -function share_shield($m) { - return str_replace($m[1],'!=+=+=!' . base64url_encode($m[1]) . '=+!=+!=',$m[0]); +function share_shield($m) +{ + return str_replace($m[1], '!=+=+=!' . base64url_encode($m[1]) . '=+!=+!=', $m[0]); } -function share_unshield($m) { - $x = str_replace(array('!=+=+=!','=+!=+!='),array('',''),$m[1]); - return str_replace($m[1], base64url_decode($x), $m[0]); +function share_unshield($m) +{ + $x = str_replace(array('!=+=+=!','=+!=+!='), array('',''), $m[1]); + return str_replace($m[1], base64url_decode($x), $m[0]); } -function cleanup_bbcode($body) { +function cleanup_bbcode($body) +{ - /** - * fix naked links by passing through a callback to see if this is a zot site of some kind - * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. - * First protect any url inside certain bbcode tags so we don't double link it. - */ + /** + * fix naked links by passing through a callback to see if this is a zot site of some kind + * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. + * First protect any url inside certain bbcode tags so we don't double link it. + */ - // markdown code blocks are slightly more complicated - - $body = preg_replace_callback('#(^|\n)([`~]{3,})(?: *\.?([a-zA-Z0-9\-.]+))?\n+([\s\S]+?)\n+\2(\n|$)#', function ($match) { - return $match[1] . $match[2] . "\n" . bb_code_protect($match[4]) . "\n" . $match[2] . (($match[5]) ? $match[5] : "\n"); - }, $body); + // markdown code blocks are slightly more complicated - $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback('/\[svg(.*?)\[\/(svg)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism','\red_escape_codeblock',$body); + $body = preg_replace_callback('#(^|\n)([`~]{3,})(?: *\.?([a-zA-Z0-9\-.]+))?\n+([\s\S]+?)\n+\2(\n|$)#', function ($match) { + return $match[1] . $match[2] . "\n" . bb_code_protect($match[4]) . "\n" . $match[2] . (($match[5]) ? $match[5] : "\n"); + }, $body); - $body = preg_replace_callback("/([^\]\='".'"'."\;\/\{\(]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\+\,\(\)]+)/ismu", '\nakedoembed', $body); + $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism', '\red_escape_codeblock', $body); + $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism', '\red_escape_codeblock', $body); + $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism', '\red_escape_codeblock', $body); + $body = preg_replace_callback('/\[svg(.*?)\[\/(svg)\]/ism', '\red_escape_codeblock', $body); + $body = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism', '\red_escape_codeblock', $body); + $body = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism', '\red_escape_codeblock', $body); - $body = preg_replace_callback("/([^\]\='".'"'."\;\/\{\(]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\+\,\(\)]+)/ismu", '\red_zrl_callback', $body); + $body = preg_replace_callback("/([^\]\='" . '"' . "\;\/\{\(]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\+\,\(\)]+)/ismu", '\nakedoembed', $body); + + $body = preg_replace_callback("/([^\]\='" . '"' . "\;\/\{\(]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\+\,\(\)]+)/ismu", '\red_zrl_callback', $body); - $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body); - $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body); - $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body); - $body = preg_replace_callback('/\[\$b64svg(.*?)\[\/(svg)\]/ism','\red_unescape_codeblock',$body); - $body = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism','\red_unescape_codeblock',$body); - $body = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism','\red_unescape_codeblock',$body); + $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism', '\red_unescape_codeblock', $body); + $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism', '\red_unescape_codeblock', $body); + $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism', '\red_unescape_codeblock', $body); + $body = preg_replace_callback('/\[\$b64svg(.*?)\[\/(svg)\]/ism', '\red_unescape_codeblock', $body); + $body = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism', '\red_unescape_codeblock', $body); + $body = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism', '\red_unescape_codeblock', $body); - $body = bb_code_unprotect($body); + $body = bb_code_unprotect($body); - // fix any img tags that should be zmg + // fix any img tags that should be zmg - $body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body); + $body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism', '\red_zrlify_img_callback', $body); - $body = bb_translate_video($body); + $body = bb_translate_video($body); - /** - * Fold multi-line [code] sequences - */ + /** + * Fold multi-line [code] sequences + */ - $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body); + $body = preg_replace('/\[\/code\]\s*\[code\]/ism', "\n", $body); - return $body; + return $body; } -function gen_link_id($mid) { - if (strpbrk($mid,':/&?<>"\'') !== false) { - return 'b64.' . base64url_encode($mid); - } - return $mid; +function gen_link_id($mid) +{ + if (strpbrk($mid, ':/&?<>"\'') !== false) { + return 'b64.' . base64url_encode($mid); + } + return $mid; } -function unpack_link_id($mid) { - if (strpos($mid,'b64.') === 0) { - $mid = base64url_decode(preg_replace('/[^A-Za-z0-9\-_].*/','',substr($mid,4))); - } - return $mid; +function unpack_link_id($mid) +{ + if (strpos($mid, 'b64.') === 0) { + $mid = base64url_decode(preg_replace('/[^A-Za-z0-9\-_].*/', '', substr($mid, 4))); + } + return $mid; } // callback for array_walk -function array_trim(&$v,$k) { - $v = trim($v); +function array_trim(&$v, $k) +{ + $v = trim($v); } -function array_escape_tags(&$v,$k) { - $v = escape_tags($v); +function array_escape_tags(&$v, $k) +{ + $v = escape_tags($v); } -function ellipsify($s,$maxlen) { - if($maxlen & 1) - $maxlen --; - if($maxlen < 4) - $maxlen = 4; +function ellipsify($s, $maxlen) +{ + if ($maxlen & 1) { + $maxlen--; + } + if ($maxlen < 4) { + $maxlen = 4; + } - if(mb_strlen($s) < $maxlen) - return $s; + if (mb_strlen($s) < $maxlen) { + return $s; + } - return mb_substr($s,0,$maxlen / 2) . '...' . mb_substr($s,mb_strlen($s) - ($maxlen / 2)); + return mb_substr($s, 0, $maxlen / 2) . '...' . mb_substr($s, mb_strlen($s) - ($maxlen / 2)); } -function purify_filename($s) { - if(($s[0] === '.') || strpos($s,'/') !== false) - return ''; - return $s; +function purify_filename($s) +{ + if (($s[0] === '.') || strpos($s, '/') !== false) { + return ''; + } + return $s; } // callback for sorting the settings/featured entries. -function featured_sort($a,$b) { - $s1 = substr($a,strpos($a,'id='),20); - $s2 = substr($b,strpos($b,'id='),20); - return(strcmp($s1,$s2)); +function featured_sort($a, $b) +{ + $s1 = substr($a, strpos($a, 'id='), 20); + $s2 = substr($b, strpos($b, 'id='), 20); + return(strcmp($s1, $s2)); } -function unpunify($s) { - if (function_exists('idn_to_utf8')) { - return idn_to_utf8($s); - } - return $s; +function unpunify($s) +{ + if (function_exists('idn_to_utf8')) { + return idn_to_utf8($s); + } + return $s; } -function punify($s) { - if (function_exists('idn_to_ascii')) { - return idn_to_ascii($s); - } - return $s; +function punify($s) +{ + if (function_exists('idn_to_ascii')) { + return idn_to_ascii($s); + } + return $s; } -function unique_multidim_array($array, $key) { +function unique_multidim_array($array, $key) +{ $temp_array = []; $i = 0; $key_array = []; - - foreach($array as $val) { + + foreach ($array as $val) { if (!in_array($val[$key], $key_array)) { $key_array[$i] = $val[$key]; $temp_array[$i] = $val; @@ -3696,161 +3898,167 @@ function unique_multidim_array($array, $key) { $i++; } return $temp_array; - -} +} // Much prettier formatting than print_r() // This assumes the output will be a web page and escapes angle-chars appropriately by default. -function print_array($arr, $escape = true, $level = 0) { +function print_array($arr, $escape = true, $level = 0) +{ - $o = EMPTY_STR; - $tabs = EMPTY_STR; + $o = EMPTY_STR; + $tabs = EMPTY_STR; - if(is_array($arr)) { - for($x = 0; $x <= $level; $x ++) { - $tabs .= "\t"; - } - $o .= '[' . "\n"; - if(count($arr)) { - foreach($arr as $k => $v) { - if(is_array($v)) { - $o .= $tabs . '[' . (($escape) ? escape_tags($k) : $k) . '] => ' . print_array($v, $escape, $level + 1) . "\n"; - } - else { - $o .= $tabs . '[' . (($escape) ? escape_tags($k) : $k) . '] => ' . print_val($v, $escape) . ",\n"; - } - } - } - $o .= substr($tabs,0,-1) . ']' . (($level) ? ',' : ';' ). "\n"; - return $o; - } - + if (is_array($arr)) { + for ($x = 0; $x <= $level; $x++) { + $tabs .= "\t"; + } + $o .= '[' . "\n"; + if (count($arr)) { + foreach ($arr as $k => $v) { + if (is_array($v)) { + $o .= $tabs . '[' . (($escape) ? escape_tags($k) : $k) . '] => ' . print_array($v, $escape, $level + 1) . "\n"; + } else { + $o .= $tabs . '[' . (($escape) ? escape_tags($k) : $k) . '] => ' . print_val($v, $escape) . ",\n"; + } + } + } + $o .= substr($tabs, 0, -1) . ']' . (($level) ? ',' : ';' ) . "\n"; + return $o; + } } -function print_val($v, $escape = true) { - if (is_bool($v)) { - if ($v) { - return 'true'; - } - return 'false'; - } - if (is_string($v)) { - return "'" . (($escape) ? escape_tags($v) : $v) . "'"; - } - return $v; +function print_val($v, $escape = true) +{ + if (is_bool($v)) { + if ($v) { + return 'true'; + } + return 'false'; + } + if (is_string($v)) { + return "'" . (($escape) ? escape_tags($v) : $v) . "'"; + } + return $v; } -function array_path_exists($str,$arr) { +function array_path_exists($str, $arr) +{ - if (! ($arr && is_array($arr))) { - return false; - } + if (! ($arr && is_array($arr))) { + return false; + } - $ptr = $arr; - $search = explode('/', $str); + $ptr = $arr; + $search = explode('/', $str); - if ($search) { - foreach ($search as $s) { - if ($ptr && is_array($ptr) && array_key_exists($s,$ptr)) { - $ptr = $ptr[$s]; - } - else { - return false; - } - } - return true; - } - return false; + if ($search) { + foreach ($search as $s) { + if ($ptr && is_array($ptr) && array_key_exists($s, $ptr)) { + $ptr = $ptr[$s]; + } else { + return false; + } + } + return true; + } + return false; } -function get_forum_channels($uid,$collections = 0) { +function get_forum_channels($uid, $collections = 0) +{ - if (! $uid) - return; + if (! $uid) { + return; + } - if ($collections) { - $pagetype = $collections; - } - else { - $pagetype = 1; - } + if ($collections) { + $pagetype = $collections; + } else { + $pagetype = 1; + } - $r = q("select abook_id, xchan_hash, xchan_network, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 and abook_self = 0 and xchan_type = %d order by xchan_name", - intval($uid), - intval($pagetype) - ); - - return $r; + $r = q( + "select abook_id, xchan_hash, xchan_network, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 and abook_self = 0 and xchan_type = %d order by xchan_name", + intval($uid), + intval($pagetype) + ); + return $r; } -function serialise($x) { - return ((is_array($x)) ? 'json:' . json_encode($x) : $x); +function serialise($x) +{ + return ((is_array($x)) ? 'json:' . json_encode($x) : $x); } -function unserialise($x) { - if (is_array($x)) { - return $x; - } - $y = ((substr($x,0,5) === 'json:') ? json_decode(substr($x,5),true) : ''); - return ((is_array($y)) ? $y : $x); +function unserialise($x) +{ + if (is_array($x)) { + return $x; + } + $y = ((substr($x, 0, 5) === 'json:') ? json_decode(substr($x, 5), true) : ''); + return ((is_array($y)) ? $y : $x); } -function obscurify($s) { - return str_rot47(base64url_encode($s)); +function obscurify($s) +{ + return str_rot47(base64url_encode($s)); } -function unobscurify($s) { - return base64url_decode(str_rot47($s)); +function unobscurify($s) +{ + return base64url_decode(str_rot47($s)); } -function svg2bb($s) { +function svg2bb($s) +{ - $s = preg_replace("/\(.*?)\<(.*?)\<\/text\>/", '$2<$3', $s); - $s = preg_replace("/\(.*?)\>(.*?)\<\/text\>/", '$2>$3', $s); - $s = preg_replace("/\(.*?)\[(.*?)\<\/text\>/", '$2[$3', $s); - $s = preg_replace("/\(.*?)\](.*?)\<\/text\>/", '$2]$3', $s); - $s = utf8_encode($s); - $purify = new SvgSanitizer(); - if ($purify->loadXML($s)) { - $purify->sanitize(); - $output = $purify->saveSVG(); - $output = preg_replace("/\<\?xml(.*?)\>/",'',$output); - $output = preg_replace("/\<\!\-\-(.*?)\-\-\>/",'',$output); - $output = str_replace(['<','>'],['[',']'],$output); - return $output; - } - return EMPTY_STR; + $s = preg_replace("/\(.*?)\<(.*?)\<\/text\>/", '$2<$3', $s); + $s = preg_replace("/\(.*?)\>(.*?)\<\/text\>/", '$2>$3', $s); + $s = preg_replace("/\(.*?)\[(.*?)\<\/text\>/", '$2[$3', $s); + $s = preg_replace("/\(.*?)\](.*?)\<\/text\>/", '$2]$3', $s); + $s = utf8_encode($s); + $purify = new SvgSanitizer(); + if ($purify->loadXML($s)) { + $purify->sanitize(); + $output = $purify->saveSVG(); + $output = preg_replace("/\<\?xml(.*?)\>/", '', $output); + $output = preg_replace("/\<\!\-\-(.*?)\-\-\>/", '', $output); + $output = str_replace(['<','>'], ['[',']'], $output); + return $output; + } + return EMPTY_STR; } // Takes something that looks like a phone number and returns a string suitable for tel: protocol or false. -function is_phone_number($s) { - $ext = substr($s,strpos($s,'x')+1); - if (! $ext) { - $ext = substr($s,strpos($s,'X')+1); - } - if ($ext && ctype_digit($ext)) { - $rext = ';ext=' . $ext; - $s = str_replace(['x' . $ext, 'X' . $ext],['',''],$s); - } - else { - $ext = EMPTY_STR; - } - $s = str_replace(['(',')',' ','-','+'],['','','','',''],$s); - return ((ctype_digit($s)) ? $s . $rext : false); +function is_phone_number($s) +{ + $ext = substr($s, strpos($s, 'x') + 1); + if (! $ext) { + $ext = substr($s, strpos($s, 'X') + 1); + } + if ($ext && ctype_digit($ext)) { + $rext = ';ext=' . $ext; + $s = str_replace(['x' . $ext, 'X' . $ext], ['',''], $s); + } else { + $ext = EMPTY_STR; + } + $s = str_replace(['(',')',' ','-','+'], ['','','','',''], $s); + return ((ctype_digit($s)) ? $s . $rext : false); } /** * fnmatch seems a bit unpredictable, so use this instead. */ -function wildmat($pattern,$string) { - return preg_match("#^".strtr(preg_quote($pattern, '#'), [ '\*' => '.*', '\?' => '.', '\[' => '[', '\]' => ']' ] ) . "$#i", $string); +function wildmat($pattern, $string) +{ + return preg_match("#^" . strtr(preg_quote($pattern, '#'), [ '\*' => '.*', '\?' => '.', '\[' => '[', '\]' => ']' ]) . "$#i", $string); } diff --git a/include/xchan.php b/include/xchan.php index f45ef9e45..d5951f297 100644 --- a/include/xchan.php +++ b/include/xchan.php @@ -3,372 +3,399 @@ use Zotlabs\Lib\Libzot; use Zotlabs\Web\HTTPSig; -function xchan_store_lowlevel($arr) { +function xchan_store_lowlevel($arr) +{ - $store = [ - 'xchan_hash' => ((array_key_exists('xchan_hash',$arr)) ? $arr['xchan_hash'] : ''), - 'xchan_guid' => ((array_key_exists('xchan_guid',$arr)) ? $arr['xchan_guid'] : ''), - 'xchan_guid_sig' => ((array_key_exists('xchan_guid_sig',$arr)) ? $arr['xchan_guid_sig'] : ''), - 'xchan_pubkey' => ((array_key_exists('xchan_pubkey',$arr)) ? $arr['xchan_pubkey'] : ''), - 'xchan_photo_mimetype' => ((array_key_exists('xchan_photo_mimetype',$arr)) ? $arr['xchan_photo_mimetype'] : ''), - 'xchan_photo_l' => ((array_key_exists('xchan_photo_l',$arr)) ? $arr['xchan_photo_l'] : ''), - 'xchan_photo_m' => ((array_key_exists('xchan_photo_m',$arr)) ? $arr['xchan_photo_m'] : ''), - 'xchan_photo_s' => ((array_key_exists('xchan_photo_s',$arr)) ? $arr['xchan_photo_s'] : ''), - 'xchan_addr' => ((array_key_exists('xchan_addr',$arr)) ? $arr['xchan_addr'] : ''), - 'xchan_url' => ((array_key_exists('xchan_url',$arr)) ? $arr['xchan_url'] : ''), - 'xchan_connurl' => ((array_key_exists('xchan_connurl',$arr)) ? $arr['xchan_connurl'] : ''), - 'xchan_follow' => ((array_key_exists('xchan_follow',$arr)) ? $arr['xchan_follow'] : ''), - 'xchan_connpage' => ((array_key_exists('xchan_connpage',$arr)) ? $arr['xchan_connpage'] : ''), - 'xchan_name' => ((array_key_exists('xchan_name',$arr)) ? $arr['xchan_name'] : ''), - 'xchan_network' => ((array_key_exists('xchan_network',$arr)) ? $arr['xchan_network'] : ''), - 'xchan_created' => ((array_key_exists('xchan_created',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_created']) : datetime_convert()), - 'xchan_updated' => ((array_key_exists('xchan_updated',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_updated']) : datetime_convert()), - 'xchan_photo_date' => ((array_key_exists('xchan_photo_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_photo_date']) : NULL_DATE), - 'xchan_name_date' => ((array_key_exists('xchan_name_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_name_date']) : NULL_DATE), - 'xchan_hidden' => ((array_key_exists('xchan_hidden',$arr)) ? intval($arr['xchan_hidden']) : 0), - 'xchan_orphan' => ((array_key_exists('xchan_orphan',$arr)) ? intval($arr['xchan_orphan']) : 0), - 'xchan_censored' => ((array_key_exists('xchan_censored',$arr)) ? intval($arr['xchan_censored']) : 0), - 'xchan_selfcensored' => ((array_key_exists('xchan_selfcensored',$arr)) ? intval($arr['xchan_selfcensored']) : 0), - 'xchan_system' => ((array_key_exists('xchan_system',$arr)) ? intval($arr['xchan_system']) : 0), - 'xchan_type' => ((array_key_exists('xchan_type',$arr)) ? intval($arr['xchan_type']) : XCHAN_TYPE_PERSON), - 'xchan_deleted' => ((array_key_exists('xchan_deleted',$arr)) ? intval($arr['xchan_deleted']) : 0) - ]; + $store = [ + 'xchan_hash' => ((array_key_exists('xchan_hash', $arr)) ? $arr['xchan_hash'] : ''), + 'xchan_guid' => ((array_key_exists('xchan_guid', $arr)) ? $arr['xchan_guid'] : ''), + 'xchan_guid_sig' => ((array_key_exists('xchan_guid_sig', $arr)) ? $arr['xchan_guid_sig'] : ''), + 'xchan_pubkey' => ((array_key_exists('xchan_pubkey', $arr)) ? $arr['xchan_pubkey'] : ''), + 'xchan_photo_mimetype' => ((array_key_exists('xchan_photo_mimetype', $arr)) ? $arr['xchan_photo_mimetype'] : ''), + 'xchan_photo_l' => ((array_key_exists('xchan_photo_l', $arr)) ? $arr['xchan_photo_l'] : ''), + 'xchan_photo_m' => ((array_key_exists('xchan_photo_m', $arr)) ? $arr['xchan_photo_m'] : ''), + 'xchan_photo_s' => ((array_key_exists('xchan_photo_s', $arr)) ? $arr['xchan_photo_s'] : ''), + 'xchan_addr' => ((array_key_exists('xchan_addr', $arr)) ? $arr['xchan_addr'] : ''), + 'xchan_url' => ((array_key_exists('xchan_url', $arr)) ? $arr['xchan_url'] : ''), + 'xchan_connurl' => ((array_key_exists('xchan_connurl', $arr)) ? $arr['xchan_connurl'] : ''), + 'xchan_follow' => ((array_key_exists('xchan_follow', $arr)) ? $arr['xchan_follow'] : ''), + 'xchan_connpage' => ((array_key_exists('xchan_connpage', $arr)) ? $arr['xchan_connpage'] : ''), + 'xchan_name' => ((array_key_exists('xchan_name', $arr)) ? $arr['xchan_name'] : ''), + 'xchan_network' => ((array_key_exists('xchan_network', $arr)) ? $arr['xchan_network'] : ''), + 'xchan_created' => ((array_key_exists('xchan_created', $arr)) ? datetime_convert('UTC', 'UTC', $arr['xchan_created']) : datetime_convert()), + 'xchan_updated' => ((array_key_exists('xchan_updated', $arr)) ? datetime_convert('UTC', 'UTC', $arr['xchan_updated']) : datetime_convert()), + 'xchan_photo_date' => ((array_key_exists('xchan_photo_date', $arr)) ? datetime_convert('UTC', 'UTC', $arr['xchan_photo_date']) : NULL_DATE), + 'xchan_name_date' => ((array_key_exists('xchan_name_date', $arr)) ? datetime_convert('UTC', 'UTC', $arr['xchan_name_date']) : NULL_DATE), + 'xchan_hidden' => ((array_key_exists('xchan_hidden', $arr)) ? intval($arr['xchan_hidden']) : 0), + 'xchan_orphan' => ((array_key_exists('xchan_orphan', $arr)) ? intval($arr['xchan_orphan']) : 0), + 'xchan_censored' => ((array_key_exists('xchan_censored', $arr)) ? intval($arr['xchan_censored']) : 0), + 'xchan_selfcensored' => ((array_key_exists('xchan_selfcensored', $arr)) ? intval($arr['xchan_selfcensored']) : 0), + 'xchan_system' => ((array_key_exists('xchan_system', $arr)) ? intval($arr['xchan_system']) : 0), + 'xchan_type' => ((array_key_exists('xchan_type', $arr)) ? intval($arr['xchan_type']) : XCHAN_TYPE_PERSON), + 'xchan_deleted' => ((array_key_exists('xchan_deleted', $arr)) ? intval($arr['xchan_deleted']) : 0) + ]; - return create_table_from_array('xchan',$store); + return create_table_from_array('xchan', $store); } // called from the zot api // Anybody can enter an identity into the system, but zot or zot6 identities must be validated // and existing zot6 identities cannot be altered via API -function xchan_store($arr) { +function xchan_store($arr) +{ - $update_photo = false; - $update_name = false; + $update_photo = false; + $update_name = false; - if(! ($arr['guid'] || $arr['hash'])) { - $arr = json_decode(file_get_contents('php://input'),true); - } - - logger('xchan_store: ' . print_r($arr,true)); - - if(! $arr['hash']) - $arr['hash'] = $arr['guid']; - if(! $arr['hash']) - return false; - - $r = q("select * from xchan where xchan_hash = '%s' limit 1", - dbesc($arr['hash']) - ); - if(! $r) { - - $update_photo = true; - - if(! $arr['network']) - $arr['network'] = 'unknown'; - if(! $arr['name']) - $arr['name'] = 'unknown'; - if(! $arr['url']) - $arr['url'] = z_root(); - if(! $arr['photo']) - $arr['photo'] = z_root() . '/' . get_default_profile_photo(); - - - if($arr['network'] === 'zot6') { - if((! $arr['key']) || (! Libzot::verify($arr['id'],$arr['id_sig'],$arr['key']))) { - logger('Unable to verify signature for ' . $arr['hash']); - return false; - } - } - - if($arr['network'] === 'zot') { - if((! $arr['key']) || (! Libzot::verify($arr['id'],'sha256.' . $arr['id_sig'],$arr['key']))) { - logger('Unable to verify signature for ' . $arr['hash']); - return false; - } - } - - $columns = db_columns('xchan'); - - $x = []; - foreach($arr as $k => $v) { - if($k === 'key') { - $x['xchan_pubkey'] = HTTPSig::convertKey(escape_tags($v)); - continue; - } - if($k === 'photo') { - continue; - } - - if(in_array($columns,'xchan_' . $k)) - $x['xchan_' . $k] = escape_tags($v); - } - - $x['xchan_updated'] = datetime_convert(); - $x['xchan_name_date'] = datetime_convert(); - $x['xchan_photo_date'] = datetime_convert(); - $x['xchan_system'] = false; - - $result = xchan_store_lowlevel($x); - - if(! $result) { - return $result; - } - } - else { - if($r[0]['network'] === 'zot6') { - return true; - } - if($r[0]['xchan_photo_date'] < datetime_convert('UTC','UTC',$arr['photo_date'])) { - $update_photo = true; - } - if($r[0]['xchan_name_date'] < datetime_convert('UTC','UTC',$arr['name_date'])) { - $update_name = true; - } - - } - - if($update_photo && $arr['photo']) { - $photos = import_remote_xchan_photo($arr['photo'],$arr['hash']); - if ($photos) { - $x = q("update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($arr['hash']) - ); - } - } - if($update_name && $arr['name']) { - $x = q("update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", - dbesc(datetime_convert()), - dbesc(escape_tags($arr['name'])), - dbesc(datetime_convert()), - dbesc($arr['hash']) - ); - } - - return $true; - -} - - -function xchan_match($arr) { - - if(! $arr) - return false; - - $str = ''; - - foreach($arr as $k => $v) { - if($str) { - $str .= " AND "; - } - $str .= " " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) . "' "; + if (! ($arr['guid'] || $arr['hash'])) { + $arr = json_decode(file_get_contents('php://input'), true); } - $r = q("select * from xchan where $str limit 1"); - - return (($r) ? $r[0] : false); + logger('xchan_store: ' . print_r($arr, true)); + if (! $arr['hash']) { + $arr['hash'] = $arr['guid']; + } + if (! $arr['hash']) { + return false; + } + + $r = q( + "select * from xchan where xchan_hash = '%s' limit 1", + dbesc($arr['hash']) + ); + if (! $r) { + $update_photo = true; + + if (! $arr['network']) { + $arr['network'] = 'unknown'; + } + if (! $arr['name']) { + $arr['name'] = 'unknown'; + } + if (! $arr['url']) { + $arr['url'] = z_root(); + } + if (! $arr['photo']) { + $arr['photo'] = z_root() . '/' . get_default_profile_photo(); + } + + + if ($arr['network'] === 'zot6') { + if ((! $arr['key']) || (! Libzot::verify($arr['id'], $arr['id_sig'], $arr['key']))) { + logger('Unable to verify signature for ' . $arr['hash']); + return false; + } + } + + if ($arr['network'] === 'zot') { + if ((! $arr['key']) || (! Libzot::verify($arr['id'], 'sha256.' . $arr['id_sig'], $arr['key']))) { + logger('Unable to verify signature for ' . $arr['hash']); + return false; + } + } + + $columns = db_columns('xchan'); + + $x = []; + foreach ($arr as $k => $v) { + if ($k === 'key') { + $x['xchan_pubkey'] = HTTPSig::convertKey(escape_tags($v)); + continue; + } + if ($k === 'photo') { + continue; + } + + if (in_array($columns, 'xchan_' . $k)) { + $x['xchan_' . $k] = escape_tags($v); + } + } + + $x['xchan_updated'] = datetime_convert(); + $x['xchan_name_date'] = datetime_convert(); + $x['xchan_photo_date'] = datetime_convert(); + $x['xchan_system'] = false; + + $result = xchan_store_lowlevel($x); + + if (! $result) { + return $result; + } + } else { + if ($r[0]['network'] === 'zot6') { + return true; + } + if ($r[0]['xchan_photo_date'] < datetime_convert('UTC', 'UTC', $arr['photo_date'])) { + $update_photo = true; + } + if ($r[0]['xchan_name_date'] < datetime_convert('UTC', 'UTC', $arr['name_date'])) { + $update_name = true; + } + } + + if ($update_photo && $arr['photo']) { + $photos = import_remote_xchan_photo($arr['photo'], $arr['hash']); + if ($photos) { + $x = q( + "update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($arr['hash']) + ); + } + } + if ($update_name && $arr['name']) { + $x = q( + "update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", + dbesc(datetime_convert()), + dbesc(escape_tags($arr['name'])), + dbesc(datetime_convert()), + dbesc($arr['hash']) + ); + } + + return $true; +} + + +function xchan_match($arr) +{ + + if (! $arr) { + return false; + } + + $str = ''; + + foreach ($arr as $k => $v) { + if ($str) { + $str .= " AND "; + } + $str .= " " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) . "' "; + } + + $r = q("select * from xchan where $str limit 1"); + + return (($r) ? $r[0] : false); } -function xchan_fetch($arr) { +function xchan_fetch($arr) +{ - $key = ''; - if($arr['hash']) { - $key = 'xchan_hash'; - $v = dbesc($arr['hash']); - } - elseif($arr['guid']) { - $key = 'xchan_guid'; - $v = dbesc($arr['guid']); - } - elseif($arr['address']) { - $key = 'xchan_addr'; - $v = dbesc($arr['address']); - } + $key = ''; + if ($arr['hash']) { + $key = 'xchan_hash'; + $v = dbesc($arr['hash']); + } elseif ($arr['guid']) { + $key = 'xchan_guid'; + $v = dbesc($arr['guid']); + } elseif ($arr['address']) { + $key = 'xchan_addr'; + $v = dbesc($arr['address']); + } - if(! $key) - return false; + if (! $key) { + return false; + } - $r = q("select * from xchan where $key = '$v' limit 1"); - if(! $r) - return false; + $r = q("select * from xchan where $key = '$v' limit 1"); + if (! $r) { + return false; + } - $ret = []; - foreach($r[0] as $k => $v) { - if($k === 'xchan_addr') - $ret['address'] = $v; - else - $ret[str_replace('xchan_','',$k)] = $v; - } - - return $ret; + $ret = []; + foreach ($r[0] as $k => $v) { + if ($k === 'xchan_addr') { + $ret['address'] = $v; + } else { + $ret[str_replace('xchan_', '', $k)] = $v; + } + } + return $ret; } -function xchan_keychange_table($table,$column,$oldxchan,$newxchan) { - $r = q("update $table set $column = '%s' where $column = '%s'", - dbesc($newxchan['xchan_hash']), - dbesc($oldxchan['xchan_hash']) - ); - return $r; +function xchan_keychange_table($table, $column, $oldxchan, $newxchan) +{ + $r = q( + "update $table set $column = '%s' where $column = '%s'", + dbesc($newxchan['xchan_hash']), + dbesc($oldxchan['xchan_hash']) + ); + return $r; } -function xchan_keychange_acl($table,$column,$oldxchan,$newxchan) { +function xchan_keychange_acl($table, $column, $oldxchan, $newxchan) +{ - $allow = (($table === 'channel') ? 'channel_allow_cid' : 'allow_cid'); - $deny = (($table === 'channel') ? 'channel_deny_cid' : 'deny_cid'); + $allow = (($table === 'channel') ? 'channel_allow_cid' : 'allow_cid'); + $deny = (($table === 'channel') ? 'channel_deny_cid' : 'deny_cid'); - $r = q("select $column, $allow, $deny from $table where ($allow like '%s' or $deny like '%s') ", - dbesc('<' . $oldxchan['xchan_hash'] . '>'), - dbesc('<' . $oldxchan['xchan_hash'] . '>') - ); + $r = q( + "select $column, $allow, $deny from $table where ($allow like '%s' or $deny like '%s') ", + dbesc('<' . $oldxchan['xchan_hash'] . '>'), + dbesc('<' . $oldxchan['xchan_hash'] . '>') + ); - if($r) { - foreach($r as $rv) { - $z = q("update $table set $allow = '%s', $deny = '%s' where $column = %d", - dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', - $rv[$allow])), - dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', - $rv[$deny])), - intval($rv[$column]) - ); - } - } - return $z; + if ($r) { + foreach ($r as $rv) { + $z = q( + "update $table set $allow = '%s', $deny = '%s' where $column = %d", + dbesc(str_replace( + '<' . $oldxchan['xchan_hash'] . '>', + '<' . $newxchan['xchan_hash'] . '>', + $rv[$allow] + )), + dbesc(str_replace( + '<' . $oldxchan['xchan_hash'] . '>', + '<' . $newxchan['xchan_hash'] . '>', + $rv[$deny] + )), + intval($rv[$column]) + ); + } + } + return $z; } -function xchan_change_key($oldx,$newx,$data) { +function xchan_change_key($oldx, $newx, $data) +{ - $tables = [ - 'abook' => 'abook_xchan', - 'abconfig' => 'xchan', - 'pgrp_member' => 'xchan', - 'chat' => 'chat_xchan', - 'chatpresence' => 'cp_xchan', - 'event' => 'event_xchan', - 'item' => 'owner_xchan', - 'item' => 'author_xchan', - 'item' => 'source_xchan', - 'mail' => 'from_xchan', - 'mail' => 'to_xchan', - 'shares' => 'share_xchan', - 'source' => 'src_channel_xchan', - 'source' => 'src_xchan', - 'xchat' => 'xchat_xchan', - 'xconfig' => 'xchan', - 'xign' => 'xchan', - 'xlink' => 'xlink_xchan', - 'xprof' => 'xprof_hash', - 'xtag' => 'xtag_hash' - ]; - - - $acls = [ - 'channel' => 'channel_id', - 'attach' => 'id', - 'chatroom' => 'cr_id', - 'event' => 'id', - 'item' => 'id', - 'menu_item' => 'mitem_id', - 'obj' => 'obj_id', - 'photo' => 'id' - ]; + $tables = [ + 'abook' => 'abook_xchan', + 'abconfig' => 'xchan', + 'pgrp_member' => 'xchan', + 'chat' => 'chat_xchan', + 'chatpresence' => 'cp_xchan', + 'event' => 'event_xchan', + 'item' => 'owner_xchan', + 'item' => 'author_xchan', + 'item' => 'source_xchan', + 'mail' => 'from_xchan', + 'mail' => 'to_xchan', + 'shares' => 'share_xchan', + 'source' => 'src_channel_xchan', + 'source' => 'src_xchan', + 'xchat' => 'xchat_xchan', + 'xconfig' => 'xchan', + 'xign' => 'xchan', + 'xlink' => 'xlink_xchan', + 'xprof' => 'xprof_hash', + 'xtag' => 'xtag_hash' + ]; - foreach($tables as $k => $v) { - xchan_keychange_table($k,$v,$oldx,$newx); - } + $acls = [ + 'channel' => 'channel_id', + 'attach' => 'id', + 'chatroom' => 'cr_id', + 'event' => 'id', + 'item' => 'id', + 'menu_item' => 'mitem_id', + 'obj' => 'obj_id', + 'photo' => 'id' + ]; - foreach($acls as $k => $v) { - xchan_keychange_acl($k,$v,$oldx,$newx); - } + + foreach ($tables as $k => $v) { + xchan_keychange_table($k, $v, $oldx, $newx); + } + + foreach ($acls as $k => $v) { + xchan_keychange_acl($k, $v, $oldx, $newx); + } } -function migrate_xchan_photos($limit = 100) { +function migrate_xchan_photos($limit = 100) +{ - $r = q("select xchan_photo_l, xchan_hash, photo.xchan, photo.resource_id from photo left join xchan on photo.xchan = xchan_hash where photo.xchan != '' and uid = 0 and imgscale = 4 and photo_usage = 2 and xchan_photo_l like ('%s') limit %d", - dbesc(z_root() . '/photo/%'), - intval($limit) - ); - if ($r) { - foreach ($r as $rv) { - logger('migrating xchan_photo for ' . $rv['xchan_hash']); - $photos = import_remote_xchan_photo($rv['xchan_photo_l'], $rv['xchan_hash']); - if ($photos) { - $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' + $r = q( + "select xchan_photo_l, xchan_hash, photo.xchan, photo.resource_id from photo left join xchan on photo.xchan = xchan_hash where photo.xchan != '' and uid = 0 and imgscale = 4 and photo_usage = 2 and xchan_photo_l like ('%s') limit %d", + dbesc(z_root() . '/photo/%'), + intval($limit) + ); + if ($r) { + foreach ($r as $rv) { + logger('migrating xchan_photo for ' . $rv['xchan_hash']); + $photos = import_remote_xchan_photo($rv['xchan_photo_l'], $rv['xchan_hash']); + if ($photos) { + $r = q( + "update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($rv['xchan_hash']) - ); - } - } - } - + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($rv['xchan_hash']) + ); + } + } + } } -function cleanup_xchan_photos($limit = 500) { +function cleanup_xchan_photos($limit = 500) +{ - $r = q("select photo.xchan, photo.resource_id from photo left join xchan on photo.xchan = xchan_hash where photo.xchan != '' and uid = 0 and imgscale = 4 and photo_usage = 2 and xchan_photo_l like ('%s') limit %d", - dbesc(z_root() . '/xp/%'), - intval($limit) - ); - if ($r) { - foreach ($r as $rv) { - q("delete from photo where xchan = '%s' and resource_id = '%s' and photo_usage = 2 and uid = 0", - dbesc($rv['xchan']), - dbesc($rv['resource_id']) - ); - } - } + $r = q( + "select photo.xchan, photo.resource_id from photo left join xchan on photo.xchan = xchan_hash where photo.xchan != '' and uid = 0 and imgscale = 4 and photo_usage = 2 and xchan_photo_l like ('%s') limit %d", + dbesc(z_root() . '/xp/%'), + intval($limit) + ); + if ($r) { + foreach ($r as $rv) { + q( + "delete from photo where xchan = '%s' and resource_id = '%s' and photo_usage = 2 and uid = 0", + dbesc($rv['xchan']), + dbesc($rv['resource_id']) + ); + } + } } -function xprof_store_lowlevel($profile) { +function xprof_store_lowlevel($profile) +{ - if (! $profile['hash']) { - return false; - } + if (! $profile['hash']) { + return false; + } - $store = [ - $arr['xprof_hash'] => $profile['hash'], - $arr['xprof_dob'] => (($profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('','',$profile['birthday'],'Y-m-d')), - $arr['xprof_age'] => (($profile['age']) ? intval($profile['age']) : 0), - $arr['xprof_desc'] => (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_gender'] => (($profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_marital'] => (($profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_sexual'] => (($profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_locale'] => (($profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_region'] => (($profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_postcode'] => (($profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_country'] => (($profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_about'] => (($profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_homepage'] => (($profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_hometown'] => (($profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT,'UTF-8',false) : ''), - $arr['xprof_keywords'] => (($profile['keywords']) ? htmlspecialchars($profile['keywords'], ENT_COMPAT,'UTF-8',false) : ''), + $store = [ + $arr['xprof_hash'] => $profile['hash'], + $arr['xprof_dob'] => (($profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('', '', $profile['birthday'], 'Y-m-d')), + $arr['xprof_age'] => (($profile['age']) ? intval($profile['age']) : 0), + $arr['xprof_desc'] => (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_gender'] => (($profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_marital'] => (($profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_sexual'] => (($profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_locale'] => (($profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_region'] => (($profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_postcode'] => (($profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_country'] => (($profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_about'] => (($profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_homepage'] => (($profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_hometown'] => (($profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT, 'UTF-8', false) : ''), + $arr['xprof_keywords'] => (($profile['keywords']) ? htmlspecialchars($profile['keywords'], ENT_COMPAT, 'UTF-8', false) : ''), - ]; + ]; - return create_table_from_array('xchan',$store); - -} \ No newline at end of file + return create_table_from_array('xchan', $store); +} diff --git a/include/zid.php b/include/zid.php index bac5f2231..effaca355 100644 --- a/include/zid.php +++ b/include/zid.php @@ -3,30 +3,29 @@ use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Verify; +function is_matrix_url($url) +{ -function is_matrix_url($url) { + // in-memory cache to avoid repeated queries for the same host + static $remembered = []; - // in-memory cache to avoid repeated queries for the same host - static $remembered = []; + $m = @parse_url($url); + if (isset($m['host']) && $m['host']) { + if (in_array($m['host'], $remembered)) { + return true; + } - $m = @parse_url($url); - if (isset($m['host']) && $m['host']) { + $r = q( + "select hubloc_url from hubloc where hubloc_host = '%s' and hubloc_network = 'zot6' limit 1", + dbesc($m['host']) + ); + if ($r) { + $remembered[] = $m['host']; + return true; + } + } - if (in_array($m['host'],$remembered)) { - return true; - } - - $r = q("select hubloc_url from hubloc where hubloc_host = '%s' and hubloc_network = 'zot6' limit 1", - dbesc($m['host']) - ); - if ($r) { - $remembered[] = $m['host']; - return true; - } - - } - - return false; + return false; } /** @@ -38,98 +37,106 @@ function is_matrix_url($url) { * $address to use instead of session environment * @return string */ -function zid($s, $address = '') { +function zid($s, $address = '') +{ - if (! strlen($s) || strpos($s,'zid=')) { - return $s; - } + if (! strlen($s) || strpos($s, 'zid=')) { + return $s; + } - $m = parse_url($s); - $fragment = ((array_key_exists('fragment',$m) && $m['fragment']) ? $m['fragment'] : false); - if ($fragment !== false) { - $s = str_replace('#' . $fragment,'',$s); - } + $m = parse_url($s); + $fragment = ((array_key_exists('fragment', $m) && $m['fragment']) ? $m['fragment'] : false); + if ($fragment !== false) { + $s = str_replace('#' . $fragment, '', $s); + } - $has_params = ((strpos($s,'?')) ? true : false); - $num_slashes = substr_count($s, '/'); - if (! $has_params) { - $has_params = ((strpos($s, '&')) ? true : false); - } + $has_params = ((strpos($s, '?')) ? true : false); + $num_slashes = substr_count($s, '/'); + if (! $has_params) { + $has_params = ((strpos($s, '&')) ? true : false); + } - $achar = strpos($s,'?') ? '&' : '?'; + $achar = strpos($s, '?') ? '&' : '?'; - $mine = get_my_url(); - $myaddr = (($address) ? $address : get_my_address()); + $mine = get_my_url(); + $myaddr = (($address) ? $address : get_my_address()); - $mine_parsed = parse_url($mine); - $s_parsed = parse_url($s); - $url_match = false; + $mine_parsed = parse_url($mine); + $s_parsed = parse_url($s); + $url_match = false; - if (isset($mine_parsed['host']) && isset($s_parsed['host']) - && $mine_parsed['host'] === $s_parsed['host']) { - $url_match = true; - } + if ( + isset($mine_parsed['host']) && isset($s_parsed['host']) + && $mine_parsed['host'] === $s_parsed['host'] + ) { + $url_match = true; + } - if ($mine && $myaddr && (! $url_match)) { - $zurl = $s . (($num_slashes >= 3) ? '' : '/') . (($achar === '?') ? '?f=&' : '&') . 'zid=' . urlencode($myaddr); - } - else { - $zurl = $s; - } + if ($mine && $myaddr && (! $url_match)) { + $zurl = $s . (($num_slashes >= 3) ? '' : '/') . (($achar === '?') ? '?f=&' : '&') . 'zid=' . urlencode($myaddr); + } else { + $zurl = $s; + } - // put fragment at the end + // put fragment at the end - if ($fragment) { - $zurl .= '#' . $fragment; - } + if ($fragment) { + $zurl .= '#' . $fragment; + } - $arr = [ - 'url' => $s, - 'zid' => urlencode($myaddr), - 'result' => $zurl - ]; - /** - * @hooks zid - * Called when adding the observer's zid to a URL. - * * \e string \b url - url to accept zid - * * \e string \b zid - urlencoded zid - * * \e string \b result - the return string we calculated, change it if you want to return something else - */ - call_hooks('zid', $arr); + $arr = [ + 'url' => $s, + 'zid' => urlencode($myaddr), + 'result' => $zurl + ]; + /** + * @hooks zid + * Called when adding the observer's zid to a URL. + * * \e string \b url - url to accept zid + * * \e string \b zid - urlencoded zid + * * \e string \b result - the return string we calculated, change it if you want to return something else + */ + call_hooks('zid', $arr); - return $arr['result']; + return $arr['result']; } -function strip_query_param($s,$param) { - return preg_replace('/[\?&]' . $param . '=(.*?)(&|$)/ism','$2',$s); +function strip_query_param($s, $param) +{ + return preg_replace('/[\?&]' . $param . '=(.*?)(&|$)/ism', '$2', $s); } -function strip_zids($s) { - return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s); +function strip_zids($s) +{ + return preg_replace('/[\?&]zid=(.*?)(&|$)/ism', '$2', $s); } -function strip_owt($s) { - return preg_replace('/[\?&]owt=(.*?)(&|$)/ism','$2',$s); +function strip_owt($s) +{ + return preg_replace('/[\?&]owt=(.*?)(&|$)/ism', '$2', $s); } -function strip_zats($s) { - return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s); +function strip_zats($s) +{ + return preg_replace('/[\?&]zat=(.*?)(&|$)/ism', '$2', $s); } -function strip_escaped_zids($s) { - $x = preg_replace('/&\;zid=(.*?)(&|$)/ism','$2',$s); - return strip_query_param($x,'f'); +function strip_escaped_zids($s) +{ + $x = preg_replace('/&\;zid=(.*?)(&|$)/ism', '$2', $s); + return strip_query_param($x, 'f'); } -function clean_query_string($s = '') { - $x = strip_zids(($s) ? $s : App::$query_string); - $x = strip_owt($x); - $x = strip_zats($x); - $x = strip_query_param($x,'sort'); +function clean_query_string($s = '') +{ + $x = strip_zids(($s) ? $s : App::$query_string); + $x = strip_owt($x); + $x = strip_zats($x); + $x = strip_query_param($x, 'sort'); - return strip_query_param($x,'f'); + return strip_query_param($x, 'f'); } @@ -144,63 +151,69 @@ function clean_query_string($s = '') { * @return string */ -function zidify_callback($match) { +function zidify_callback($match) +{ - $arr = [ 'zid' => ((strpos($match[1],'zrl') || strpos($match[3],'zrl')) ? true : false), 'url' => $match[2] ]; - call_hooks('zidify', $arr); + $arr = [ 'zid' => ((strpos($match[1], 'zrl') || strpos($match[3], 'zrl')) ? true : false), 'url' => $match[2] ]; + call_hooks('zidify', $arr); - $replace = ''; + $replace = ''; - $x = str_replace($match[0], $replace, $match[0]); + $x = str_replace($match[0], $replace, $match[0]); - return $x; + return $x; } -function zidify_img_callback($match) { +function zidify_img_callback($match) +{ - $arr = [ 'zid' => ((strpos($match[1],'zrl') || strpos($match[3],'zrl')) ? true : false), 'url' => $match[2] ]; - call_hooks('zidify', $arr); + $arr = [ 'zid' => ((strpos($match[1], 'zrl') || strpos($match[3], 'zrl')) ? true : false), 'url' => $match[2] ]; + call_hooks('zidify', $arr); - $replace = ''; + $replace = ''; - $x = str_replace($match[0], $replace, $match[0]); + $x = str_replace($match[0], $replace, $match[0]); - return $x; + return $x; } -function zidify_links($s) { - $s = preg_replace_callback('/\/ism','zidify_callback',$s); - $s = preg_replace_callback('/\/ism','zidify_img_callback',$s); +function zidify_links($s) +{ + $s = preg_replace_callback('/\/ism', 'zidify_callback', $s); + $s = preg_replace_callback('/\/ism', 'zidify_img_callback', $s); - return $s; + return $s; } -function zidify_text_callback($match) { - $is_zid = is_matrix_url($match[2]); - $replace = ''; +function zidify_text_callback($match) +{ + $is_zid = is_matrix_url($match[2]); + $replace = ''; - $x = str_replace($match[0], $replace, $match[0]); + $x = str_replace($match[0], $replace, $match[0]); - return $x; + return $x; } -function zidify_text_img_callback($match) { - $is_zid = is_matrix_url($match[2]); - $replace = ''; +function zidify_text_img_callback($match) +{ + $is_zid = is_matrix_url($match[2]); + $replace = ''; - $x = str_replace($match[0], $replace, $match[0]); + $x = str_replace($match[0], $replace, $match[0]); - return $x; + return $x; } -function zidify_text($s) { +function zidify_text($s) +{ - $s = preg_replace_callback('/\/ism','zidify_text_callback',$s); - $s = preg_replace_callback('/\/ism','zidify_text_img_callback',$s); + $s = preg_replace_callback('/\/ism', 'zidify_text_callback', $s); + $s = preg_replace_callback('/\/ism', 'zidify_text_img_callback', $s); - return $s; + return $s; } @@ -215,25 +228,26 @@ function zidify_text($s) { * @param array $matches * @return string */ -function red_zrl_callback($matches) { +function red_zrl_callback($matches) +{ - $zrl = is_matrix_url($matches[2]); + $zrl = is_matrix_url($matches[2]); - $t = strip_zids($matches[2]); - if ($t !== $matches[2]) { - $zrl = true; - $matches[2] = $t; - } + $t = strip_zids($matches[2]); + if ($t !== $matches[2]) { + $zrl = true; + $matches[2] = $t; + } - if ($matches[1] === '#^') { - $matches[1] = ''; - } - - if ($zrl) { - return $matches[1] . '[zrl=' . $matches[2] . ']' . $matches[2] . '[/zrl]'; - } + if ($matches[1] === '#^') { + $matches[1] = ''; + } - return $matches[1] . '[url=' . $matches[2] . ']' . $matches[2] . '[/url]'; + if ($zrl) { + return $matches[1] . '[zrl=' . $matches[2] . ']' . $matches[2] . '[/zrl]'; + } + + return $matches[1] . '[url=' . $matches[2] . ']' . $matches[2] . '[/url]'; } /** @@ -243,42 +257,46 @@ function red_zrl_callback($matches) { * @param array $matches * @return string */ -function red_escape_zrl_callback($matches) { +function red_escape_zrl_callback($matches) +{ - // Uncertain why the url/zrl forms weren't picked up by the non-greedy regex. + // Uncertain why the url/zrl forms weren't picked up by the non-greedy regex. - if ((strpos($matches[3], 'zmg') !== false) || (strpos($matches[3], 'img') !== false) || (strpos($matches[3],'zrl') !== false) || (strpos($matches[3],'url') !== false)) { - return $matches[0]; - } + if ((strpos($matches[3], 'zmg') !== false) || (strpos($matches[3], 'img') !== false) || (strpos($matches[3], 'zrl') !== false) || (strpos($matches[3], 'url') !== false)) { + return $matches[0]; + } - return '[' . $matches[1] . 'rl' . $matches[2] . ']' . $matches[3] . '"' . $matches[4] . '"' . $matches[5] . '[/' . $matches[6] . 'rl]'; + return '[' . $matches[1] . 'rl' . $matches[2] . ']' . $matches[3] . '"' . $matches[4] . '"' . $matches[5] . '[/' . $matches[6] . 'rl]'; } -function red_escape_codeblock($m) { - return '[$b64' . $m[2] . base64_encode($m[1]) . '[/' . $m[2] . ']'; +function red_escape_codeblock($m) +{ + return '[$b64' . $m[2] . base64_encode($m[1]) . '[/' . $m[2] . ']'; } -function red_unescape_codeblock($m) { - return '[' . $m[2] . base64_decode($m[1]) . '[/' . $m[2] . ']'; +function red_unescape_codeblock($m) +{ + return '[' . $m[2] . base64_decode($m[1]) . '[/' . $m[2] . ']'; } -function red_zrlify_img_callback($matches) { +function red_zrlify_img_callback($matches) +{ - $zrl = is_matrix_url($matches[2]); + $zrl = is_matrix_url($matches[2]); - $t = strip_zids($matches[2]); - if ($t !== $matches[2]) { - $zrl = true; - $matches[2] = $t; - } + $t = strip_zids($matches[2]); + if ($t !== $matches[2]) { + $zrl = true; + $matches[2] = $t; + } - if ($zrl) { - return '[zmg' . $matches[1] . ']' . $matches[2] . '[/zmg]'; - } + if ($zrl) { + return '[zmg' . $matches[1] . ']' . $matches[2] . '[/zmg]'; + } - return $matches[0]; + return $matches[0]; } @@ -287,155 +305,161 @@ function red_zrlify_img_callback($matches) { * * @param string $token */ -function owt_init($token) { +function owt_init($token) +{ - require_once('include/security.php'); - - Verify::purge('owt', '3 MINUTE'); + require_once('include/security.php'); - $ob_hash = Verify::get_meta('owt', 0, $token); + Verify::purge('owt', '3 MINUTE'); - if ($ob_hash === false) { - return; - } + $ob_hash = Verify::get_meta('owt', 0, $token); - $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash + if ($ob_hash === false) { + return; + } + + $r = q( + "select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc", - dbesc($ob_hash), - dbesc($ob_hash), - dbesc($ob_hash) - ); + dbesc($ob_hash), + dbesc($ob_hash), + dbesc($ob_hash) + ); - if (! $r) { - // finger them if they can't be found. - $wf = discover_by_webbie($ob_hash); - if ($wf) { - $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash + if (! $r) { + // finger them if they can't be found. + $wf = discover_by_webbie($ob_hash); + if ($wf) { + $r = q( + "select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc", - dbesc($ob_hash), - dbesc($ob_hash), - dbesc($ob_hash) - ); - } - } - if (! $r) { - logger('owt: unable to finger ' . $ob_hash); - return; - } + dbesc($ob_hash), + dbesc($ob_hash), + dbesc($ob_hash) + ); + } + } + if (! $r) { + logger('owt: unable to finger ' . $ob_hash); + return; + } - $r = Libzot::zot_record_preferred($r); + $r = Libzot::zot_record_preferred($r); - $hubloc = $r; + $hubloc = $r; - $_SESSION['authenticated'] = 1; + $_SESSION['authenticated'] = 1; - $delegate_success = false; - if ($_REQUEST['delegate']) { - $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1", - dbesc($_REQUEST['delegate']) - ); - if ($r && intval($r[0]['channel_id'])) { - $allowed = perm_is_allowed($r[0]['channel_id'],$hubloc['xchan_hash'],'delegate'); - if ($allowed) { - $_SESSION['delegate_channel'] = $r[0]['channel_id']; - $_SESSION['delegate'] = $hubloc['xchan_hash']; - $_SESSION['account_id'] = intval($r[0]['channel_account_id']); - // this will set the local_channel authentication in the session - change_channel($r[0]['channel_id']); - $delegate_success = true; - } - } - } + $delegate_success = false; + if ($_REQUEST['delegate']) { + $r = q( + "select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1", + dbesc($_REQUEST['delegate']) + ); + if ($r && intval($r[0]['channel_id'])) { + $allowed = perm_is_allowed($r[0]['channel_id'], $hubloc['xchan_hash'], 'delegate'); + if ($allowed) { + $_SESSION['delegate_channel'] = $r[0]['channel_id']; + $_SESSION['delegate'] = $hubloc['xchan_hash']; + $_SESSION['account_id'] = intval($r[0]['channel_account_id']); + // this will set the local_channel authentication in the session + change_channel($r[0]['channel_id']); + $delegate_success = true; + } + } + } - if (! $delegate_success) { - // normal visitor (remote_channel) login session credentials - $_SESSION['visitor_id'] = $hubloc['xchan_hash']; - $_SESSION['my_url'] = $hubloc['xchan_url']; - $_SESSION['my_address'] = $hubloc['hubloc_addr']; - $_SESSION['remote_hub'] = $hubloc['hubloc_url']; - $_SESSION['DNT'] = 1; - } + if (! $delegate_success) { + // normal visitor (remote_channel) login session credentials + $_SESSION['visitor_id'] = $hubloc['xchan_hash']; + $_SESSION['my_url'] = $hubloc['xchan_url']; + $_SESSION['my_address'] = $hubloc['hubloc_addr']; + $_SESSION['remote_hub'] = $hubloc['hubloc_url']; + $_SESSION['DNT'] = 1; + } - $arr = [ - 'xchan' => $hubloc, - 'url' => App::$query_string, - 'session' => $_SESSION - ]; - /** - * @hooks magic_auth_success - * Called when a magic-auth was successful. - * * \e array \b xchan - * * \e string \b url - * * \e array \b session - */ - call_hooks('magic_auth_success', $arr); + $arr = [ + 'xchan' => $hubloc, + 'url' => App::$query_string, + 'session' => $_SESSION + ]; + /** + * @hooks magic_auth_success + * Called when a magic-auth was successful. + * * \e array \b xchan + * * \e string \b url + * * \e array \b session + */ + call_hooks('magic_auth_success', $arr); - App::set_observer($hubloc); - App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); - if (! get_config('system', 'hide_owa_greeting')) { - info(sprintf( t('OpenWebAuth: %1$s welcomes %2$s'),App::get_hostname(), $hubloc['xchan_name'])); - } + App::set_observer($hubloc); + App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); + if (! get_config('system', 'hide_owa_greeting')) { + info(sprintf(t('OpenWebAuth: %1$s welcomes %2$s'), App::get_hostname(), $hubloc['xchan_name'])); + } - logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']); - return; + logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']); + return; } -function observer_auth($ob_hash) { +function observer_auth($ob_hash) +{ - require_once('include/security.php'); + require_once('include/security.php'); - if ($ob_hash === false) { - return; - } + if ($ob_hash === false) { + return; + } - $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash + $r = q( + "select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc", - dbesc($ob_hash), - dbesc($ob_hash), - dbesc($ob_hash) - ); + dbesc($ob_hash), + dbesc($ob_hash), + dbesc($ob_hash) + ); - if (! $r) { - // finger them if they can't be found. - $wf = discover_by_webbie($ob_hash); - if ($wf) { - $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash + if (! $r) { + // finger them if they can't be found. + $wf = discover_by_webbie($ob_hash); + if ($wf) { + $r = q( + "select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc", - dbesc($ob_hash), - dbesc($ob_hash), - dbesc($ob_hash) - ); - } - } - if (! $r) { - logger('unable to finger ' . $ob_hash); - return; - } + dbesc($ob_hash), + dbesc($ob_hash), + dbesc($ob_hash) + ); + } + } + if (! $r) { + logger('unable to finger ' . $ob_hash); + return; + } - $hubloc = $r[0]; + $hubloc = $r[0]; - $_SESSION['authenticated'] = 1; + $_SESSION['authenticated'] = 1; - // normal visitor (remote_channel) login session credentials - $_SESSION['visitor_id'] = $hubloc['xchan_hash']; - $_SESSION['my_url'] = $hubloc['xchan_url']; + // normal visitor (remote_channel) login session credentials + $_SESSION['visitor_id'] = $hubloc['xchan_hash']; + $_SESSION['my_url'] = $hubloc['xchan_url']; - // For now, only enable authenticated link substitution for zot6 channels or - // those that arrive with a zid. - // This is to prevent signed ActivityPub fetches from getting zid-enabled links. - // If a pre-set zid applies, $_SESSION['my_address'] will have been set already - // in Zotlabs\Web\WebServer.php - // @FIXME: to work seamlessly with Friendica and other platforms that choose to - // provide OWA we will need to store the OWA endpoints for each site in SConfig - // and refer to this to determine whether or not to provide "zidified" links. + // For now, only enable authenticated link substitution for zot6 channels or + // those that arrive with a zid. + // This is to prevent signed ActivityPub fetches from getting zid-enabled links. + // If a pre-set zid applies, $_SESSION['my_address'] will have been set already + // in Zotlabs\Web\WebServer.php + // @FIXME: to work seamlessly with Friendica and other platforms that choose to + // provide OWA we will need to store the OWA endpoints for each site in SConfig + // and refer to this to determine whether or not to provide "zidified" links. - if ($hubloc['hubloc_network'] === 'zot6') { - $_SESSION['my_address'] = $hubloc['hubloc_addr']; - } - $_SESSION['remote_hub'] = $hubloc['hubloc_url']; - $_SESSION['DNT'] = 1; - - App::set_observer($hubloc); - App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); + if ($hubloc['hubloc_network'] === 'zot6') { + $_SESSION['my_address'] = $hubloc['hubloc_addr']; + } + $_SESSION['remote_hub'] = $hubloc['hubloc_url']; + $_SESSION['DNT'] = 1; + App::set_observer($hubloc); + App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); } diff --git a/install/htconfig.sample.php b/install/htconfig.sample.php index 0bac2289f..407ba9b79 100755 --- a/install/htconfig.sample.php +++ b/install/htconfig.sample.php @@ -1,13 +1,13 @@ exec($stmt); - if($r===false) { - echo "\nError executing $stmt: ".var_export($db->errorInfo(), true)."\n"; - $err++; - } else { - $n++; - } - if($n % 5 == 0) - echo "\033[255DExecuting: $file, $n/$c\033[K"; - } - echo "\n"; -} - -$drivers=true; -if(!class_exists('PDO')) - $drivers=false; -if($drivers) { - $drivers = PDO::getAvailableDrivers(); - if(!in_array('pgsql', $drivers) || !in_array('mysql', $drivers)) - $drivers = false; -} -if(!$drivers) { - echo "Sorry. This migration tool requires both mysql and pgsql PDO drivers.\n"; - $r = ask_question("If you are on dreamhost you can enable them. This might work on other shared hosts too. Type 'n' to do it yourself.\nWould you like to try (Y/n)? ", array('y', 'n'), 'y'); - if($r=='y') { - $path = $_SERVER['HOME'] . '/.php/5.4'; - if(!file_exists($path)) - mkdir($path, 0770, true); - - $rcfile = $path . '/phprc'; - - $str = ''; - $mods = get_loaded_extensions(); - foreach(array('pdo_mysql','pdo_pgsql','pgsql') as $ext) - if(!in_array($ext, $mods)) - $str .= 'extension=' . $ext . ".so\n"; - - file_put_contents($rcfile, $str, FILE_APPEND ); - echo "drivers enabled.\nNow type: \033[1m/usr/local/bin/php-5.4 install/".basename($argv[0])."\033[0m\n"; - } - exit(); +function run_sql($file, $db, &$err, &$n) +{ + $sql = file_get_contents($file); + $sql = explode(';', $sql); + $err = 0; + $n = 0; + $c = count($sql); + if (!$c) { + echo "Unknown error.\n"; + exit(); + } + foreach ($sql as $stmt) { + if ($stmt == '' || $stmt == "\n" || $stmt == "\n\n") { + $c--; + continue; + } + $r = $db->exec($stmt); + if ($r === false) { + echo "\nError executing $stmt: " . var_export($db->errorInfo(), true) . "\n"; + $err++; + } else { + $n++; + } + if ($n % 5 == 0) { + echo "\033[255DExecuting: $file, $n/$c\033[K"; + } + } + echo "\n"; } -foreach(array('install','include','mod','view') as $dir) { - if(!file_exists($dir)) { - echo "You must execute from inside the webroot like the cron\n"; - exit(); - } +$drivers = true; +if (!class_exists('PDO')) { + $drivers = false; +} +if ($drivers) { + $drivers = PDO::getAvailableDrivers(); + if (!in_array('pgsql', $drivers) || !in_array('mysql', $drivers)) { + $drivers = false; + } +} +if (!$drivers) { + echo "Sorry. This migration tool requires both mysql and pgsql PDO drivers.\n"; + $r = ask_question("If you are on dreamhost you can enable them. This might work on other shared hosts too. Type 'n' to do it yourself.\nWould you like to try (Y/n)? ", array('y', 'n'), 'y'); + if ($r == 'y') { + $path = $_SERVER['HOME'] . '/.php/5.4'; + if (!file_exists($path)) { + mkdir($path, 0770, true); + } + + $rcfile = $path . '/phprc'; + + $str = ''; + $mods = get_loaded_extensions(); + foreach (array('pdo_mysql','pdo_pgsql','pgsql') as $ext) { + if (!in_array($ext, $mods)) { + $str .= 'extension=' . $ext . ".so\n"; + } + } + + file_put_contents($rcfile, $str, FILE_APPEND); + echo "drivers enabled.\nNow type: \033[1m/usr/local/bin/php-5.4 install/" . basename($argv[0]) . "\033[0m\n"; + } + exit(); +} + +foreach (array('install','include','mod','view') as $dir) { + if (!file_exists($dir)) { + echo "You must execute from inside the webroot like the cron\n"; + exit(); + } } $cfgfile = '.htconfig.php'; -if($argc >= 2 && $argv[1] == '--resume') { - if($argc < 4) { - echo "Resume usage {$argv[0]} --resume \n"; - exit(); - } - $starttable = $argv[2]; - $startrow = $argv[3]; - $cfgfile = '.htconfig.php-mysql'; +if ($argc >= 2 && $argv[1] == '--resume') { + if ($argc < 4) { + echo "Resume usage {$argv[0]} --resume
                    \n"; + exit(); + } + $starttable = $argv[2]; + $startrow = $argv[3]; + $cfgfile = '.htconfig.php-mysql'; } $cfg = parse_htconfig($cfgfile); $type = get_configtype($cfg); -if($type != 'mysql') { - echo "Error. Must start with standard mysql installation in .htconfig.php.\n"; - exit(); +if ($type != 'mysql') { + echo "Error. Must start with standard mysql installation in .htconfig.php.\n"; + exit(); } -if(!$cfg['port']) - $cfg['port'] = 3306; +if (!$cfg['port']) { + $cfg['port'] = 3306; +} try { - $mydb = new PDO("mysql:host={$cfg['host']};dbname={$cfg['data']};port={$cfg['port']}", $cfg['user'], $cfg['pass']); + $mydb = new PDO("mysql:host={$cfg['host']};dbname={$cfg['data']};port={$cfg['port']}", $cfg['user'], $cfg['pass']); } catch (PDOException $e) { - echo "Error connecting to mysql DB: " . $e->getMessage() . "\n"; - exit(); + echo "Error connecting to mysql DB: " . $e->getMessage() . "\n"; + exit(); } // mysql insists on buffering even when you use fetch() instead of fetchAll() for some stupid reason // http://stackoverflow.com/questions/6895098/pdo-mysql-memory-consumption-with-large-result-set -$mydb->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); +$mydb->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); -if(!file_exists('.htconfig.php-pgsql')) { - echo "Enter postgres server info:\n"; - $p['host'] = get_data("Hostname: ", '/[\w.]+/'); - $p['port'] = get_data("Enter port (0 for default): ", '/\d+/'); - $p['user'] = get_data("Username: ", '/\w+/'); - $p['pass'] = get_data("Password: ", '/[[:print:]]+/'); - $p['data'] = get_data("Database name: ", '/\w+/'); - $old = file_get_contents('.htconfig.php'); - $new = preg_replace( - array( - '/^(\$db_host\s*=\s*\')([\w.]+)(\';)$/m', - '/^(\$db_port\s*=\s*\')(\d+)(\';)$/m', - '/^(\$db_user\s*=\s*\')(\w+)(\';)$/m', - '/^(\$db_pass\s*=\s*\')([[:print:]]+)(\';)/m', - '/^(\$db_data\s*=\s*\')(\w+)(\';)$/m', - '/^(\$db_type\s*=\s*\')(\d)(\';)$/m' // in case they already have it - ), array( - "$1{$p['host']}$3", - "\${1}{$p['port']}$3", - "$1{$p['user']}$3", - "$1{$p['pass']}$3", - "$1{$p['data']}$3\n\$db_type = '1';\n", // they probably don't - "\${1}1$3" - ), - $old, - 1, - $repl - ); - if($new === false || $repl < 5) { - echo "Failed. Please make a postgres config file named .htconfig.php-pgsql - Be sure to add \"\$db_type = '1';\" to your config.\n"; - exit(); - } - file_put_contents('.htconfig.php-pgsql', $new); +if (!file_exists('.htconfig.php-pgsql')) { + echo "Enter postgres server info:\n"; + $p['host'] = get_data("Hostname: ", '/[\w.]+/'); + $p['port'] = get_data("Enter port (0 for default): ", '/\d+/'); + $p['user'] = get_data("Username: ", '/\w+/'); + $p['pass'] = get_data("Password: ", '/[[:print:]]+/'); + $p['data'] = get_data("Database name: ", '/\w+/'); + $old = file_get_contents('.htconfig.php'); + $new = preg_replace( + array( + '/^(\$db_host\s*=\s*\')([\w.]+)(\';)$/m', + '/^(\$db_port\s*=\s*\')(\d+)(\';)$/m', + '/^(\$db_user\s*=\s*\')(\w+)(\';)$/m', + '/^(\$db_pass\s*=\s*\')([[:print:]]+)(\';)/m', + '/^(\$db_data\s*=\s*\')(\w+)(\';)$/m', + '/^(\$db_type\s*=\s*\')(\d)(\';)$/m' // in case they already have it + ), + array( + "$1{$p['host']}$3", + "\${1}{$p['port']}$3", + "$1{$p['user']}$3", + "$1{$p['pass']}$3", + "$1{$p['data']}$3\n\$db_type = '1';\n", // they probably don't + "\${1}1$3" + ), + $old, + 1, + $repl + ); + if ($new === false || $repl < 5) { + echo "Failed. Please make a postgres config file named .htconfig.php-pgsql - Be sure to add \"\$db_type = '1';\" to your config.\n"; + exit(); + } + file_put_contents('.htconfig.php-pgsql', $new); } $pcfg = parse_htconfig('.htconfig.php-pgsql'); $ptype = get_configtype($pcfg); -if($ptype != 'pgsql') { - echo "Error. Must have a valid pgsql config named .htconfig.php-pgsql. Be sure to add \"\$db_type = '1';\" to your config.\n"; - exit(); +if ($ptype != 'pgsql') { + echo "Error. Must have a valid pgsql config named .htconfig.php-pgsql. Be sure to add \"\$db_type = '1';\" to your config.\n"; + exit(); } -if(!$pcfg['port']) - $pcfg['port'] = 5432; +if (!$pcfg['port']) { + $pcfg['port'] = 5432; +} try { - $pgdb = new PDO("pgsql:host={$pcfg['host']};dbname={$pcfg['data']};port={$pcfg['port']}", $pcfg['user'], $pcfg['pass']); + $pgdb = new PDO("pgsql:host={$pcfg['host']};dbname={$pcfg['data']};port={$pcfg['port']}", $pcfg['user'], $pcfg['pass']); } catch (PDOException $e) { - echo "Error connecting to pgsql DB: " . $e->getMessage() . "\n"; - echo "cfg string: " . "pgsql:host={$pcfg['host']};dbname={$pcfg['data']};port={$pcfg['port']}\n"; - exit(); + echo "Error connecting to pgsql DB: " . $e->getMessage() . "\n"; + echo "cfg string: " . "pgsql:host={$pcfg['host']};dbname={$pcfg['data']};port={$pcfg['port']}\n"; + exit(); } $B = "\033[0;34m"; $H = "\033[0;35m"; @@ -199,159 +223,172 @@ $W = "\033[1;37m"; $M = "\033[1;31m"; $N = "\033[0m"; -if(isset($starttable)) { - $r = ask_question("Ready to migrate {$W}Red{$M}(#){$W}Matrix$N from mysql db @$B{$cfg['host']}$N/$B{$cfg['data']}$N to postgres db @$B{$pcfg['host']}$N/$B{$pcfg['data']}$N. +if (isset($starttable)) { + $r = ask_question( + "Ready to migrate {$W}Red{$M}(#){$W}Matrix$N from mysql db @$B{$cfg['host']}$N/$B{$cfg['data']}$N to postgres db @$B{$pcfg['host']}$N/$B{$pcfg['data']}$N. Resuming failed migration ({$M}experimental$N) starting at table '$starttable' row $startrow. -Are you ready to begin (N/y)? ", - array('y', 'n'), - 'n' - ); - if($r == 'n') - exit(); +Are you ready to begin (N/y)? ", + array('y', 'n'), + 'n' + ); + if ($r == 'n') { + exit(); + } } else { - $r = ask_question("Ready to migrate {$W}Red{$M}(#){$W}Matrix$N from mysql db @$B{$cfg['host']}$N/$B{$cfg['data']}$N to postgres db @$B{$pcfg['host']}$N/$B{$pcfg['data']}$N. + $r = ask_question("Ready to migrate {$W}Red{$M}(#){$W}Matrix$N from mysql db @$B{$cfg['host']}$N/$B{$cfg['data']}$N to postgres db @$B{$pcfg['host']}$N/$B{$pcfg['data']}$N. The site will be disabled during the migration by moving the $H.htconfig.php$N file to $H.htconfig.php-mysql$N. If for any reason the migration fails, you will need to move the config file back into place manually before trying again. -Are you ready to begin (N/y)? ", array('y','n'), 'n' - ); +Are you ready to begin (N/y)? ", array('y','n'), 'n'); - if($r == 'n') - exit(); + if ($r == 'n') { + exit(); + } - rename('.htconfig.php', '.htconfig.php-mysql'); + rename('.htconfig.php', '.htconfig.php-mysql'); - run_sql('install/schema_postgres.sql', $pgdb, $err, $n); - if($err) { - echo "There were $err errors creating the pgsql schema. Unable to continue.\n"; - exit(); - } + run_sql('install/schema_postgres.sql', $pgdb, $err, $n); + if ($err) { + echo "There were $err errors creating the pgsql schema. Unable to continue.\n"; + exit(); + } - echo "pgsql schema created. $n queries executed successfully.\n"; + echo "pgsql schema created. $n queries executed successfully.\n"; } $res = $pgdb->query("select relname, attname, pg_type.typname from ((pg_attribute inner join pg_class on attrelid=pg_class.oid) inner join pg_type on atttypid=pg_type.oid) inner join pg_namespace on relnamespace=pg_namespace.oid where nspname='public' and atttypid not in (26,27,28,29) and relkind='r' and attname <> 'item_search_vector';"); -if($res === false) { - echo "Error reading back schema. Unable to continue.\n"; - var_export($pgdb->errorInfo()); - exit(); +if ($res === false) { + echo "Error reading back schema. Unable to continue.\n"; + var_export($pgdb->errorInfo()); + exit(); } $schema = []; -while(($row = $res->fetch()) !== false) - $schema[$row[0]][$row[1]] = $row[2]; - +while (($row = $res->fetch()) !== false) { + $schema[$row[0]][$row[1]] = $row[2]; +} + $res = $pgdb->query("select relname, attname from pg_attribute inner join pg_class on attrelid=pg_class.oid inner join pg_constraint on conrelid=pg_class.oid and pg_attribute.attnum = any (conkey) where contype='p';"); -if($res === false) { - echo "Error reading back primary keys. Unable to continue.\n"; - var_export($pgdb->errorInfo()); - exit(); +if ($res === false) { + echo "Error reading back primary keys. Unable to continue.\n"; + var_export($pgdb->errorInfo()); + exit(); } $pkeys = []; -while(($row = $res->fetch()) !== false) - $pkeys[$row[0]] = $row[1]; +while (($row = $res->fetch()) !== false) { + $pkeys[$row[0]] = $row[1]; +} -$err = 0; $n = 0; +$err = 0; +$n = 0; $reserved = array('ignore','key','with'); -foreach($schema as $table=>$fields) { - if(isset($starttable) && !$n && $table != $starttable) { - echo "Skipping table $table\n"; - continue; - } - $fnames = array_keys($fields); - $pfnames = array_keys($fields); - - foreach($fnames as &$fname) - if(in_array($fname, $reserved)) - $fname = '`' . $fname . '`'; - $fstr = implode(',', $fnames); - - foreach($pfnames as &$pfname) - if(in_array($pfname, $reserved)) - $pfname = '"' . $pfname . '"'; - $pfstr = implode(',', $pfnames); - - $cres = $mydb->query("SELECT count(*) FROM $table;"); - if($cres === false) { - echo "Fatal error counting table $table: ".var_export($mydb->errorInfo(), true)."\n"; - exit(); - } - $nrows = $cres->fetchColumn(0); - $cres->closeCursor(); - - if(!$nrows) { - echo "TABLE $table has 0 rows in mysql db.\n"; - continue; - } - - $pstr = ''; - for($x=0, $c=count($fields); $x < $c; $x++) - $pstr .= ($x ? ',?' : '?'); +foreach ($schema as $table => $fields) { + if (isset($starttable) && !$n && $table != $starttable) { + echo "Skipping table $table\n"; + continue; + } + $fnames = array_keys($fields); + $pfnames = array_keys($fields); - if(isset($starttable) && $table == $starttable) { - $selectsql = "SELECT $fstr FROM $table ORDER BY {$pkeys[$table]} LIMIT $nrows OFFSET $startrow;"; - $crow = $startrow; - } else { - $selectsql = "SELECT $fstr FROM $table ORDER BY {$pkeys[$table]};"; - $crow = 0; - } + foreach ($fnames as &$fname) { + if (in_array($fname, $reserved)) { + $fname = '`' . $fname . '`'; + } + } + $fstr = implode(',', $fnames); - echo "\033[255DTABLE: $table [$c fields] $crow/$nrows (".number_format(($crow/$nrows)*100,2)."%)\033[K"; - - $res = $mydb->query($selectsql); - if($res === false) { - echo "Fatal Error importing table $table: ".var_export($mydb->errorInfo(), true)."\n"; - exit(); - } + foreach ($pfnames as &$pfname) { + if (in_array($pfname, $reserved)) { + $pfname = '"' . $pfname . '"'; + } + } + $pfstr = implode(',', $pfnames); - $istmt = $pgdb->prepare("INSERT INTO $table ($pfstr) VALUES ($pstr);"); - if($istmt === false) { - echo "Fatal error preparing query. Aborting.\n"; - var_export($pgdb->errorInfo()); - exit(); - } + $cres = $mydb->query("SELECT count(*) FROM $table;"); + if ($cres === false) { + echo "Fatal error counting table $table: " . var_export($mydb->errorInfo(), true) . "\n"; + exit(); + } + $nrows = $cres->fetchColumn(0); + $cres->closeCursor(); - while(($row = $res->fetch(PDO::FETCH_NUM)) !== false) { - foreach($row as $idx => &$val) - if(array_slice(array_values($fields),$idx,1)[0] == 'timestamp' && $val == '0000-00-00 00:00:00') - $istmt->bindParam($idx+1, ($nulldate='0001-01-01 00:00:00')); - else if(array_slice(array_values($fields),$idx,1)[0] == 'bytea') - $istmt->bindParam($idx+1, $val, PDO::PARAM_LOB); - else - $istmt->bindParam($idx+1, $val); - $r = $istmt->execute(); - if($r === false) { - $err++; - echo "Insert error: ".var_export(array($pgdb->errorInfo(), $table, $fields, $row), true)."\nResume with {$argv[0]} --resume $table $crow\n"; - exit(); - } else - $n++; - $crow++; - if(($crow % 10) == 0 || $crow == $nrows) - echo "\033[255DTABLE: $table [$c fields] $crow/$nrows (".number_format(($crow/$nrows)*100,2)."%)\033[K"; - } - $res->closeCursor(); - echo "\n"; + if (!$nrows) { + echo "TABLE $table has 0 rows in mysql db.\n"; + continue; + } + + $pstr = ''; + for ($x = 0, $c = count($fields); $x < $c; $x++) { + $pstr .= ($x ? ',?' : '?'); + } + + if (isset($starttable) && $table == $starttable) { + $selectsql = "SELECT $fstr FROM $table ORDER BY {$pkeys[$table]} LIMIT $nrows OFFSET $startrow;"; + $crow = $startrow; + } else { + $selectsql = "SELECT $fstr FROM $table ORDER BY {$pkeys[$table]};"; + $crow = 0; + } + + echo "\033[255DTABLE: $table [$c fields] $crow/$nrows (" . number_format(($crow / $nrows) * 100, 2) . "%)\033[K"; + + $res = $mydb->query($selectsql); + if ($res === false) { + echo "Fatal Error importing table $table: " . var_export($mydb->errorInfo(), true) . "\n"; + exit(); + } + + $istmt = $pgdb->prepare("INSERT INTO $table ($pfstr) VALUES ($pstr);"); + if ($istmt === false) { + echo "Fatal error preparing query. Aborting.\n"; + var_export($pgdb->errorInfo()); + exit(); + } + + while (($row = $res->fetch(PDO::FETCH_NUM)) !== false) { + foreach ($row as $idx => &$val) { + if (array_slice(array_values($fields), $idx, 1)[0] == 'timestamp' && $val == '0000-00-00 00:00:00') { + $istmt->bindParam($idx + 1, ($nulldate = '0001-01-01 00:00:00')); + } elseif (array_slice(array_values($fields), $idx, 1)[0] == 'bytea') { + $istmt->bindParam($idx + 1, $val, PDO::PARAM_LOB); + } else { + $istmt->bindParam($idx + 1, $val); + } + } + $r = $istmt->execute(); + if ($r === false) { + $err++; + echo "Insert error: " . var_export(array($pgdb->errorInfo(), $table, $fields, $row), true) . "\nResume with {$argv[0]} --resume $table $crow\n"; + exit(); + } else { + $n++; + } + $crow++; + if (($crow % 10) == 0 || $crow == $nrows) { + echo "\033[255DTABLE: $table [$c fields] $crow/$nrows (" . number_format(($crow / $nrows) * 100, 2) . "%)\033[K"; + } + } + $res->closeCursor(); + echo "\n"; } echo "Done with $err errors and $n inserts.\n"; -if($err) { - echo "Migration had errors. Aborting.\n"; - exit(); +if ($err) { + echo "Migration had errors. Aborting.\n"; + exit(); } run_sql('install/migrate_mypg_fixseq.sql', $pgdb, $err, $n); echo "Sequences updated with $err errors and $n inserts.\n"; -if($err) - exit(); - +if ($err) { + exit(); +} + $r = ask_question("Everything successful. Once you connect up the pg database there is no going back. Do you want to make it live (N,y)?", array('y', 'n'), 'n'); -if($r == 'n') { - echo "You can make active by renaming .htconfig.php-pgsql to .htconfig.php, or start over by renaming .htconfig.php-mysql to .htconfig.php\n"; - exit(); -} +if ($r == 'n') { + echo "You can make active by renaming .htconfig.php-pgsql to .htconfig.php, or start over by renaming .htconfig.php-mysql to .htconfig.php\n"; + exit(); +} rename('.htconfig.php-pgsql', '.htconfig.php'); echo "Done. {$W}Red{$M}(#){$W}Matrix$N now running on postgres.\n"; - - diff --git a/install/testargs.php b/install/testargs.php index 4c9bce4e9..a05405944 100644 --- a/install/testargs.php +++ b/install/testargs.php @@ -8,14 +8,14 @@ * During installation we need to check if register_argc_argv is * enabled for the command line PHP processor, because otherwise * deliveries will fail. So we will do a shell exec of php and - * execute this file with a command line argument, and see if it - * echoes the argument back to us. Otherwise notify the person + * execute this file with a command line argument, and see if it + * echoes the argument back to us. Otherwise notify the person * that their installation doesn't meet the system requirements. * - */ + */ - -if(($argc > 1) && isset($argv[1])) - echo $argv[1]; -else - echo ''; +if (($argc > 1) && isset($argv[1])) { + echo $argv[1]; +} else { + echo ''; +} diff --git a/tests/unit/Access/AccessListTest.php b/tests/unit/Access/AccessListTest.php index ee9623a7f..ea3fc5570 100644 --- a/tests/unit/Access/AccessListTest.php +++ b/tests/unit/Access/AccessListTest.php @@ -1,4 +1,5 @@ '', - 'allow_gid' => '', - 'deny_cid' => '', - 'deny_gid' => '' - ]; + /** + * @brief Expected result for most tests. + * @var array + */ + protected $expectedResult = [ + 'allow_cid' => '', + 'allow_gid' => '', + 'deny_cid' => '', + 'deny_gid' => '' + ]; - public function testConstructor() { - $channel = [ - 'channel_allow_cid' => '', - 'channel_allow_gid' => '', - 'channel_deny_cid' => '', - 'channel_deny_gid' => '' - ]; + public function testConstructor() + { + $channel = [ + 'channel_allow_cid' => '', + 'channel_allow_gid' => '', + 'channel_deny_cid' => '', + 'channel_deny_gid' => '' + ]; - $accessList = new AccessControl($channel); + $accessList = new AccessControl($channel); - $this->assertEquals($this->expectedResult, $accessList->get()); - $this->assertFalse($accessList->get_explicit()); - } + $this->assertEquals($this->expectedResult, $accessList->get()); + $this->assertFalse($accessList->get_explicit()); + } - /** - * @expectedException PHPUnit\Framework\Error\Error - */ - public function testPHPErrorOnInvalidConstructor() { - $accessList = new AccessControl('invalid'); - // Causes: "Illegal string offset 'channel_allow_cid'" - } + /** + * @expectedException PHPUnit\Framework\Error\Error + */ + public function testPHPErrorOnInvalidConstructor() + { + $accessList = new AccessControl('invalid'); + // Causes: "Illegal string offset 'channel_allow_cid'" + } - public function testDefaultGetExplicit() { - $accessList = new AccessControl([]); + public function testDefaultGetExplicit() + { + $accessList = new AccessControl([]); - $this->assertFalse($accessList->get_explicit()); - } + $this->assertFalse($accessList->get_explicit()); + } - public function testDefaultGet() { - $arr = [ - 'allow_cid' => '', - 'allow_gid' => '', - 'deny_cid' => '', - 'deny_gid' => '' - ]; + public function testDefaultGet() + { + $arr = [ + 'allow_cid' => '', + 'allow_gid' => '', + 'deny_cid' => '', + 'deny_gid' => '' + ]; - $accessList = new AccessControl([]); + $accessList = new AccessControl([]); - $this->assertEquals($arr, $accessList->get()); - } + $this->assertEquals($arr, $accessList->get()); + } - public function testSet() { - $arr = [ - 'allow_cid' => '', - 'allow_gid' => '', - 'deny_cid' => '', - 'deny_gid' => '' - ]; - $accessList = new AccessControl([]); + public function testSet() + { + $arr = [ + 'allow_cid' => '', + 'allow_gid' => '', + 'deny_cid' => '', + 'deny_gid' => '' + ]; + $accessList = new AccessControl([]); - // default explicit true - $accessList->set($arr); + // default explicit true + $accessList->set($arr); - $this->assertEquals($this->expectedResult, $accessList->get()); - $this->assertTrue($accessList->get_explicit()); + $this->assertEquals($this->expectedResult, $accessList->get()); + $this->assertTrue($accessList->get_explicit()); - // set explicit false - $accessList->set($arr, false); + // set explicit false + $accessList->set($arr, false); - $this->assertEquals($this->expectedResult, $accessList->get()); - $this->assertFalse($accessList->get_explicit()); - } + $this->assertEquals($this->expectedResult, $accessList->get()); + $this->assertFalse($accessList->get_explicit()); + } - /** - * @expectedException PHPUnit\Framework\Error\Error - */ - public function testPHPErrorOnInvalidSet() { - $accessList = new AccessControl([]); + /** + * @expectedException PHPUnit\Framework\Error\Error + */ + public function testPHPErrorOnInvalidSet() + { + $accessList = new AccessControl([]); - $accessList->set('invalid'); - // Causes: "Illegal string offset 'allow_cid'" - } + $accessList->set('invalid'); + // Causes: "Illegal string offset 'allow_cid'" + } - /** - * set_from_[] calls some other functions, too which are not yet unit tested. - * @uses ::perms2str - * @uses ::sanitise_acl - * @uses ::notags - */ - public function testSetFromArray() { - // array - $arraySetFromArray = [ - 'contact_allow' => ['acid', 'acid2'], - 'group_allow' => ['agid'], - 'contact_deny' => [], - 'group_deny' => ['dgid', 'dgid2'] - ]; - $accessList = new AccessControl([]); - $accessList->set_from_array($arraySetFromArray); + /** + * set_from_[] calls some other functions, too which are not yet unit tested. + * @uses ::perms2str + * @uses ::sanitise_acl + * @uses ::notags + */ + public function testSetFromArray() + { + // array + $arraySetFromArray = [ + 'contact_allow' => ['acid', 'acid2'], + 'group_allow' => ['agid'], + 'contact_deny' => [], + 'group_deny' => ['dgid', 'dgid2'] + ]; + $accessList = new AccessControl([]); + $accessList->set_from_array($arraySetFromArray); - $this->assertEquals($this->expectedResult, $accessList->get()); - $this->assertTrue($accessList->get_explicit()); + $this->assertEquals($this->expectedResult, $accessList->get()); + $this->assertTrue($accessList->get_explicit()); - // string - $stringSetFromArray = [ - 'contact_allow' => 'acid,acid2', - 'group_allow' => 'agid', - 'contact_deny' => '', - 'group_deny' => 'dgid, dgid2' - ]; - $accessList2 = new AccessControl([]); - $accessList2->set_from_array($stringSetFromArray, false); + // string + $stringSetFromArray = [ + 'contact_allow' => 'acid,acid2', + 'group_allow' => 'agid', + 'contact_deny' => '', + 'group_deny' => 'dgid, dgid2' + ]; + $accessList2 = new AccessControl([]); + $accessList2->set_from_array($stringSetFromArray, false); - $this->assertEquals($this->expectedResult, $accessList2->get()); - $this->assertFalse($accessList2->get_explicit()); - } + $this->assertEquals($this->expectedResult, $accessList2->get()); + $this->assertFalse($accessList2->get_explicit()); + } - /** - * @dataProvider isprivateProvider - */ - public function testIsPrivate($channel) { - $accessListPublic = new AccessControl([]); - $this->assertFalse($accessListPublic->is_private()); + /** + * @dataProvider isprivateProvider + */ + public function testIsPrivate($channel) + { + $accessListPublic = new AccessControl([]); + $this->assertFalse($accessListPublic->is_private()); - $accessListPrivate = new AccessControl($channel); - $this->assertTrue($accessListPrivate->is_private()); - } + $accessListPrivate = new AccessControl($channel); + $this->assertTrue($accessListPrivate->is_private()); + } - public function isprivateProvider() { - return [ - 'all set' => [[ - 'channel_allow_cid' => '', - 'channel_allow_gid' => '', - 'channel_deny_cid' => '', - 'channel_deny_gid' => '' - ]], - 'only one set' => [[ - 'channel_allow_cid' => '', - 'channel_allow_gid' => '', - 'channel_deny_cid' => '', - 'channel_deny_gid' => '' - ]], - 'acid+null' => [[ - 'channel_allow_cid' => '', - 'channel_allow_gid' => null, - 'channel_deny_cid' => '', - 'channel_deny_gid' => '' - ]] - ]; - } - -} \ No newline at end of file + public function isprivateProvider() + { + return [ + 'all set' => [[ + 'channel_allow_cid' => '', + 'channel_allow_gid' => '', + 'channel_deny_cid' => '', + 'channel_deny_gid' => '' + ]], + 'only one set' => [[ + 'channel_allow_cid' => '', + 'channel_allow_gid' => '', + 'channel_deny_cid' => '', + 'channel_deny_gid' => '' + ]], + 'acid+null' => [[ + 'channel_allow_cid' => '', + 'channel_allow_gid' => null, + 'channel_deny_cid' => '', + 'channel_deny_gid' => '' + ]] + ]; + } +} diff --git a/tests/unit/Access/PermissionLimitsTest.php b/tests/unit/Access/PermissionLimitsTest.php index 57ad42a19..03c9b055b 100644 --- a/tests/unit/Access/PermissionLimitsTest.php +++ b/tests/unit/Access/PermissionLimitsTest.php @@ -1,4 +1,5 @@ getFunctionMock('Zotlabs\Access', 't'); + $t->expects($this->exactly($permsCount)); - // Create a stub for global function t() with expectation - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t->expects($this->exactly($permsCount)); + $stdlimits = PermissionLimits::Std_Limits(); + $this->assertCount($permsCount, $stdlimits, "There should be $permsCount permissions."); - $stdlimits = PermissionLimits::Std_Limits(); - $this->assertCount($permsCount, $stdlimits, "There should be $permsCount permissions."); - - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_stream']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['send_stream']); - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_profile']); - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_contacts']); - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_storage']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_storage']); - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_pages']); - $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_wiki']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_pages']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_wiki']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_wall']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_comments']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_mail']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_like']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['tag_deliver']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['chat']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['republish']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['delegate']); - } - -} \ No newline at end of file + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_stream']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['send_stream']); + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_profile']); + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_contacts']); + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_storage']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_storage']); + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_pages']); + $this->assertEquals(PERMS_PUBLIC, $stdlimits['view_wiki']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_pages']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['write_wiki']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_wall']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_comments']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_mail']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_like']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['tag_deliver']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['chat']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['republish']); + $this->assertEquals(PERMS_SPECIFIC, $stdlimits['delegate']); + } +} diff --git a/tests/unit/Access/PermissionRolesTest.php b/tests/unit/Access/PermissionRolesTest.php index d2189afc9..4ef9b2d8b 100644 --- a/tests/unit/Access/PermissionRolesTest.php +++ b/tests/unit/Access/PermissionRolesTest.php @@ -1,4 +1,5 @@ assertEquals($expectedVersion, PermissionRoles::version()); - $this->assertEquals($expectedVersion, PermissionRoles::version()); - - $pr = new PermissionRoles(); - $this->assertEquals($expectedVersion, $pr->version()); - } + $pr = new PermissionRoles(); + $this->assertEquals($expectedVersion, $pr->version()); + } - public function testRoles() { - // Create a stub for global function t() with expectation - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t->expects($this->atLeastOnce())->willReturnCallback( - function ($string) { - return $string; - } - ); + public function testRoles() + { + // Create a stub for global function t() with expectation + $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $t->expects($this->atLeastOnce())->willReturnCallback( + function ($string) { + return $string; + } + ); - $roles = PermissionRoles::roles(); - $r = new PermissionRoles(); - $this->assertEquals($roles, $r->roles()); + $roles = PermissionRoles::roles(); + $r = new PermissionRoles(); + $this->assertEquals($roles, $r->roles()); - $socialNetworking = [ - 'social_federation' => 'Social - Federation', - 'social' => 'Social - Mostly Public', - 'social_restricted' => 'Social - Restricted', - 'social_private' => 'Social - Private' - ]; + $socialNetworking = [ + 'social_federation' => 'Social - Federation', + 'social' => 'Social - Mostly Public', + 'social_restricted' => 'Social - Restricted', + 'social_private' => 'Social - Private' + ]; - $this->assertArraySubset(['Social Networking' => $socialNetworking], $roles); - $this->assertEquals($socialNetworking, $roles['Social Networking']); + $this->assertArraySubset(['Social Networking' => $socialNetworking], $roles); + $this->assertEquals($socialNetworking, $roles['Social Networking']); - $this->assertCount(5, $roles, 'There should be 5 permission groups.'); + $this->assertCount(5, $roles, 'There should be 5 permission groups.'); - $this->assertCount(1, $roles['Other'], "In the 'Other' group should be just one permission role"); - } + $this->assertCount(1, $roles['Other'], "In the 'Other' group should be just one permission role"); + } - /** - * @uses ::call_hooks - * @uses Zotlabs\Access\PermissionLimits::Std_Limits - * @uses Zotlabs\Access\Permissions::Perms - */ - public function testRole_perms() { - // Create a stub for global function t() - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t = $this->getFunctionMock('Zotlabs\Access', 'get_config'); + /** + * @uses ::call_hooks + * @uses Zotlabs\Access\PermissionLimits::Std_Limits + * @uses Zotlabs\Access\Permissions::Perms + */ + public function testRole_perms() + { + // Create a stub for global function t() + $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $t = $this->getFunctionMock('Zotlabs\Access', 'get_config'); - $rp_social = PermissionRoles::role_perms('social'); - $this->assertEquals('social', $rp_social['role']); + $rp_social = PermissionRoles::role_perms('social'); + $this->assertEquals('social', $rp_social['role']); - $rp_custom = PermissionRoles::role_perms('custom'); - $this->assertEquals(['role' => 'custom'], $rp_custom); - - $rp_nonexistent = PermissionRoles::role_perms('nonexistent'); - $this->assertEquals(['role' => 'nonexistent'], $rp_nonexistent); - } + $rp_custom = PermissionRoles::role_perms('custom'); + $this->assertEquals(['role' => 'custom'], $rp_custom); + $rp_nonexistent = PermissionRoles::role_perms('nonexistent'); + $this->assertEquals(['role' => 'nonexistent'], $rp_nonexistent); + } } diff --git a/tests/unit/Access/PermissionsTest.php b/tests/unit/Access/PermissionsTest.php index 461554ae4..cb643bb5a 100644 --- a/tests/unit/Access/PermissionsTest.php +++ b/tests/unit/Access/PermissionsTest.php @@ -1,4 +1,5 @@ assertEquals($expectedVersion, Permissions::version()); - // static call - $this->assertEquals($expectedVersion, Permissions::version()); + // instance call + $p = new Permissions(); + $this->assertEquals($expectedVersion, $p->version()); + } - // instance call - $p = new Permissions(); - $this->assertEquals($expectedVersion, $p->version()); - } + /** + * @coversNothing + */ + public function testVersionEqualsPermissionRoles() + { + $p = new Permissions(); + $pr = new PermissionRoles(); + $this->assertEquals($p->version(), $pr->version()); + } - /** - * @coversNothing - */ - public function testVersionEqualsPermissionRoles() { - $p = new Permissions(); - $pr = new PermissionRoles(); - $this->assertEquals($p->version(), $pr->version()); - } + /** + * @uses ::call_hooks + */ + public function testPerms() + { + // There are 18 default perms + $permsCount = 18; - /** - * @uses ::call_hooks - */ - public function testPerms() { - // There are 18 default perms - $permsCount = 18; + // Create a stub for global function t() with expectation + $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $t->expects($this->exactly(2 * $permsCount))->willReturnCallback( + function ($string) { + return $string; + } + ); - // Create a stub for global function t() with expectation - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t->expects($this->exactly(2*$permsCount))->willReturnCallback( - function ($string) { - return $string; - } - ); + // static method Perms() + $perms = Permissions::Perms(); - // static method Perms() - $perms = Permissions::Perms(); + $p = new Permissions(); + $this->assertEquals($perms, $p->Perms()); - $p = new Permissions(); - $this->assertEquals($perms, $p->Perms()); + $this->assertEquals($permsCount, count($perms), "There should be $permsCount permissions."); - $this->assertEquals($permsCount, count($perms), "There should be $permsCount permissions."); + $this->assertEquals('Can view my channel stream and posts', $perms['view_stream']); - $this->assertEquals('Can view my channel stream and posts', $perms['view_stream']); + // non existent perm should not be set + $this->assertFalse(isset($perms['invalid_perm'])); + } - // non existent perm should not be set - $this->assertFalse(isset($perms['invalid_perm'])); - } + /** + * filter parmeter is only used in hook \b permissions_list. So the result + * in this test should be the same as if there was no filter parameter. + * + * @todo Stub call_hooks() function and also test filter + * + * @uses ::call_hooks + */ + public function testPermsFilter() + { + // There are 18 default perms + $permsCount = 18; - /** - * filter parmeter is only used in hook \b permissions_list. So the result - * in this test should be the same as if there was no filter parameter. - * - * @todo Stub call_hooks() function and also test filter - * - * @uses ::call_hooks - */ - public function testPermsFilter() { - // There are 18 default perms - $permsCount = 18; + // Create a stub for global function t() with expectation + $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $t->expects($this->exactly(2 * $permsCount))->willReturnCallback( + function ($string) { + return $string; + } + ); - // Create a stub for global function t() with expectation - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t->expects($this->exactly(2*$permsCount))->willReturnCallback( - function ($string) { - return $string; - } - ); + $perms = Permissions::Perms('view_'); + $this->assertEquals($permsCount, count($perms)); - $perms = Permissions::Perms('view_'); - $this->assertEquals($permsCount, count($perms)); + $this->assertEquals('Can view my channel stream and posts', $perms['view_stream']); - $this->assertEquals('Can view my channel stream and posts', $perms['view_stream']); + $perms = Permissions::Perms('invalid_perm'); + $this->assertEquals($permsCount, count($perms)); + } - $perms = Permissions::Perms('invalid_perm'); - $this->assertEquals($permsCount, count($perms)); - } + /** + * Better should mock Permissions::Perms, but not possible with static methods. + * + * @uses ::call_hooks + * + * @dataProvider FilledPermsProvider + * + * @param array $permarr An indexed permissions array to pass + * @param array $expected The expected result perms array + */ + public function testFilledPerms($permarr, $expected) + { + // Create a stub for global function t() + $t = $this->getFunctionMock('Zotlabs\Access', 't'); - /** - * Better should mock Permissions::Perms, but not possible with static methods. - * - * @uses ::call_hooks - * - * @dataProvider FilledPermsProvider - * - * @param array $permarr An indexed permissions array to pass - * @param array $expected The expected result perms array - */ - public function testFilledPerms($permarr, $expected) { - // Create a stub for global function t() - $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $this->assertEquals($expected, Permissions::FilledPerms($permarr)); + } + /** + * @return array An associative array with test values for FilledPerms() + * * \e array Indexed array which is passed as parameter to FilledPerms() + * * \e array Expected associative result array with filled perms + */ + public function FilledPermsProvider() + { + return [ + 'Empty param array' => [ + [], + [ + 'view_stream' => 0, + 'send_stream' => 0, + 'view_profile' => 0, + 'view_contacts' => 0, + 'view_storage' => 0, + 'write_storage' => 0, + 'view_pages' => 0, + 'view_wiki' => 0, + 'write_pages' => 0, + 'write_wiki' => 0, + 'post_wall' => 0, + 'post_comments' => 0, + 'post_mail' => 0, + 'post_like' => 0, + 'tag_deliver' => 0, + 'chat' => 0, + 'republish' => 0, + 'delegate' => 0 + ] + ], + 'provide view_stream and view_pages as param' => [ + ['view_stream', 'view_pages'], + [ + 'view_stream' => 1, + 'send_stream' => 0, + 'view_profile' => 0, + 'view_contacts' => 0, + 'view_storage' => 0, + 'write_storage' => 0, + 'view_pages' => 1, + 'view_wiki' => 0, + 'write_pages' => 0, + 'write_wiki' => 0, + 'post_wall' => 0, + 'post_comments' => 0, + 'post_mail' => 0, + 'post_like' => 0, + 'tag_deliver' => 0, + 'chat' => 0, + 'republish' => 0, + 'delegate' => 0 + ] + ], + 'provide an unknown param' => [ + ['view_stream', 'unknown_perm'], + [ + 'view_stream' => 1, + 'send_stream' => 0, + 'view_profile' => 0, + 'view_contacts' => 0, + 'view_storage' => 0, + 'write_storage' => 0, + 'view_pages' => 0, + 'view_wiki' => 0, + 'write_pages' => 0, + 'write_wiki' => 0, + 'post_wall' => 0, + 'post_comments' => 0, + 'post_mail' => 0, + 'post_like' => 0, + 'tag_deliver' => 0, + 'chat' => 0, + 'republish' => 0, + 'delegate' => 0 + ] + ] + ]; + } + /** + * @uses ::call_hooks + */ + public function testFilledPermsNull() + { + // Create a stub for global function t() with expectation + $t = $this->getFunctionMock('Zotlabs\Access', 't'); + $t->expects($this->atLeastOnce()); + // Create a stub for global function bt() with expectations + $bt = $this->getFunctionMock('Zotlabs\Access', 'btlogger'); + $bt->expects($this->once())->with($this->equalTo('FilledPerms: null')); - $this->assertEquals($expected, Permissions::FilledPerms($permarr)); - } - /** - * @return array An associative array with test values for FilledPerms() - * * \e array Indexed array which is passed as parameter to FilledPerms() - * * \e array Expected associative result array with filled perms - */ - public function FilledPermsProvider() { - return [ - 'Empty param array' => [ - [], - [ - 'view_stream' => 0, - 'send_stream' => 0, - 'view_profile' => 0, - 'view_contacts' => 0, - 'view_storage' => 0, - 'write_storage' => 0, - 'view_pages' => 0, - 'view_wiki' => 0, - 'write_pages' => 0, - 'write_wiki' => 0, - 'post_wall' => 0, - 'post_comments' => 0, - 'post_mail' => 0, - 'post_like' => 0, - 'tag_deliver' => 0, - 'chat' => 0, - 'republish' => 0, - 'delegate' => 0 - ] - ], - 'provide view_stream and view_pages as param' => [ - ['view_stream', 'view_pages'], - [ - 'view_stream' => 1, - 'send_stream' => 0, - 'view_profile' => 0, - 'view_contacts' => 0, - 'view_storage' => 0, - 'write_storage' => 0, - 'view_pages' => 1, - 'view_wiki' => 0, - 'write_pages' => 0, - 'write_wiki' => 0, - 'post_wall' => 0, - 'post_comments' => 0, - 'post_mail' => 0, - 'post_like' => 0, - 'tag_deliver' => 0, - 'chat' => 0, - 'republish' => 0, - 'delegate' => 0 - ] - ], - 'provide an unknown param' => [ - ['view_stream', 'unknown_perm'], - [ - 'view_stream' => 1, - 'send_stream' => 0, - 'view_profile' => 0, - 'view_contacts' => 0, - 'view_storage' => 0, - 'write_storage' => 0, - 'view_pages' => 0, - 'view_wiki' => 0, - 'write_pages' => 0, - 'write_wiki' => 0, - 'post_wall' => 0, - 'post_comments' => 0, - 'post_mail' => 0, - 'post_like' => 0, - 'tag_deliver' => 0, - 'chat' => 0, - 'republish' => 0, - 'delegate' => 0 - ] - ] - ]; - } - /** - * @uses ::call_hooks - */ - public function testFilledPermsNull() { - // Create a stub for global function t() with expectation - $t = $this->getFunctionMock('Zotlabs\Access', 't'); - $t->expects($this->atLeastOnce()); - // Create a stub for global function bt() with expectations - $bt = $this->getFunctionMock('Zotlabs\Access', 'btlogger'); - $bt->expects($this->once())->with($this->equalTo('FilledPerms: null')); + $result = [ + 'view_stream' => 0, + 'send_stream' => 0, + 'view_profile' => 0, + 'view_contacts' => 0, + 'view_storage' => 0, + 'write_storage' => 0, + 'view_pages' => 0, + 'view_wiki' => 0, + 'write_pages' => 0, + 'write_wiki' => 0, + 'post_wall' => 0, + 'post_comments' => 0, + 'post_mail' => 0, + 'post_like' => 0, + 'tag_deliver' => 0, + 'chat' => 0, + 'republish' => 0, + 'delegate' => 0 + ]; - $result = [ - 'view_stream' => 0, - 'send_stream' => 0, - 'view_profile' => 0, - 'view_contacts' => 0, - 'view_storage' => 0, - 'write_storage' => 0, - 'view_pages' => 0, - 'view_wiki' => 0, - 'write_pages' => 0, - 'write_wiki' => 0, - 'post_wall' => 0, - 'post_comments' => 0, - 'post_mail' => 0, - 'post_like' => 0, - 'tag_deliver' => 0, - 'chat' => 0, - 'republish' => 0, - 'delegate' => 0 - ]; + $this->assertEquals($result, Permissions::FilledPerms(null)); + } - $this->assertEquals($result, Permissions::FilledPerms(null)); - } + /** + * @dataProvider OPermsProvider + * + * @param array $permarr The params to pass to the OPerms method + * @param array $expected The expected result + */ + public function testOPerms($permarr, $expected) + { + $this->assertEquals($expected, Permissions::OPerms($permarr)); + } + /** + * @return array An associative array with test values for OPerms() + * * \e array Array with perms to test + * * \e array Expected result array + */ + public function OPermsProvider() + { + return [ + 'empty' => [ + [], + [] + ], + 'valid' => [ + ['perm1' => 1, 'perm2' => 0], + [['name' => 'perm1', 'value' => 1], ['name' => 'perm2', 'value' => 0]] + ], + 'null array' => [ + null, + [] + ] + ]; + } - /** - * @dataProvider OPermsProvider - * - * @param array $permarr The params to pass to the OPerms method - * @param array $expected The expected result - */ - public function testOPerms($permarr, $expected) { - $this->assertEquals($expected, Permissions::OPerms($permarr)); - } - /** - * @return array An associative array with test values for OPerms() - * * \e array Array with perms to test - * * \e array Expected result array - */ - public function OPermsProvider() { - return [ - 'empty' => [ - [], - [] - ], - 'valid' => [ - ['perm1' => 1, 'perm2' => 0], - [['name' => 'perm1', 'value' => 1], ['name' => 'perm2', 'value' => 0]] - ], - 'null array' => [ - null, - [] - ] - ]; - } - - /** - * @dataProvider permsCompareProvider - * - * @param array $p1 The first permission - * @param array $p2 The second permission - * @param bool $expectedresult The expected result of the tested method - */ - public function testPermsCompare($p1, $p2, $expectedresult) { - $this->assertEquals($expectedresult, Permissions::PermsCompare($p1, $p2)); - } - /** - * @return array An associative array with test values for PermsCompare() - * * \e array 1st array with perms - * * \e array 2nd array with perms - * * \e boolean expected result for the perms comparison - */ - public function permsCompareProvider() { - return [ - 'equal' => [ - ['perm1' => 1, 'perm2' => 0], - ['perm1' => 1, 'perm2' => 0], - true - ], - 'different values' => [ - ['perm1' => 1, 'perm2' => 0], - ['perm1' => 0, 'perm2' => 1], - false - ], - 'different order' => [ - ['perm1' => 1, 'perm2' => 0], - ['perm2' => 0, 'perm1' => 1], - true - ], - 'partial first in second' => [ - ['perm1' => 1], - ['perm1' => 1, 'perm2' => 0], - true - ], - 'partial second in first' => [ - ['perm1' => 1, 'perm2' => 0], - ['perm1' => 1], - false - ] - ]; - } + /** + * @dataProvider permsCompareProvider + * + * @param array $p1 The first permission + * @param array $p2 The second permission + * @param bool $expectedresult The expected result of the tested method + */ + public function testPermsCompare($p1, $p2, $expectedresult) + { + $this->assertEquals($expectedresult, Permissions::PermsCompare($p1, $p2)); + } + /** + * @return array An associative array with test values for PermsCompare() + * * \e array 1st array with perms + * * \e array 2nd array with perms + * * \e boolean expected result for the perms comparison + */ + public function permsCompareProvider() + { + return [ + 'equal' => [ + ['perm1' => 1, 'perm2' => 0], + ['perm1' => 1, 'perm2' => 0], + true + ], + 'different values' => [ + ['perm1' => 1, 'perm2' => 0], + ['perm1' => 0, 'perm2' => 1], + false + ], + 'different order' => [ + ['perm1' => 1, 'perm2' => 0], + ['perm2' => 0, 'perm1' => 1], + true + ], + 'partial first in second' => [ + ['perm1' => 1], + ['perm1' => 1, 'perm2' => 0], + true + ], + 'partial second in first' => [ + ['perm1' => 1, 'perm2' => 0], + ['perm1' => 1], + false + ] + ]; + } } diff --git a/tests/unit/AntiXSSTest.php b/tests/unit/AntiXSSTest.php index ebe0678a3..503d9963a 100644 --- a/tests/unit/AntiXSSTest.php +++ b/tests/unit/AntiXSSTest.php @@ -1,4 +1,5 @@ '; + /** + * test, that tags are escaped + */ + public function testEscapeTags() + { + $invalidstring = ''; - $validstring=notags($invalidstring); - $escapedString=escape_tags($invalidstring); + $validstring = notags($invalidstring); + $escapedString = escape_tags($invalidstring); - $this->assertEquals('[submit type="button" onclick="alert(\'failed!\');" /]', $validstring); - $this->assertEquals("<submit type="button" onclick="alert('failed!');" />", $escapedString); - } + $this->assertEquals('[submit type="button" onclick="alert(\'failed!\');" /]', $validstring); + $this->assertEquals("<submit type="button" onclick="alert('failed!');" />", $escapedString); + } - /** - *xmlify and unxmlify - */ - public function testXmlify() { - $text="I want to break\n this!11!"; - $xml=xmlify($text); - $retext=unxmlify($text); + /** + *xmlify and unxmlify + */ + public function testXmlify() + { + $text = "I want to break\n this!11!"; + $xml = xmlify($text); + $retext = unxmlify($text); - $this->assertEquals($text, $retext); - } + $this->assertEquals($text, $retext); + } - /** - * xmlify and put in a document - */ - public function testXmlifyDocument() { - $tag="I want to break"; - $xml=xmlify($tag); - $text=''.$xml.''; + /** + * xmlify and put in a document + */ + public function testXmlifyDocument() + { + $tag = "I want to break"; + $xml = xmlify($tag); + $text = '' . $xml . ''; - $xml_parser=xml_parser_create(); - //should be possible to parse it - $values=[]; $index=[]; - $this->assertEquals(1, xml_parse_into_struct($xml_parser, $text, $values, $index)); + $xml_parser = xml_parser_create(); + //should be possible to parse it + $values = []; + $index = []; + $this->assertEquals(1, xml_parse_into_struct($xml_parser, $text, $values, $index)); - $this->assertEquals(array('TEXT'=>array(0)), - $index); - $this->assertEquals(array(array('tag'=>'TEXT', 'type'=>'complete', 'level'=>1, 'value'=>$tag)), - $values); + $this->assertEquals( + array('TEXT' => array(0)), + $index + ); + $this->assertEquals( + array(array('tag' => 'TEXT', 'type' => 'complete', 'level' => 1, 'value' => $tag)), + $values + ); - xml_parser_free($xml_parser); - } + xml_parser_free($xml_parser); + } - /** - * test hex2bin and reverse - */ - public function testHex2Bin() { - $this->assertEquals(-3, hex2bin(bin2hex(-3))); - $this->assertEquals(0, hex2bin(bin2hex(0))); - $this->assertEquals(12, hex2bin(bin2hex(12))); - $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX))); - } + /** + * test hex2bin and reverse + */ + public function testHex2Bin() + { + $this->assertEquals(-3, hex2bin(bin2hex(-3))); + $this->assertEquals(0, hex2bin(bin2hex(0))); + $this->assertEquals(12, hex2bin(bin2hex(12))); + $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX))); + } - //function qp, quick and dirty?? - //get_mentions - //get_contact_block, bis Zeile 538 + //function qp, quick and dirty?? + //get_mentions + //get_contact_block, bis Zeile 538 } -?> diff --git a/tests/unit/AutonameTest.php b/tests/unit/AutonameTest.php index 566fe6149..6f0a697c7 100644 --- a/tests/unit/AutonameTest.php +++ b/tests/unit/AutonameTest.php @@ -1,4 +1,5 @@ assertNotEquals($autoname1, $autoname2); - } + $this->assertNotEquals($autoname1, $autoname2); + } - /** - *autonames should be random, odd length - */ - public function testAutonameOdd() { - $autoname1=autoname(9); - $autoname2=autoname(9); + /** + *autonames should be random, odd length + */ + public function testAutonameOdd() + { + $autoname1 = autoname(9); + $autoname2 = autoname(9); - $this->assertNotEquals($autoname1, $autoname2); - } + $this->assertNotEquals($autoname1, $autoname2); + } - /** - * try to fail autonames - */ - public function testAutonameNoLength() { - $autoname1=autoname(0); - $this->assertEquals(0, strlen($autoname1)); - } + /** + * try to fail autonames + */ + public function testAutonameNoLength() + { + $autoname1 = autoname(0); + $this->assertEquals(0, strlen($autoname1)); + } - /** - * try to fail it with invalid input - * - * TODO: What's corect behaviour here? An exception? - */ - public function testAutonameNegativeLength() { - $autoname1=autoname(-23); - $this->assertEquals(0, strlen($autoname1)); - } + /** + * try to fail it with invalid input + * + * TODO: What's corect behaviour here? An exception? + */ + public function testAutonameNegativeLength() + { + $autoname1 = autoname(-23); + $this->assertEquals(0, strlen($autoname1)); + } - // public function testAutonameMaxLength() { - // $autoname2=autoname(PHP_INT_MAX); - // $this->assertEquals(PHP_INT_MAX, strlen($autoname2)); - // } + // public function testAutonameMaxLength() { + // $autoname2=autoname(PHP_INT_MAX); + // $this->assertEquals(PHP_INT_MAX, strlen($autoname2)); + // } - /** - * test with a length, that may be too short - * length is maximum - autoname can return something shorter. - */ - public function testAutonameLength1() { - $autoname1=autoname(1); - $test = ((strlen($autoname1) < 2) ? 1 : 0); - $this->assertEquals(1, $test); + /** + * test with a length, that may be too short + * length is maximum - autoname can return something shorter. + */ + public function testAutonameLength1() + { + $autoname1 = autoname(1); + $test = ((strlen($autoname1) < 2) ? 1 : 0); + $this->assertEquals(1, $test); - $autoname2=autoname(1); - $test = ((strlen($autoname2) < 2) ? 1 : 0); - $this->assertEquals(1, $test); + $autoname2 = autoname(1); + $test = ((strlen($autoname2) < 2) ? 1 : 0); + $this->assertEquals(1, $test); - // The following test is problematic, with only 26 possibilities - // generating the same thing twice happens often aka - // birthday paradox -// $this->assertFalse($autoname1==$autoname2); - } + // The following test is problematic, with only 26 possibilities + // generating the same thing twice happens often aka + // birthday paradox +// $this->assertFalse($autoname1==$autoname2); + } } diff --git a/tests/unit/ContainsAttributeTest.php b/tests/unit/ContainsAttributeTest.php index 0930d9837..96bb9dc88 100644 --- a/tests/unit/ContainsAttributeTest.php +++ b/tests/unit/ContainsAttributeTest.php @@ -1,4 +1,5 @@ assertTrue(attribute_contains($testAttr, "class3")); - $this->assertFalse(attribute_contains($testAttr, "class2")); - } +class ContainsAttributeTest extends TestCase +{ + /** + * test attribute contains + */ + public function testAttributeContains1() + { + $testAttr = "class1 notclass2 class3"; + $this->assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } - /** - * test attribute contains - */ - public function testAttributeContains2() { - $testAttr="class1 not-class2 class3"; - $this->assertTrue(attribute_contains($testAttr, "class3")); - $this->assertFalse(attribute_contains($testAttr, "class2")); - } + /** + * test attribute contains + */ + public function testAttributeContains2() + { + $testAttr = "class1 not-class2 class3"; + $this->assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } - /** - * test with empty input - */ - public function testAttributeContainsEmpty() { - $testAttr=""; - $this->assertFalse(attribute_contains($testAttr, "class2")); - } + /** + * test with empty input + */ + public function testAttributeContainsEmpty() + { + $testAttr = ""; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } - /** - * test input with special chars - */ - public function testAttributeContainsSpecialChars() { - $testAttr="--... %\$ä() /(=?}"; - $this->assertFalse(attribute_contains($testAttr, "class2")); - } -} \ No newline at end of file + /** + * test input with special chars + */ + public function testAttributeContainsSpecialChars() + { + $testAttr = "--... %\$ä() /(=?}"; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } +} diff --git a/tests/unit/DatabaseTestCase.php b/tests/unit/DatabaseTestCase.php index 3ed8862ea..60f3cd405 100644 --- a/tests/unit/DatabaseTestCase.php +++ b/tests/unit/DatabaseTestCase.php @@ -1,4 +1,5 @@ conn === null) { - if (self::$pdo === null) { - $dsn = getenv('hz_db_scheme') . ':host=' . getenv('hz_db_server') - . ';port=' . getenv('hz_db_port') . ';dbname=' . getenv('hz_db_database'); + final public function getConnection() + { + if ($this->conn === null) { + if (self::$pdo === null) { + $dsn = getenv('hz_db_scheme') . ':host=' . getenv('hz_db_server') + . ';port=' . getenv('hz_db_port') . ';dbname=' . getenv('hz_db_database'); - self::$pdo = new PDO($dsn, getenv('hz_db_user'), getenv('hz_db_pass')); - } - $this->conn = $this->createDefaultDBConnection(self::$pdo, getenv('hz_db_database')); - } + self::$pdo = new PDO($dsn, getenv('hz_db_user'), getenv('hz_db_pass')); + } + $this->conn = $this->createDefaultDBConnection(self::$pdo, getenv('hz_db_database')); + } - return $this->conn; - } + return $this->conn; + } } diff --git a/tests/unit/Lib/MarkdownTest.php b/tests/unit/Lib/MarkdownTest.php index da1d82877..c350397a2 100644 --- a/tests/unit/Lib/MarkdownTest.php +++ b/tests/unit/Lib/MarkdownTest.php @@ -1,4 +1,5 @@ assertEquals($markdown, Markdown::from_html($html)); - } + /** + * @covers ::html2markdown + * @dataProvider html2markdownProvider + */ + public function testHtml2markdown($html, $markdown) + { + $this->assertEquals($markdown, Markdown::from_html($html)); + } - public function html2markdownProvider() { - return [ - 'empty text' => [ - '', - '' - ], - 'space and nbsp only' => [ - '  ', - '' - ], + public function html2markdownProvider() + { + return [ + 'empty text' => [ + '', + '' + ], + 'space and nbsp only' => [ + '  ', + '' + ], - 'strong, b, em, i, bib' => [ - 'strong bold em italic boitalicld', - '**strong** **bold** *em* *italic* **bo*italic*ld**' - ], + 'strong, b, em, i, bib' => [ + 'strong bold em italic boitalicld', + '**strong** **bold** *em* *italic* **bo*italic*ld**' + ], - 'empty tags' => [ - 'text1 text2 ', - 'text1 text2' - ], - 'HTML entities, lt does not work' => [ - '& gt > lt <', - '& gt > lt' - ], - 'escaped HTML entities' => [ - '& lt < gt >', - '& lt < gt >' - ], - 'linebreak' => [ - "line1
                    line2\nline3", - "line1 \nline2 line3" - ], - 'headlines' => [ - '

                    header1

                    Header 3

                    ', - "header1\n=======\n\n### Header 3" - ], - 'unordered list' => [ - '
                    • Item 1
                    • Item 2
                    • Item 3
                    ', - "- Item 1\n- Item 2\n- Item **3**" - ], - 'ordered list' => [ - '
                    1. Item 1
                    2. Item 2
                    3. Item 3
                    ', - "1. Item 1\n2. Item 2\n3. Item **3**" - ], - 'nested lists' => [ - '
                    • Item 1
                      1. Item 1a
                      2. Item 1b
                    • Item 2
                    ', - "- Item 1\n 1. Item 1a\n 2. Item **1b**\n- Item 2" - ], - 'img' => [ - 'alt text', - '![alt text](/path/to/img.png "title text")' - ], - 'link' => [ - 'link', - '[link](http://hubzilla.org "Hubzilla")' - ], - 'img link' => [ - 'alt img text', - '[![alt img text](/img/hubzilla.png "img title")](http://hubzilla.org "Hubzilla")' - ], - 'script' => [ - "", - "" - ], - 'blockquote, issue #793' => [ - '
                    something
                    blah', - "> something\n\nblah" - ], - 'code' => [ - '<p>HTML text</p>', - '`

                    HTML text

                    `' - ], - 'pre' => [ - '
                      one line with spaces  
                    ', - "```\n one line with spaces \n```" - ], - 'div p' => [ - '
                    div

                    p

                    ', - "
                    div
                    p\n\n
                    " - ] - ]; - } + 'empty tags' => [ + 'text1 text2 ', + 'text1 text2' + ], + 'HTML entities, lt does not work' => [ + '& gt > lt <', + '& gt > lt' + ], + 'escaped HTML entities' => [ + '& lt < gt >', + '& lt < gt >' + ], + 'linebreak' => [ + "line1
                    line2\nline3", + "line1 \nline2 line3" + ], + 'headlines' => [ + '

                    header1

                    Header 3

                    ', + "header1\n=======\n\n### Header 3" + ], + 'unordered list' => [ + '
                    • Item 1
                    • Item 2
                    • Item 3
                    ', + "- Item 1\n- Item 2\n- Item **3**" + ], + 'ordered list' => [ + '
                    1. Item 1
                    2. Item 2
                    3. Item 3
                    ', + "1. Item 1\n2. Item 2\n3. Item **3**" + ], + 'nested lists' => [ + '
                    • Item 1
                      1. Item 1a
                      2. Item 1b
                    • Item 2
                    ', + "- Item 1\n 1. Item 1a\n 2. Item **1b**\n- Item 2" + ], + 'img' => [ + 'alt text', + '![alt text](/path/to/img.png "title text")' + ], + 'link' => [ + 'link', + '[link](http://hubzilla.org "Hubzilla")' + ], + 'img link' => [ + 'alt img text', + '[![alt img text](/img/hubzilla.png "img title")](http://hubzilla.org "Hubzilla")' + ], + 'script' => [ + "", + "" + ], + 'blockquote, issue #793' => [ + '
                    something
                    blah', + "> something\n\nblah" + ], + 'code' => [ + '<p>HTML text</p>', + '`

                    HTML text

                    `' + ], + 'pre' => [ + '
                      one line with spaces  
                    ', + "```\n one line with spaces \n```" + ], + 'div p' => [ + '
                    div

                    p

                    ', + "
                    div
                    p\n\n
                    " + ] + ]; + } - /*public function testHtml2markdownException() { - //$this->expectException(\InvalidArgumentException::class); - // need to stub logger() for this to work - $this->assertEquals('', Markdown::from_html('<expectException(\InvalidArgumentException::class); + // need to stub logger() for this to work + $this->assertEquals('', Markdown::from_html('<getFunctionMock(__NAMESPACE__, "bbcode"); - $bbc->expects($this->once())->willReturn('testbold
                    i
                    • li1
                    • li2

                    '); + // php-mock can not mock global functions which is called by a global function. + // If the calling function is in a namespace it does work. + $bbc = $this->getFunctionMock(__NAMESPACE__, "bbcode"); + $bbc->expects($this->once())->willReturn('testbold
                    i
                    • li1
                    • li2

                    '); - $this->assertEquals($bb1, Markdown::from_bbcode($html1)); - } + $this->assertEquals($bb1, Markdown::from_bbcode($html1)); + } */ } diff --git a/tests/unit/Lib/PermissionDescriptionTest.php b/tests/unit/Lib/PermissionDescriptionTest.php index 96c381d0c..ce7853e41 100644 --- a/tests/unit/Lib/PermissionDescriptionTest.php +++ b/tests/unit/Lib/PermissionDescriptionTest.php @@ -1,4 +1,5 @@ assertEquals($permDesc, $permDesc2); + $this->assertNotEquals($permDesc, $permDesc3); + } - $this->assertEquals($permDesc, $permDesc2); - $this->assertNotEquals($permDesc, $permDesc3); - } + public function testFromStandalonePermission() + { + // Create a stub for global function t() + $t = $this->getFunctionMock('Zotlabs\Lib', 't'); + $t->expects($this->atLeastOnce())->willReturnCallback( + function ($string) { + return $string; + } + ); + // Create a mock for global function logger() + $this->getFunctionMock('Zotlabs\Lib', 'logger'); - public function testFromStandalonePermission() { - // Create a stub for global function t() - $t = $this->getFunctionMock('Zotlabs\Lib', 't'); - $t->expects($this->atLeastOnce())->willReturnCallback( - function ($string) { - return $string; - } - ); - // Create a mock for global function logger() - $this->getFunctionMock('Zotlabs\Lib', 'logger'); + $permDescUnknown = PermissionDescription::fromStandalonePermission(-1); + $permDescSelf = PermissionDescription::fromStandalonePermission(0); - $permDescUnknown = PermissionDescription::fromStandalonePermission(-1); - $permDescSelf = PermissionDescription::fromStandalonePermission(0); + $this->assertNull($permDescUnknown); + $this->assertNotNull($permDescSelf); + } - $this->assertNull($permDescUnknown); - $this->assertNotNull($permDescSelf); - } + public function testFromGlobalPermission() + { + //$permDesc = PermissionDescription::fromGlobalPermission('view_profile'); - public function testFromGlobalPermission() { - //$permDesc = PermissionDescription::fromGlobalPermission('view_profile'); + $this->markTestIncomplete( + 'The method fromGlobalPermission() is not yet testable ...' + ); + } - $this->markTestIncomplete( - 'The method fromGlobalPermission() is not yet testable ...' - ); - } + public function testGetPermissionDescription() + { + // Create a stub for global function t() + $t = $this->getFunctionMock('Zotlabs\Lib', 't'); + $t->expects($this->atLeastOnce())->willReturnCallback( + function ($string) { + return $string; + } + ); + // Create a mock for global function logger() + $this->getFunctionMock('Zotlabs\Lib', 'logger'); - public function testGetPermissionDescription() { - // Create a stub for global function t() - $t = $this->getFunctionMock('Zotlabs\Lib', 't'); - $t->expects($this->atLeastOnce())->willReturnCallback( - function ($string) { - return $string; - } - ); - // Create a mock for global function logger() - $this->getFunctionMock('Zotlabs\Lib', 'logger'); + // Create a stub for the PermissionDescription class + $stub = $this->createMock(PermissionDescription::class); + $stub->method('get_permission_description') + ->will($this->returnArgument(0)); - // Create a stub for the PermissionDescription class - $stub = $this->createMock(PermissionDescription::class); - $stub->method('get_permission_description') - ->will($this->returnArgument(0)); + $permDescSelf = PermissionDescription::fromStandalonePermission(0); + $this->assertInstanceOf(PermissionDescription::class, $permDescSelf); + $this->assertEquals($permDescSelf->get_permission_description(), 'Only me'); - $permDescSelf = PermissionDescription::fromStandalonePermission(0); - $this->assertInstanceOf(PermissionDescription::class, $permDescSelf); - $this->assertEquals($permDescSelf->get_permission_description(), 'Only me'); - - $permDescPublic = PermissionDescription::fromStandalonePermission(PERMS_PUBLIC); - $this->assertEquals($permDescPublic->get_permission_description(), 'Public'); - } + $permDescPublic = PermissionDescription::fromStandalonePermission(PERMS_PUBLIC); + $this->assertEquals($permDescPublic->get_permission_description(), 'Public'); + } } diff --git a/tests/unit/UnitTestCase.php b/tests/unit/UnitTestCase.php index 7d706d5be..16d49c618 100644 --- a/tests/unit/UnitTestCase.php +++ b/tests/unit/UnitTestCase.php @@ -1,4 +1,5 @@ assertEquals("audio/ogg", z_mime_content_type($multidots)); - $this->assertNotEquals("application/octet-stream", z_mime_content_type($multidots)); - } +class UploadTest extends TestCase +{ + public function testFileNameMutipleDots() + { + $multidots = "foo.bar.baz.0.1.3.ogg"; + $this->assertEquals("audio/ogg", z_mime_content_type($multidots)); + $this->assertNotEquals("application/octet-stream", z_mime_content_type($multidots)); + } - public function testFileNameOneDot() { - $multidots = "foo.ogg"; - $this->assertEquals("audio/ogg", z_mime_content_type($multidots)); - $this->assertNotEquals("application/octet-stream", z_mime_content_type($multidots)); - } -} \ No newline at end of file + public function testFileNameOneDot() + { + $multidots = "foo.ogg"; + $this->assertEquals("audio/ogg", z_mime_content_type($multidots)); + $this->assertNotEquals("application/octet-stream", z_mime_content_type($multidots)); + } +} diff --git a/tests/unit/expand_acl_test.php b/tests/unit/expand_acl_test.php index 700fea46e..790ce58e5 100644 --- a/tests/unit/expand_acl_test.php +++ b/tests/unit/expand_acl_test.php @@ -1,4 +1,5 @@ <2><3>'; - $this->assertEquals(array(1, 2, 3), expand_acl($text)); - } - - /** - * test with a big number - */ - public function testExpandAclBigNumber() { - $text='<1><'.PHP_INT_MAX.'><15>'; - $this->assertEquals(array(1, PHP_INT_MAX, 15), expand_acl($text)); - } - - /** - * test with a string in it. - * - * TODO: is this valid input? Otherwise: should there be an exception? - */ - public function testExpandAclString() { - $text="<1><279012>"; - $this->assertEquals(array(1, 279012), expand_acl($text)); - } - - /** - * test with a ' ' in it. - * - * TODO: is this valid input? Otherwise: should there be an exception? - */ - public function testExpandAclSpace() { - $text="<1><279 012><32>"; - $this->assertEquals(array(1, "279", "32"), expand_acl($text)); - } - - /** - * test empty input - */ - public function testExpandAclEmpty() { - $text=""; - $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, no < at all - * - * TODO: should there be an exception? - */ - public function testExpandAclNoBrackets() { - $text="According to documentation, that's invalid. "; //should be invalid - $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, just open < - * - * TODO: should there be an exception? - */ - public function testExpandAclJustOneBracket1() { - $text="assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, just close > - * - * TODO: should there be an exception? - */ - public function testExpandAclJustOneBracket2() { - $text="Another invalid> string"; //should be invalid - $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, just close > - * - * TODO: should there be an exception? - */ - public function testExpandAclCloseOnly() { - $text="Another> invalid> string>"; //should be invalid - $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, just open < - * - * TODO: should there be an exception? - */ - public function testExpandAclOpenOnly() { - $text="assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, open and close do not match - * - * TODO: should there be an exception? - */ - public function testExpandAclNoMatching1() { - $text=" invalid "; //should be invalid - $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, open and close do not match - * - * TODO: should there be an exception? - */ - public function testExpandAclNoMatching2() { - $text="<1>2><3>"; +/** + * TestCase for the expand_acl function + * + * @author Alexander Kampmann + * @package test.util + */ +class ExpandAclTest extends PHPUnit_Framework_TestCase +{ + + /** + * test expand_acl, perfect input + */ + public function testExpandAclNormal() + { + $text = '<1><2><3>'; + $this->assertEquals(array(1, 2, 3), expand_acl($text)); + } + + /** + * test with a big number + */ + public function testExpandAclBigNumber() + { + $text = '<1><' . PHP_INT_MAX . '><15>'; + $this->assertEquals(array(1, PHP_INT_MAX, 15), expand_acl($text)); + } + + /** + * test with a string in it. + * + * TODO: is this valid input? Otherwise: should there be an exception? + */ + public function testExpandAclString() + { + $text = "<1><279012>"; + $this->assertEquals(array(1, 279012), expand_acl($text)); + } + + /** + * test with a ' ' in it. + * + * TODO: is this valid input? Otherwise: should there be an exception? + */ + public function testExpandAclSpace() + { + $text = "<1><279 012><32>"; + $this->assertEquals(array(1, "279", "32"), expand_acl($text)); + } + + /** + * test empty input + */ + public function testExpandAclEmpty() + { + $text = ""; + $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, no < at all + * + * TODO: should there be an exception? + */ + public function testExpandAclNoBrackets() + { + $text = "According to documentation, that's invalid. "; //should be invalid + $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, just open < + * + * TODO: should there be an exception? + */ + public function testExpandAclJustOneBracket1() + { + $text = "assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, just close > + * + * TODO: should there be an exception? + */ + public function testExpandAclJustOneBracket2() + { + $text = "Another invalid> string"; //should be invalid + $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, just close > + * + * TODO: should there be an exception? + */ + public function testExpandAclCloseOnly() + { + $text = "Another> invalid> string>"; //should be invalid + $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, just open < + * + * TODO: should there be an exception? + */ + public function testExpandAclOpenOnly() + { + $text = "assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, open and close do not match + * + * TODO: should there be an exception? + */ + public function testExpandAclNoMatching1() + { + $text = " invalid "; //should be invalid + $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, open and close do not match + * + * TODO: should there be an exception? + */ + public function testExpandAclNoMatching2() + { + $text = "<1>2><3>"; // The angles are delimiters which aren't important // the important thing is the numeric content, this returns array(1,2,3) currently // we may wish to eliminate 2 from the results, though it isn't harmful // It would be a better test to figure out if there is any ACL input which can // produce this $text and fix that instead. -// $this->assertEquals([], expand_acl($text)); - } - - /** - * test invalid input, empty <> - * - * TODO: should there be an exception? Or array(1, 3) - * (This should be array(1,3) - mike) - */ - public function testExpandAclEmptyMatch() { - $text="<1><><3>"; - $this->assertEquals(array(1,3), expand_acl($text)); - } -} \ No newline at end of file +// $this->assertEquals([], expand_acl($text)); + } + + /** + * test invalid input, empty <> + * + * TODO: should there be an exception? Or array(1, 3) + * (This should be array(1,3) - mike) + */ + public function testExpandAclEmptyMatch() + { + $text = "<1><><3>"; + $this->assertEquals(array(1,3), expand_acl($text)); + } +} diff --git a/tests/unit/get_tags_test.php b/tests/unit/get_tags_test.php index e7bfe0ec8..2c20eeb1a 100644 --- a/tests/unit/get_tags_test.php +++ b/tests/unit/get_tags_test.php @@ -1,7 +1,8 @@ 15, - 'attag'=>'', 'network'=>'dfrn', - 'name'=>'Mike Lastname', 'alias'=>'Mike', - 'nick'=>'Mike', 'url'=>"http://justatest.de")); - - $args=func_get_args(); +function q($sql) +{ + $result = array(array('id' => 15, + 'attag' => '', 'network' => 'dfrn', + 'name' => 'Mike Lastname', 'alias' => 'Mike', + 'nick' => 'Mike', 'url' => "http://justatest.de")); - //last parameter is always (in this test) uid, so, it should be 11 - if($args[count($args)-1]!=11) { - return; - } - - - if(3==count($args)) { - //first call in handle_body, id only - if($result[0]['id']==$args[1]) { - return $result; - } - //second call in handle_body, name - if($result[0]['name']===$args[1]) { - return $result; - } - } - //third call in handle_body, nick or attag - if($result[0]['nick']===$args[2] || $result[0]['attag']===$args[1]) { - return $result; - } + $args = func_get_args(); + + //last parameter is always (in this test) uid, so, it should be 11 + if ($args[count($args) - 1] != 11) { + return; + } + + + if (3 == count($args)) { + //first call in handle_body, id only + if ($result[0]['id'] == $args[1]) { + return $result; + } + //second call in handle_body, name + if ($result[0]['name'] === $args[1]) { + return $result; + } + } + //third call in handle_body, nick or attag + if ($result[0]['nick'] === $args[2] || $result[0]['attag'] === $args[1]) { + return $result; + } } /** - * replacement for dbesc. + * replacement for dbesc. * I don't want to test dbesc here, so - * I just return the input. It won't be a problem, because - * the test does not use a real database. - * + * I just return the input. It won't be a problem, because + * the test does not use a real database. + * * DON'T USE HAT FUNCTION OUTSIDE A TEST! - * + * * @param string $str * @return input */ -function dbesc($str) { - return $str; +function dbesc($str) +{ + return $str; } /** - * TestCase for tag handling. - * + * TestCase for tag handling. + * * @author alexander * @package test.util */ -class GetTagsTest extends PHPUnit_Framework_TestCase { - /** the mock to use as app */ - private $a; +class GetTagsTest extends PHPUnit_Framework_TestCase +{ + /** the mock to use as app */ + private $a; - /** - * initialize the test. That's a phpUnit function, - * don't change its name. - */ - public function setUp() { - $this->a=new MockApp(); - } + /** + * initialize the test. That's a phpUnit function, + * don't change its name. + */ + public function setUp() + { + $this->a = new MockApp(); + } - /** - * test with one Person tag - */ - public function testGetTagsShortPerson() { - $text="hi @Mike"; + /** + * test with one Person tag + */ + public function testGetTagsShortPerson() + { + $text = "hi @Mike"; - $tags=get_tags($text); + $tags = get_tags($text); - $str_tags=''; - foreach($tags as $tag) { - handle_tag($text, $str_tags, 11, $tag); - } + $str_tags = ''; + foreach ($tags as $tag) { + handle_tag($text, $str_tags, 11, $tag); + } - //correct tags found? - $this->assertEquals(1, count($tags)); - $this->assertTrue(in_array("@Mike", $tags)); - - //correct output from handle_tag? - $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); - $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url]", $text); - } - - /** - * test with one Person tag. - * There's a minor spelling mistake... - */ - public function testGetTagsShortPersonSpelling() { - $text="hi @Mike.because"; - - $tags=get_tags($text); - - //correct tags found? - $this->assertEquals(1, count($tags)); - $this->assertTrue(in_array("@Mike.because", $tags)); - - $str_tags=''; - handle_tag($text, $str_tags, 11, $tags[0]); - - // (mike) - This is a tricky case. - // we support mentions as in @mike@example.com - which contains a period. - // This shouldn't match anything unless you have a contact named "Mike.because". - // We may need another test for "@Mike. because" - which should return the contact - // as we ignore trailing periods in tags. - -// $this->assertEquals("cid:15", $inform); -// $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); -// $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url].because", $text); + //correct tags found? + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); - $this->assertEquals("", $str_tags); + //correct output from handle_tag? + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); + $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url]", $text); + } - } - - /** - * test with two Person tags. - * There's a minor spelling mistake... - */ + /** + * test with one Person tag. + * There's a minor spelling mistake... + */ + public function testGetTagsShortPersonSpelling() + { + $text = "hi @Mike.because"; - public function testGetTagsPerson2Spelling() { - $text="hi @Mike@campino@friendica.eu"; - - $tags=get_tags($text); + $tags = get_tags($text); -// This construct is not supported. Results are indeterminate -// $this->assertEquals(2, count($tags)); -// $this->assertTrue(in_array("@Mike", $tags)); -// $this->assertTrue(in_array("@campino@friendica.eu", $tags)); - } + //correct tags found? + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("@Mike.because", $tags)); - /** - * Test with one hash tag. - */ - public function testGetTagsShortTag() { - $text="This is a #test_case"; + $str_tags = ''; + handle_tag($text, $str_tags, 11, $tags[0]); - $tags=get_tags($text); + // (mike) - This is a tricky case. + // we support mentions as in @mike@example.com - which contains a period. + // This shouldn't match anything unless you have a contact named "Mike.because". + // We may need another test for "@Mike. because" - which should return the contact + // as we ignore trailing periods in tags. - $this->assertEquals(1, count($tags)); - $this->assertTrue(in_array("#test_case", $tags)); - } +// $this->assertEquals("cid:15", $inform); +// $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); +// $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url].because", $text); - /** - * test with a person and a hash tag - */ - public function testGetTagsShortTagAndPerson() { - $text="hi @Mike This is a #test_case"; + $this->assertEquals("", $str_tags); + } - $tags=get_tags($text); + /** + * test with two Person tags. + * There's a minor spelling mistake... + */ - $this->assertEquals(3, count($tags)); - $this->assertTrue(in_array("@Mike", $tags)); - $this->assertTrue(in_array("@Mike This", $tags)); - $this->assertTrue(in_array("#test_case", $tags)); + public function testGetTagsPerson2Spelling() + { + $text = "hi @Mike@campino@friendica.eu"; - $str_tags=''; - foreach($tags as $tag) { - handle_tag($text, $str_tags, 11, $tag); - } - - $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url],#[url=baseurl/search?tag=test%20case]test case[/url]", $str_tags); - $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url] This is a #[url=baseurl/search?tag=test%20case]test case[/url]", $text); - - } + $tags = get_tags($text); - /** - * test with a person, a hash tag and some special chars. - */ - public function testGetTagsShortTagAndPersonSpecialChars() { - $text="hi @Mike, This is a #test_case."; +// This construct is not supported. Results are indeterminate +// $this->assertEquals(2, count($tags)); +// $this->assertTrue(in_array("@Mike", $tags)); +// $this->assertTrue(in_array("@campino@friendica.eu", $tags)); + } - $tags=get_tags($text); + /** + * Test with one hash tag. + */ + public function testGetTagsShortTag() + { + $text = "This is a #test_case"; - $this->assertEquals(2, count($tags)); - $this->assertTrue(in_array("@Mike", $tags)); - $this->assertTrue(in_array("#test_case", $tags)); - } + $tags = get_tags($text); - /** - * Test with a person tag and text behind it. - */ - public function testGetTagsPersonOnly() { - $text="@Test I saw the Theme Dev group was created."; + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("#test_case", $tags)); + } - $tags=get_tags($text); + /** + * test with a person and a hash tag + */ + public function testGetTagsShortTagAndPerson() + { + $text = "hi @Mike This is a #test_case"; - $this->assertEquals(2, count($tags)); - $this->assertTrue(in_array("@Test I", $tags)); - $this->assertTrue(in_array("@Test", $tags)); - } + $tags = get_tags($text); - /** - * this test demonstrates strange behaviour by intval. - * It makes the next test fail. - */ - public function testIntval() { - $this->assertEquals(15, intval("15 it")); - } - - /** - * test a tag with an id in it - */ - public function testIdTag() { - $text="Test with @mike+15 id tag"; - - $tags=get_tags($text); - - $this->assertEquals(2, count($tags)); - $this->assertTrue(in_array("@mike+15", $tags)); - - //happens right now, but it shouldn't be necessary - $this->assertTrue(in_array("@mike+15 id", $tags)); - - $str_tags=''; - foreach($tags as $tag) { - handle_tag($text, $str_tags, 11, $tag); - } - - $this->assertEquals("Test with @[url=http://justatest.de]Mike Lastname[/url] id tag", $text); - $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); - } - - /** - * test with two persons and one special tag. - */ - public function testGetTags2Persons1TagSpecialChars() { - $text="hi @Mike, I'm just writing #test_cases, so" - ." so @somebody@friendica.com may change #things."; + $this->assertEquals(3, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("@Mike This", $tags)); + $this->assertTrue(in_array("#test_case", $tags)); - $tags=get_tags($text); + $str_tags = ''; + foreach ($tags as $tag) { + handle_tag($text, $str_tags, 11, $tag); + } - $this->assertEquals(5, count($tags)); - $this->assertTrue(in_array("@Mike", $tags)); - $this->assertTrue(in_array("#test_cases", $tags)); - $this->assertTrue(in_array("@somebody@friendica.com", $tags)); - $this->assertTrue(in_array("@somebody@friendica.com may", $tags)); - $this->assertTrue(in_array("#things", $tags)); - } + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url],#[url=baseurl/search?tag=test%20case]test case[/url]", $str_tags); + $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url] This is a #[url=baseurl/search?tag=test%20case]test case[/url]", $text); + } - /** - * test with a long text. - */ - public function testGetTags() { - $text="hi @Mike, I'm just writing #test_cases, " - ." so @somebody@friendica.com may change #things. Of course I " - ."look for a lot of #pitfalls, like #tags at the end of a sentence " - ."@comment. I hope noone forgets about @fullstops.because that might" - ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " - ."Now, add a @first_last tag. "; - - $tags=get_tags($text); + /** + * test with a person, a hash tag and some special chars. + */ + public function testGetTagsShortTagAndPersonSpecialChars() + { + $text = "hi @Mike, This is a #test_case."; - $this->assertTrue(in_array("@Mike", $tags)); - $this->assertTrue(in_array("#test_cases", $tags)); - $this->assertTrue(in_array("@somebody@friendica.com", $tags)); - $this->assertTrue(in_array("#things", $tags)); - $this->assertTrue(in_array("#pitfalls", $tags)); - $this->assertTrue(in_array("#tags", $tags)); - $this->assertTrue(in_array("@comment", $tags)); - $this->assertTrue(in_array("@fullstops.because", $tags)); - $this->assertTrue(in_array("#things", $tags)); - $this->assertTrue(in_array("@Mike", $tags)); - $this->assertTrue(in_array("#nice", $tags)); - $this->assertTrue(in_array("@first_last", $tags)); - - //right now, none of the is matched (unsupported) -// $this->assertFalse(in_array("@Mike@campino@friendica.eu", $tags)); -// $this->assertTrue(in_array("@campino@friendica.eu", $tags)); -// $this->assertTrue(in_array("@campino@friendica.eu is", $tags)); - } + $tags = get_tags($text); - /** - * test with an empty string - */ - public function testGetTagsEmpty() { - $tags=get_tags(""); - $this->assertEquals(0, count($tags)); - } -} \ No newline at end of file + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_case", $tags)); + } + + /** + * Test with a person tag and text behind it. + */ + public function testGetTagsPersonOnly() + { + $text = "@Test I saw the Theme Dev group was created."; + + $tags = get_tags($text); + + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@Test I", $tags)); + $this->assertTrue(in_array("@Test", $tags)); + } + + /** + * this test demonstrates strange behaviour by intval. + * It makes the next test fail. + */ + public function testIntval() + { + $this->assertEquals(15, intval("15 it")); + } + + /** + * test a tag with an id in it + */ + public function testIdTag() + { + $text = "Test with @mike+15 id tag"; + + $tags = get_tags($text); + + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@mike+15", $tags)); + + //happens right now, but it shouldn't be necessary + $this->assertTrue(in_array("@mike+15 id", $tags)); + + $str_tags = ''; + foreach ($tags as $tag) { + handle_tag($text, $str_tags, 11, $tag); + } + + $this->assertEquals("Test with @[url=http://justatest.de]Mike Lastname[/url] id tag", $text); + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); + } + + /** + * test with two persons and one special tag. + */ + public function testGetTags2Persons1TagSpecialChars() + { + $text = "hi @Mike, I'm just writing #test_cases, so" + . " so @somebody@friendica.com may change #things."; + + $tags = get_tags($text); + + $this->assertEquals(5, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_cases", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com may", $tags)); + $this->assertTrue(in_array("#things", $tags)); + } + + /** + * test with a long text. + */ + public function testGetTags() + { + $text = "hi @Mike, I'm just writing #test_cases, " + . " so @somebody@friendica.com may change #things. Of course I " + . "look for a lot of #pitfalls, like #tags at the end of a sentence " + . "@comment. I hope noone forgets about @fullstops.because that might" + . " break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " + . "Now, add a @first_last tag. "; + + $tags = get_tags($text); + + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_cases", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com", $tags)); + $this->assertTrue(in_array("#things", $tags)); + $this->assertTrue(in_array("#pitfalls", $tags)); + $this->assertTrue(in_array("#tags", $tags)); + $this->assertTrue(in_array("@comment", $tags)); + $this->assertTrue(in_array("@fullstops.because", $tags)); + $this->assertTrue(in_array("#things", $tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#nice", $tags)); + $this->assertTrue(in_array("@first_last", $tags)); + + //right now, none of the is matched (unsupported) +// $this->assertFalse(in_array("@Mike@campino@friendica.eu", $tags)); +// $this->assertTrue(in_array("@campino@friendica.eu", $tags)); +// $this->assertTrue(in_array("@campino@friendica.eu is", $tags)); + } + + /** + * test with an empty string + */ + public function testGetTagsEmpty() + { + $tags = get_tags(""); + $this->assertEquals(0, count($tags)); + } +} diff --git a/tests/unit/includes/LanguageTest.php b/tests/unit/includes/LanguageTest.php index ea3935ca5..b713b5d4c 100644 --- a/tests/unit/includes/LanguageTest.php +++ b/tests/unit/includes/LanguageTest.php @@ -1,4 +1,5 @@ getFunctionMock(__NAMESPACE__, 'get_config'); - //$gc->expects($this->once())->willReturn(10) - //$cg = $this->getFunctionMock('Zotlabs\Lib\Config', 'Get'); - //$cg->expects($this->once())->willReturn(10); - //$this->assertEquals($langCode, detect_language($text)); + // php-mock can not mock global functions which is called by a global function. + // If the calling function is in a namespace it would work. + //$gc = $this->getFunctionMock(__NAMESPACE__, 'get_config'); + //$gc->expects($this->once())->willReturn(10) + //$cg = $this->getFunctionMock('Zotlabs\Lib\Config', 'Get'); + //$cg->expects($this->once())->willReturn(10); + //$this->assertEquals($langCode, detect_language($text)); - // Can not unit test detect_language(), therefore test the used library - // only for now to find regressions on library updates. - $l = new Text_LanguageDetect(); - // return 2-letter ISO 639-1 (en) language code - $l->setNameMode(2); - $lng = $l->detectConfidence($text); + // Can not unit test detect_language(), therefore test the used library + // only for now to find regressions on library updates. + $l = new Text_LanguageDetect(); + // return 2-letter ISO 639-1 (en) language code + $l->setNameMode(2); + $lng = $l->detectConfidence($text); - $this->assertEquals($langCode, $lng['language']); - $this->assertEquals($confidence, round($lng['confidence'], 6)); - } + $this->assertEquals($langCode, $lng['language']); + $this->assertEquals($confidence, round($lng['confidence'], 6)); + } - public function languageExamplesProvider() { - return [ - 'empty text' => [ - '', - '', - null - ], - 'English' => [ - 'English is a West Germanic language that was first spoken in early medieval England and is now a global lingua franca.[4][5] Named after the Angles, one of the Germanic tribes that migrated to England, it ultimately derives its name from the Anglia (Angeln) peninsula in the Baltic Sea. It is closely related to the Frisian languages, but its vocabulary has been significantly influenced by other Germanic languages, particularly Norse (a North Germanic language), as well as by Latin and Romance languages, especially French.', - 'en', - 0.078422 - ], - 'German' => [ - 'Deutschland ist ein Bundesstaat in Mitteleuropa. Er besteht aus 16 Ländern und ist als freiheitlich-demokratischer und sozialer Rechtsstaat verfasst. Die Bundesrepublik Deutschland stellt die jüngste Ausprägung des deutschen Nationalstaates dar. Mit rund 82,8 Millionen Einwohnern (31. Dezember 2016) zählt Deutschland zu den dicht besiedelten Flächenstaaten.', - 'de', - 0.134339 - ], - 'Norwegian' => [ - 'Kongeriket Norge er et nordisk, europeisk land og en selvstendig stat vest på Den skandinaviske halvøy. Landet er langt og smalt, og kysten strekker seg langs Nord-Atlanteren, hvor også Norges kjente fjorder befinner seg. Totalt dekker det relativt tynt befolkede landet 385 000 kvadratkilometer med litt over fem millioner innbyggere (2016).', - 'no', - 0.007076 - ] - ]; - } + public function languageExamplesProvider() + { + return [ + 'empty text' => [ + '', + '', + null + ], + 'English' => [ + 'English is a West Germanic language that was first spoken in early medieval England and is now a global lingua franca.[4][5] Named after the Angles, one of the Germanic tribes that migrated to England, it ultimately derives its name from the Anglia (Angeln) peninsula in the Baltic Sea. It is closely related to the Frisian languages, but its vocabulary has been significantly influenced by other Germanic languages, particularly Norse (a North Germanic language), as well as by Latin and Romance languages, especially French.', + 'en', + 0.078422 + ], + 'German' => [ + 'Deutschland ist ein Bundesstaat in Mitteleuropa. Er besteht aus 16 Ländern und ist als freiheitlich-demokratischer und sozialer Rechtsstaat verfasst. Die Bundesrepublik Deutschland stellt die jüngste Ausprägung des deutschen Nationalstaates dar. Mit rund 82,8 Millionen Einwohnern (31. Dezember 2016) zählt Deutschland zu den dicht besiedelten Flächenstaaten.', + 'de', + 0.134339 + ], + 'Norwegian' => [ + 'Kongeriket Norge er et nordisk, europeisk land og en selvstendig stat vest på Den skandinaviske halvøy. Landet er langt og smalt, og kysten strekker seg langs Nord-Atlanteren, hvor også Norges kjente fjorder befinner seg. Totalt dekker det relativt tynt befolkede landet 385 000 kvadratkilometer med litt over fem millioner innbyggere (2016).', + 'no', + 0.007076 + ] + ]; + } - /** - * @covers ::get_language_name - * @dataProvider getLanguageNameProvider - */ - public function testGetLanguageName($lang, $name, $trans) { - $this->assertEquals($name, get_language_name($lang)); - foreach ($trans as $k => $v) { - //echo "$k -> $v"; - $this->assertEquals($v, get_language_name($lang, $k)); - } - } + /** + * @covers ::get_language_name + * @dataProvider getLanguageNameProvider + */ + public function testGetLanguageName($lang, $name, $trans) + { + $this->assertEquals($name, get_language_name($lang)); + foreach ($trans as $k => $v) { + //echo "$k -> $v"; + $this->assertEquals($v, get_language_name($lang, $k)); + } + } - public function getLanguageNameProvider() { - return [ - 'empty language code' => [ - '', - '', - ['de' => ''] - ], - 'invalid language code' => [ - 'zz', - 'zz', - ['de' => 'zz'] - ], - 'de' => [ - 'de', - 'German', - [ - 'de' => 'Deutsch', - 'nb' => 'tysk' - ] - ], - 'de-de' => [ - 'de-de', - 'German', - [ - 'de-de' => 'Deutsch', - 'nb' => 'Deutsch' // should be tysk, seems to be a bug upstream - ] - ], - 'en' => [ - 'en', - 'English', - [ - 'de' => 'Englisch', - 'nb' => 'engelsk' - ] - ], - 'en-gb' => [ - 'en-gb', - 'British English', - [ - 'de' => 'Britisches Englisch', - 'nb' => 'engelsk (Storbritannia)' - ] - ], - 'en-au' => [ - 'en-au', - 'Australian English', - [ - 'de' => 'Australisches Englisch', - 'nb' => 'engelsk (Australia)' - ] - ], - 'nb' => [ - 'nb', - 'Norwegian Bokmål', - [ - 'de' => 'Norwegisch Bokmål', - 'nb' => 'norsk bokmål' - ] - ] - ]; - } -} \ No newline at end of file + public function getLanguageNameProvider() + { + return [ + 'empty language code' => [ + '', + '', + ['de' => ''] + ], + 'invalid language code' => [ + 'zz', + 'zz', + ['de' => 'zz'] + ], + 'de' => [ + 'de', + 'German', + [ + 'de' => 'Deutsch', + 'nb' => 'tysk' + ] + ], + 'de-de' => [ + 'de-de', + 'German', + [ + 'de-de' => 'Deutsch', + 'nb' => 'Deutsch' // should be tysk, seems to be a bug upstream + ] + ], + 'en' => [ + 'en', + 'English', + [ + 'de' => 'Englisch', + 'nb' => 'engelsk' + ] + ], + 'en-gb' => [ + 'en-gb', + 'British English', + [ + 'de' => 'Britisches Englisch', + 'nb' => 'engelsk (Storbritannia)' + ] + ], + 'en-au' => [ + 'en-au', + 'Australian English', + [ + 'de' => 'Australisches Englisch', + 'nb' => 'engelsk (Australia)' + ] + ], + 'nb' => [ + 'nb', + 'Norwegian Bokmål', + [ + 'de' => 'Norwegisch Bokmål', + 'nb' => 'norsk bokmål' + ] + ] + ]; + } +} diff --git a/tests/unit/includes/TextTest.php b/tests/unit/includes/TextTest.php index 97fa64895..b23624354 100644 --- a/tests/unit/includes/TextTest.php +++ b/tests/unit/includes/TextTest.php @@ -9,112 +9,121 @@ use Zotlabs\Tests\Unit\UnitTestCase; * * @author ken restivo */ -class TextTest extends UnitTestCase { +class TextTest extends UnitTestCase +{ - public function testPurifyHTML() { - // linebreaks - $htmlbr = 'first line
                    + public function testPurifyHTML() + { + // linebreaks + $htmlbr = 'first line
                    one tab preserved empty line above'; - $this->assertEquals($htmlbr, purify_html($htmlbr)); + $this->assertEquals($htmlbr, purify_html($htmlbr)); - // HTML5 is not supported by HTMLPurifier yet, test our own configuration - $html5elements = '
                    section
                    footer
                    '; - $this->assertEquals($html5elements, purify_html($html5elements)); - $this->assertEquals('', purify_html('')); + // HTML5 is not supported by HTMLPurifier yet, test our own configuration + $html5elements = '
                    section
                    footer
                    '; + $this->assertEquals($html5elements, purify_html($html5elements)); + $this->assertEquals('', purify_html('')); - // unsupported HTML5 elements - $this->assertEquals('Your HTML parser does not support HTML5 video.', purify_html('')); - $this->assertEquals('Your HTML parser does not support HTML5 audio.', purify_html('')); + // unsupported HTML5 elements + $this->assertEquals('Your HTML parser does not support HTML5 video.', purify_html('')); + $this->assertEquals('Your HTML parser does not support HTML5 audio.', purify_html('')); - // preserve f6 and bootstrap additional data attributes from our own configuration - $this->assertEquals('
                    text
                    ', purify_html('
                    text
                    ')); - $this->assertEquals('
                    • item1
                    ', purify_html('
                    • item1
                    ')); - $this->assertEquals('
                    • item1
                    ', purify_html('
                    • item1
                    ')); - } + // preserve f6 and bootstrap additional data attributes from our own configuration + $this->assertEquals('
                    text
                    ', purify_html('
                    text
                    ')); + $this->assertEquals('
                    • item1
                    ', purify_html('
                    • item1
                    ')); + $this->assertEquals('
                    • item1
                    ', purify_html('
                    • item1
                    ')); + } - /** - * @covers ::purify_html - */ - public function testPurifyHTML_html() { - $this->assertEquals('

                    ids und classes

                    ', purify_html('

                    ids und classes

                    ')); - $this->assertEquals('

                    close missing tags

                    ', purify_html('

                    close missing tags')); - $this->assertEquals('

                    deprecated tag
                    ', purify_html('
                    deprecated tag
                    ')); - $this->assertEquals('
                    illegal nesting
                    ', purify_html('
                    illegal nesting
                    ')); - $this->assertEquals('link with target', purify_html('link with target')); - $this->assertEquals('link with rel="nofollow"', purify_html('link with rel="nofollow"')); - $this->assertEquals('a b', purify_html('a b')); - $this->assertEquals('ä ä € €', purify_html('ä ä € €')); - $this->assertEquals('text', purify_html('text')); - $this->assertEquals('', purify_html('')); - } + /** + * @covers ::purify_html + */ + public function testPurifyHTML_html() + { + $this->assertEquals('

                    ids und classes

                    ', purify_html('

                    ids und classes

                    ')); + $this->assertEquals('

                    close missing tags

                    ', purify_html('

                    close missing tags')); + $this->assertEquals('

                    deprecated tag
                    ', purify_html('
                    deprecated tag
                    ')); + $this->assertEquals('
                    illegal nesting
                    ', purify_html('
                    illegal nesting
                    ')); + $this->assertEquals('link with target', purify_html('link with target')); + $this->assertEquals('link with rel="nofollow"', purify_html('link with rel="nofollow"')); + $this->assertEquals('a b', purify_html('a b')); + $this->assertEquals('ä ä € €', purify_html('ä ä € €')); + $this->assertEquals('text', purify_html('text')); + $this->assertEquals('', purify_html('')); + } - /** - * @covers ::purify_html - */ - public function testPurifyHTML_js() { - $this->assertEquals('
                    ', purify_html('
                    ')); - $this->assertEquals('link', purify_html('link')); - $this->assertEquals('', purify_html('')); - $this->assertEquals('', purify_html('')); - } + /** + * @covers ::purify_html + */ + public function testPurifyHTML_js() + { + $this->assertEquals('
                    ', purify_html('
                    ')); + $this->assertEquals('link', purify_html('link')); + $this->assertEquals('', purify_html('')); + $this->assertEquals('', purify_html('')); + } - /** - * @covers ::purify_html - */ - public function testPurifyHTML_css() { - $this->assertEquals('

                    red

                    ', purify_html('

                    red

                    ')); - $this->assertEquals('

                    invalid color

                    ', purify_html('

                    invalid color

                    ')); - $this->assertEquals('

                    invalid style

                    ', purify_html('

                    invalid style

                    ')); + /** + * @covers ::purify_html + */ + public function testPurifyHTML_css() + { + $this->assertEquals('

                    red

                    ', purify_html('

                    red

                    ')); + $this->assertEquals('

                    invalid color

                    ', purify_html('

                    invalid color

                    ')); + $this->assertEquals('

                    invalid style

                    ', purify_html('

                    invalid style

                    ')); - // test our own CSS configuration - $this->assertEquals('
                    position removed
                    ', purify_html('
                    position removed
                    ')); - $this->assertEquals('
                    position preserved
                    ', purify_html('
                    position preserved
                    ', true)); - $this->assertEquals('
                    invalid position removed
                    ', purify_html('
                    invalid position removed
                    ', true)); + // test our own CSS configuration + $this->assertEquals('
                    position removed
                    ', purify_html('
                    position removed
                    ')); + $this->assertEquals('
                    position preserved
                    ', purify_html('
                    position preserved
                    ', true)); + $this->assertEquals('
                    invalid position removed
                    ', purify_html('
                    invalid position removed
                    ', true)); - $this->assertEquals('
                    position removed
                    ', purify_html('
                    position removed
                    ')); - $this->assertEquals('
                    position preserved
                    ', purify_html('
                    position preserved
                    ', true)); - $this->assertEquals('
                    invalid position removed
                    ', purify_html('
                    invalid position removed
                    ', true)); - } + $this->assertEquals('
                    position removed
                    ', purify_html('
                    position removed
                    ')); + $this->assertEquals('
                    position preserved
                    ', purify_html('
                    position preserved
                    ', true)); + $this->assertEquals('
                    invalid position removed
                    ', purify_html('
                    invalid position removed
                    ', true)); + } - /** - * @dataProvider notagsProvider - */ - public function testNotags($string, $expected) { - $this->assertEquals($expected, notags($string)); - } - public function notagsProvider() { - return [ - 'empty string' => ['', ''], - 'simple tag' => ['', '[value]'], - 'tag pair' => ['text', '[b]text[/b]'], - 'double angle bracket' => ['< ['>', '>'] - ]; - } + /** + * @dataProvider notagsProvider + */ + public function testNotags($string, $expected) + { + $this->assertEquals($expected, notags($string)); + } + public function notagsProvider() + { + return [ + 'empty string' => ['', ''], + 'simple tag' => ['', '[value]'], + 'tag pair' => ['text', '[b]text[/b]'], + 'double angle bracket' => ['< ['>', '>'] + ]; + } - /** - * @dataProvider sanitise_aclProvider - */ - public function testSanitise_acl($string, $expected) { - sanitise_acl($string); - $this->assertEquals($expected, $string); - } - public function sanitise_aclProvider() { - return [ - 'text' => ['value', ''], - 'text with angle bracket' => ['', '<[value]>'], - 'comma separated acls' => ['value1,value2', ''] - ]; - } - - public function testUnsetSanitise_acl() { - $empty = ''; - sanitise_acl($empty); - $this->assertTrue(isset($empty)); // unset() not working? Would expect false - $this->assertEmpty($empty); - } + /** + * @dataProvider sanitise_aclProvider + */ + public function testSanitise_acl($string, $expected) + { + sanitise_acl($string); + $this->assertEquals($expected, $string); + } + public function sanitise_aclProvider() + { + return [ + 'text' => ['value', ''], + 'text with angle bracket' => ['', '<[value]>'], + 'comma separated acls' => ['value1,value2', ''] + ]; + } + public function testUnsetSanitise_acl() + { + $empty = ''; + sanitise_acl($empty); + $this->assertTrue(isset($empty)); // unset() not working? Would expect false + $this->assertEmpty($empty); + } } diff --git a/tests/unit/includes/dba/DBATest.php b/tests/unit/includes/dba/DBATest.php index a7342e09a..6131e983e 100644 --- a/tests/unit/includes/dba/DBATest.php +++ b/tests/unit/includes/dba/DBATest.php @@ -1,4 +1,5 @@ assertNull(DBA::$dba); + public function testDbaFactoryMysql() + { + $this->assertNull(DBA::$dba); - $ret = DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '0'); - $this->assertInstanceOf('dba_pdo', $ret); - $this->assertFalse($ret->connected); + $ret = DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '0'); + $this->assertInstanceOf('dba_pdo', $ret); + $this->assertFalse($ret->connected); - $this->assertSame('mysql', DBA::$scheme); - $this->assertSame('schema_mysql.sql', DBA::$install_script); - $this->assertSame('0001-01-01 00:00:00', DBA::$null_date); - $this->assertSame('UTC_TIMESTAMP()', DBA::$utc_now); - $this->assertSame('`', DBA::$tquot); - } + $this->assertSame('mysql', DBA::$scheme); + $this->assertSame('schema_mysql.sql', DBA::$install_script); + $this->assertSame('0001-01-01 00:00:00', DBA::$null_date); + $this->assertSame('UTC_TIMESTAMP()', DBA::$utc_now); + $this->assertSame('`', DBA::$tquot); + } - public function testDbaFactoryPostgresql() { - $this->assertNull(DBA::$dba); + public function testDbaFactoryPostgresql() + { + $this->assertNull(DBA::$dba); - $ret = DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '1'); - $this->assertInstanceOf('dba_pdo', $ret); - $this->assertFalse($ret->connected); - - $this->assertSame('pgsql', DBA::$scheme); - $this->assertSame('schema_postgres.sql', DBA::$install_script); - $this->assertSame('0001-01-01 00:00:00', DBA::$null_date); - $this->assertSame("now() at time zone 'UTC'", DBA::$utc_now); - $this->assertSame('"', DBA::$tquot); - } + $ret = DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '1'); + $this->assertInstanceOf('dba_pdo', $ret); + $this->assertFalse($ret->connected); + $this->assertSame('pgsql', DBA::$scheme); + $this->assertSame('schema_postgres.sql', DBA::$install_script); + $this->assertSame('0001-01-01 00:00:00', DBA::$null_date); + $this->assertSame("now() at time zone 'UTC'", DBA::$utc_now); + $this->assertSame('"', DBA::$tquot); + } } diff --git a/tests/unit/includes/dba/dba_pdoTest.php b/tests/unit/includes/dba/dba_pdoTest.php index 0c387341c..a3fc14ddd 100644 --- a/tests/unit/includes/dba/dba_pdoTest.php +++ b/tests/unit/includes/dba/dba_pdoTest.php @@ -1,4 +1,5 @@ dba = new dba_pdo( - getenv('hz_db_server'), - getenv('hz_db_scheme'), - getenv('hz_db_port'), - getenv('hz_db_user'), - getenv('hz_db_pass'), - getenv('hz_db_database') - ); - } - protected function assertPreConditions() { - $this->assertSame('pdo', $this->dba->getdriver(), "Driver is expected to be 'pdo'."); - $this->assertInstanceOf('dba_driver', $this->dba); - $this->assertTrue($this->dba->connected, 'Pre condition failed, DB is not connected.'); - $this->assertInstanceOf('PDO', $this->dba->db); - } - protected function tearDown() { - $this->dba = null; - } + $this->dba = new dba_pdo( + getenv('hz_db_server'), + getenv('hz_db_scheme'), + getenv('hz_db_port'), + getenv('hz_db_user'), + getenv('hz_db_pass'), + getenv('hz_db_database') + ); + } + protected function assertPreConditions() + { + $this->assertSame('pdo', $this->dba->getdriver(), "Driver is expected to be 'pdo'."); + $this->assertInstanceOf('dba_driver', $this->dba); + $this->assertTrue($this->dba->connected, 'Pre condition failed, DB is not connected.'); + $this->assertInstanceOf('PDO', $this->dba->db); + } + protected function tearDown() + { + $this->dba = null; + } - /** - * @group mysql - */ - public function testQuoteintervalOnMysql() { - $this->assertSame('value', $this->dba->quote_interval('value')); - } - /** - * @group postgresql - */ - public function testQuoteintervalOnPostgresql() { - $this->assertSame("'value'", $this->dba->quote_interval('value')); - } + /** + * @group mysql + */ + public function testQuoteintervalOnMysql() + { + $this->assertSame('value', $this->dba->quote_interval('value')); + } + /** + * @group postgresql + */ + public function testQuoteintervalOnPostgresql() + { + $this->assertSame("'value'", $this->dba->quote_interval('value')); + } - /** - * @group mysql - */ - public function testGenerateMysqlConcatSql() { - $this->assertSame('GROUP_CONCAT(DISTINCT field SEPARATOR \';\')', $this->dba->concat('field', ';')); - $this->assertSame('GROUP_CONCAT(DISTINCT field2 SEPARATOR \' \')', $this->dba->concat('field2', ' ')); - } - /** - * @group postgresql - */ - public function testGeneratePostgresqlConcatSql() { - $this->assertSame('string_agg(field,\';\')', $this->dba->concat('field', ';')); - $this->assertSame('string_agg(field2,\' \')', $this->dba->concat('field2', ' ')); - } + /** + * @group mysql + */ + public function testGenerateMysqlConcatSql() + { + $this->assertSame('GROUP_CONCAT(DISTINCT field SEPARATOR \';\')', $this->dba->concat('field', ';')); + $this->assertSame('GROUP_CONCAT(DISTINCT field2 SEPARATOR \' \')', $this->dba->concat('field2', ' ')); + } + /** + * @group postgresql + */ + public function testGeneratePostgresqlConcatSql() + { + $this->assertSame('string_agg(field,\';\')', $this->dba->concat('field', ';')); + $this->assertSame('string_agg(field2,\' \')', $this->dba->concat('field2', ' ')); + } - public function testConnectToSqlServer() { - // connect() is done in dba_pdo constructor which is called in setUp() - $this->assertTrue($this->dba->connected); - } + public function testConnectToSqlServer() + { + // connect() is done in dba_pdo constructor which is called in setUp() + $this->assertTrue($this->dba->connected); + } - /** - * @depends testConnectToSqlServer - */ - public function testCloseSqlServerConnection() { - $this->dba->close(); + /** + * @depends testConnectToSqlServer + */ + public function testCloseSqlServerConnection() + { + $this->dba->close(); - $this->assertNull($this->dba->db); - $this->assertFalse($this->dba->connected); - } + $this->assertNull($this->dba->db); + $this->assertFalse($this->dba->connected); + } - /** - * @depends testConnectToSqlServer - */ - public function testSelectQueryShouldReturnArray() { - $ret = $this->dba->q('SELECT * FROM account'); + /** + * @depends testConnectToSqlServer + */ + public function testSelectQueryShouldReturnArray() + { + $ret = $this->dba->q('SELECT * FROM account'); - $this->assertTrue(is_array($ret)); - } + $this->assertTrue(is_array($ret)); + } - /** - * @depends testConnectToSqlServer - */ - public function testInsertQueryShouldReturnPdostatement() { - // Fixture account.yml adds two entries to account table - $this->assertEquals(2, $this->getConnection()->getRowCount('account'), 'Pre-Condition'); + /** + * @depends testConnectToSqlServer + */ + public function testInsertQueryShouldReturnPdostatement() + { + // Fixture account.yml adds two entries to account table + $this->assertEquals(2, $this->getConnection()->getRowCount('account'), 'Pre-Condition'); - $ret = $this->dba->q('INSERT INTO account + $ret = $this->dba->q('INSERT INTO account (account_id, account_email, account_language) VALUES (100, \'insert@example.com\', \'de\') '); - $this->assertInstanceOf('PDOStatement', $ret); + $this->assertInstanceOf('PDOStatement', $ret); - $this->assertEquals(3, $this->getConnection()->getRowCount('account'), 'Inserting failed'); - } + $this->assertEquals(3, $this->getConnection()->getRowCount('account'), 'Inserting failed'); + } - public function testConnectToWrongSqlServer() { - $nodba = new dba_pdo('wrongserver', - getenv('hz_db_scheme'), getenv('hz_db_port'), - getenv('hz_db_user'), getenv('hz_db_pass'), - getenv('hz_db_database') - ); + public function testConnectToWrongSqlServer() + { + $nodba = new dba_pdo( + 'wrongserver', + getenv('hz_db_scheme'), + getenv('hz_db_port'), + getenv('hz_db_user'), + getenv('hz_db_pass'), + getenv('hz_db_database') + ); - $this->assertSame('pdo', $nodba->getdriver()); - $this->assertInstanceOf('dba_pdo', $nodba); - $this->assertFalse($nodba->connected); - $this->assertNull($nodba->db); + $this->assertSame('pdo', $nodba->getdriver()); + $this->assertInstanceOf('dba_pdo', $nodba); + $this->assertFalse($nodba->connected); + $this->assertNull($nodba->db); - $this->assertFalse($nodba->q('SELECT * FROM account')); - } + $this->assertFalse($nodba->q('SELECT * FROM account')); + } - /** - * @depends testConnectToSqlServer - */ - public function testSelectQueryToNonExistentTableShouldReturnFalse() { - $ret = $this->dba->q('SELECT * FROM non_existent_table'); + /** + * @depends testConnectToSqlServer + */ + public function testSelectQueryToNonExistentTableShouldReturnFalse() + { + $ret = $this->dba->q('SELECT * FROM non_existent_table'); - $this->assertFalse($ret); - } + $this->assertFalse($ret); + } - /** - * @depends testConnectToSqlServer - */ - public function testInsertQueryToNonExistentTableShouldReturnEmptyArray() { - $ret = $this->dba->q('INSERT INTO non_existent_table + /** + * @depends testConnectToSqlServer + */ + public function testInsertQueryToNonExistentTableShouldReturnEmptyArray() + { + $ret = $this->dba->q('INSERT INTO non_existent_table (account_email, account_language) VALUES (\'email@example.com\', \'en\') '); - $this->assertNotInstanceOf('PDOStatement', $ret); - $this->isEmpty($ret); - } - + $this->assertNotInstanceOf('PDOStatement', $ret); + $this->isEmpty($ret); + } } diff --git a/tests/unit/template_test.php b/tests/unit/template_test.php index 929512773..975f1bb38 100644 --- a/tests/unit/template_test.php +++ b/tests/unit/template_test.php @@ -1,218 +1,220 @@ -assertTrue(is_null($second)); - } - - public function testSimpleVariableString() { - $tpl='Hello $name!'; - - $text=replace_macros($tpl, array('$name'=>'Anna')); - - $this->assertEquals('Hello Anna!', $text); - } - - public function testSimpleVariableInt() { - $tpl='There are $num new messages!'; - - $text=replace_macros($tpl, array('$num'=>172)); - - $this->assertEquals('There are 172 new messages!', $text); - } - - public function testConditionalElse() { - $tpl='There{{ if $num!=1 }} are $num new messages{{ else }} is 1 new message{{ endif }}!'; - - $text1=replace_macros($tpl, array('$num'=>1)); - $text22=replace_macros($tpl, array('$num'=>22)); - - $this->assertEquals('There is 1 new message!', $text1); - $this->assertEquals('There are 22 new messages!', $text22); - } - - public function testConditionalNoElse() { - $tpl='{{ if $num!=0 }}There are $num new messages!{{ endif }}'; - - $text0=replace_macros($tpl, array('$num'=>0)); - $text22=replace_macros($tpl, array('$num'=>22)); - - $this->assertEquals('', $text0); - $this->assertEquals('There are 22 new messages!', $text22); - } - - public function testConditionalFail() { - $tpl='There {{ if $num!=1 }} are $num new messages{{ else }} is 1 new message{{ endif }}!'; - - $text1=replace_macros($tpl, []); - - //$this->assertEquals('There is 1 new message!', $text1); - } - - public function testSimpleFor() { - $tpl='{{ for $messages as $message }} $message {{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>array('message 1', 'message 2'))); - - $this->assertEquals(' message 1 message 2 ', $text); - } - - public function testFor() { - $tpl='{{ for $messages as $message }} from: $message.from to $message.to {{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>array(array('from'=>'Mike', 'to'=>'Alex'), array('from'=>'Alex', 'to'=>'Mike')))); - - $this->assertEquals(' from: Mike to Alex from: Alex to Mike ', $text); - } - - public function testKeyedFor() { - $tpl='{{ for $messages as $from=>$to }} from: $from to $to {{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>array('Mike'=>'Alex', 'Sven'=>'Mike'))); - - $this->assertEquals(' from: Mike to Alex from: Sven to Mike ', $text); - } - - public function testForEmpty() { - $tpl='messages: {{for $messages as $message}} from: $message.from to $message.to {{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>[])); - - $this->assertEquals('messages: ', $text); - } - - public function testForWrongType() { - $tpl='messages: {{for $messages as $message}} from: $message.from to $message.to {{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>11)); - - $this->assertEquals('messages: ', $text); - } - - public function testForConditional() { - $tpl='new messages: {{for $messages as $message}}{{ if $message.new }} $message.text{{endif}}{{ endfor }}'; - - $text=replace_macros($tpl, array('$messages'=>array( - array('new'=>true, 'text'=>'new message'), - array('new'=>false, 'text'=>'old message')))); - - $this->assertEquals('new messages: new message', $text); - } - - public function testConditionalFor() { - $tpl='{{ if $enabled }}new messages:{{for $messages as $message}} $message.text{{ endfor }}{{endif}}'; - - $text=replace_macros($tpl, array('$enabled'=>true, - '$messages'=>array( - array('new'=>true, 'text'=>'new message'), - array('new'=>false, 'text'=>'old message')))); - - $this->assertEquals('new messages: new message old message', $text); - } - - public function testFantasy() { - $tpl='Fantasy: {{fantasy $messages}}'; - - $text=replace_macros($tpl, array('$messages'=>'no no')); - - $this->assertEquals('Fantasy: {{fantasy no no}}', $text); - } - - public function testInc() { - $tpl='{{inc field_input.tpl with $field=$myvar}}{{ endinc }}'; - - $text=replace_macros($tpl, array('$myvar'=>array('myfield', 'label', 'value', 'help'))); - - $this->assertEquals(" \n" - ."
                    \n" - ." \n" - ." \n" - ." help\n" - ."
                    \n", $text); - } - - public function testIncNoVar() { - $tpl='{{inc field_input.tpl }}{{ endinc }}'; - - $text=replace_macros($tpl, array('$field'=>array('myfield', 'label', 'value', 'help'))); - - $this->assertEquals(" \n
                    \n \n" - ." \n" - ." help\n" - ."
                    \n", $text); - } - - public function testDoubleUse() { - $tpl='Hello $name! {{ if $enabled }} I love you! {{ endif }}'; - - $text=replace_macros($tpl, array('$name'=>'Anna', '$enabled'=>false)); - - $this->assertEquals('Hello Anna! ', $text); - - $tpl='Hey $name! {{ if $enabled }} I hate you! {{ endif }}'; - - $text=replace_macros($tpl, array('$name'=>'Max', '$enabled'=>true)); - - $this->assertEquals('Hey Max! I hate you! ', $text); - } - - public function testIncDouble() { - $tpl='{{inc field_input.tpl with $field=$var1}}{{ endinc }}' - .'{{inc field_input.tpl with $field=$var2}}{{ endinc }}'; - - $text=replace_macros($tpl, array('$var1'=>array('myfield', 'label', 'value', 'help'), - '$var2'=>array('myfield2', 'label2', 'value2', 'help2'))); - - $this->assertEquals(" \n" - ."
                    \n" - ." \n" - ." \n" - ." help\n" - ."
                    \n" - ." \n" - ."
                    \n" - ." \n" - ." \n" - ." help2\n" - ."
                    \n", $text); - } -} \ No newline at end of file +assertTrue(is_null($second)); + } + + public function testSimpleVariableString() + { + $tpl = 'Hello $name!'; + $text = replace_macros($tpl, array('$name' => 'Anna')); + $this->assertEquals('Hello Anna!', $text); + } + + public function testSimpleVariableInt() + { + $tpl = 'There are $num new messages!'; + $text = replace_macros($tpl, array('$num' => 172)); + $this->assertEquals('There are 172 new messages!', $text); + } + + public function testConditionalElse() + { + $tpl = 'There{{ if $num!=1 }} are $num new messages{{ else }} is 1 new message{{ endif }}!'; + $text1 = replace_macros($tpl, array('$num' => 1)); + $text22 = replace_macros($tpl, array('$num' => 22)); + $this->assertEquals('There is 1 new message!', $text1); + $this->assertEquals('There are 22 new messages!', $text22); + } + + public function testConditionalNoElse() + { + $tpl = '{{ if $num!=0 }}There are $num new messages!{{ endif }}'; + $text0 = replace_macros($tpl, array('$num' => 0)); + $text22 = replace_macros($tpl, array('$num' => 22)); + $this->assertEquals('', $text0); + $this->assertEquals('There are 22 new messages!', $text22); + } + + public function testConditionalFail() + { + $tpl = 'There {{ if $num!=1 }} are $num new messages{{ else }} is 1 new message{{ endif }}!'; + $text1 = replace_macros($tpl, []); + + //$this->assertEquals('There is 1 new message!', $text1); + } + + public function testSimpleFor() + { + $tpl = '{{ for $messages as $message }} $message {{ endfor }}'; + $text = replace_macros($tpl, array('$messages' => array('message 1', 'message 2'))); + $this->assertEquals(' message 1 message 2 ', $text); + } + + public function testFor() + { + $tpl = '{{ for $messages as $message }} from: $message.from to $message.to {{ endfor }}'; + $text = replace_macros($tpl, array('$messages' => array(array('from' => 'Mike', 'to' => 'Alex'), array('from' => 'Alex', 'to' => 'Mike')))); + $this->assertEquals(' from: Mike to Alex from: Alex to Mike ', $text); + } + + public function testKeyedFor() + { + $tpl = '{{ for $messages as $from=>$to }} from: $from to $to {{ endfor }}'; + + $text = replace_macros($tpl, array('$messages' => array('Mike' => 'Alex', 'Sven' => 'Mike'))); + + $this->assertEquals(' from: Mike to Alex from: Sven to Mike ', $text); + } + + public function testForEmpty() + { + $tpl = 'messages: {{for $messages as $message}} from: $message.from to $message.to {{ endfor }}'; + $text = replace_macros($tpl, array('$messages' => [])); + $this->assertEquals('messages: ', $text); + } + + public function testForWrongType() + { + $tpl = 'messages: {{for $messages as $message}} from: $message.from to $message.to {{ endfor }}'; + $text = replace_macros($tpl, array('$messages' => 11)); + $this->assertEquals('messages: ', $text); + } + + public function testForConditional() + { + $tpl = 'new messages: {{for $messages as $message}}{{ if $message.new }} $message.text{{endif}}{{ endfor }}'; + $text = replace_macros($tpl, array('$messages' => array( + array('new' => true, 'text' => 'new message'), + array('new' => false, 'text' => 'old message')))); + $this->assertEquals('new messages: new message', $text); + } + + public function testConditionalFor() + { + $tpl = '{{ if $enabled }}new messages:{{for $messages as $message}} $message.text{{ endfor }}{{endif}}'; + + $text = replace_macros($tpl, array('$enabled' => true, + '$messages' => array( + array('new' => true, 'text' => 'new message'), + array('new' => false, 'text' => 'old message')))); + + $this->assertEquals('new messages: new message old message', $text); + } + + public function testFantasy() + { + $tpl = 'Fantasy: {{fantasy $messages}}'; + $text = replace_macros($tpl, array('$messages' => 'no no')); + $this->assertEquals('Fantasy: {{fantasy no no}}', $text); + } + + public function testInc() + { + $tpl = '{{inc field_input.tpl with $field=$myvar}}{{ endinc }}'; + $text = replace_macros($tpl, array('$myvar' => array('myfield', 'label', 'value', 'help'))); + $this->assertEquals(" \n" + . "
                    \n" + . " \n" + . " \n" + . " help\n" + . "
                    \n", $text); + } + + public function testIncNoVar() + { + $tpl = '{{inc field_input.tpl }}{{ endinc }}'; + $text = replace_macros($tpl, array('$field' => array('myfield', 'label', 'value', 'help'))); + $this->assertEquals(" \n
                    \n \n" + . " \n" + . " help\n" + . "
                    \n", $text); + } + + public function testDoubleUse() + { + $tpl = 'Hello $name! {{ if $enabled }} I love you! {{ endif }}'; + + $text = replace_macros($tpl, array('$name' => 'Anna', '$enabled' => false)); + + $this->assertEquals('Hello Anna! ', $text); + + $tpl = 'Hey $name! {{ if $enabled }} I hate you! {{ endif }}'; + + $text = replace_macros($tpl, array('$name' => 'Max', '$enabled' => true)); + + $this->assertEquals('Hey Max! I hate you! ', $text); + } + + public function testIncDouble() + { + $tpl = '{{inc field_input.tpl with $field=$var1}}{{ endinc }}' + . '{{inc field_input.tpl with $field=$var2}}{{ endinc }}'; + + $text = replace_macros($tpl, array('$var1' => array('myfield', 'label', 'value', 'help'), + '$var2' => array('myfield2', 'label2', 'value2', 'help2'))); + + $this->assertEquals(" \n" + . "
                    \n" + . " \n" + . " \n" + . " help\n" + . "
                    \n" + . " \n" + . "
                    \n" + . " \n" + . " \n" + . " help2\n" + . "
                    \n", $text); + } +} diff --git a/util/docblox_errorchecker.php b/util/docblox_errorchecker.php index 81b7baf6d..259486514 100644 --- a/util/docblox_errorchecker.php +++ b/util/docblox_errorchecker.php @@ -1,4 +1,5 @@ -\n\n"; - return; - } +if ($argc != 2) { + print 'Usage: ' . $argv[0] . " \n\n"; + return; +} $phpfile = $argv[1]; - $pofile = dirname($phpfile). '/messages.po'; + $pofile = dirname($phpfile) . '/messages.po'; - if (!file_exists($phpfile)){ - print "Unable to find '$phpfile'\n"; - return; - } +if (!file_exists($phpfile)) { + print "Unable to find '$phpfile'\n"; + return; +} include_once($phpfile); @@ -28,58 +29,58 @@ $infile = file($pofile); $k = ''; $c = ''; - $ink = False; - foreach ($infile as $l) { - - $l = trim($l, ' '); - if (!preg_match('/^msgstr\[[1-9]/',$l)) { - if ($k!= '' && (substr($l,0,7)== 'msgstr ' || substr($l,0,8)== 'msgstr[0')){ - $ink = False; - $k = stripcslashes($k); - $v = ''; - if (isset(App::$strings[$k])) { - $v = App::$strings[$k]; - } else { - $k = '__ctx:' .$c. '__ ' .$k; - if (isset(App::$strings[$k])) { - $v = App::$strings[$k]; - $c = ''; - } - } - if (!empty($v)) { - if (is_array($v)) { - $l = ''; - $n = 0; - foreach ($v as &$value) { - $l .= 'msgstr[' .$n."] \"".addcslashes($value,"\"\n")."\"\n"; - $n++; - } - } else { - $l = "msgstr \"".addcslashes($v,"\"\n")."\"\n"; - } - } - } - - if (substr($l,0,6)== 'msgid_' || substr($l,0,7)== 'msgstr[') $ink = False; - - if ($ink) { - preg_match('/^"(.*)"$/',$l,$m); - $k .= $m[1]; - } - - if (substr($l,0,6)== 'msgid ') { - preg_match('/^msgid "(.*)"$/',$l,$m); - $k = $m[1]; - $ink = True; - } - - if (substr($l,0,8)== 'msgctxt ') { - preg_match('/^msgctxt "(.*)"$/',$l,$m); - $c = $m[1]; - } - - $out .= $l; + $ink = false; +foreach ($infile as $l) { + $l = trim($l, ' '); + if (!preg_match('/^msgstr\[[1-9]/', $l)) { + if ($k != '' && (substr($l, 0, 7) == 'msgstr ' || substr($l, 0, 8) == 'msgstr[0')) { + $ink = false; + $k = stripcslashes($k); + $v = ''; + if (isset(App::$strings[$k])) { + $v = App::$strings[$k]; + } else { + $k = '__ctx:' . $c . '__ ' . $k; + if (isset(App::$strings[$k])) { + $v = App::$strings[$k]; + $c = ''; } + } + if (!empty($v)) { + if (is_array($v)) { + $l = ''; + $n = 0; + foreach ($v as &$value) { + $l .= 'msgstr[' . $n . "] \"" . addcslashes($value, "\"\n") . "\"\n"; + $n++; + } + } else { + $l = "msgstr \"" . addcslashes($v, "\"\n") . "\"\n"; + } + } } + + if (substr($l, 0, 6) == 'msgid_' || substr($l, 0, 7) == 'msgstr[') { + $ink = false; + } + + if ($ink) { + preg_match('/^"(.*)"$/', $l, $m); + $k .= $m[1]; + } + + if (substr($l, 0, 6) == 'msgid ') { + preg_match('/^msgid "(.*)"$/', $l, $m); + $k = $m[1]; + $ink = true; + } + + if (substr($l, 0, 8) == 'msgctxt ') { + preg_match('/^msgctxt "(.*)"$/', $l, $m); + $c = $m[1]; + } + + $out .= $l; + } +} file_put_contents($pofile, $out); -?> diff --git a/util/po2php.php b/util/po2php.php index 25cff5f29..775b850d4 100644 --- a/util/po2php.php +++ b/util/po2php.php @@ -1,152 +1,173 @@ \n\n"; - return; - } + if ($argc < 2) { + print 'Usage: ' . $argv[0] . " \n\n"; + return; + } - $rtl = false; + $rtl = false; - $pofile = $argv[1]; - $outfile = dirname($pofile). '/strings.php'; + $pofile = $argv[1]; + $outfile = dirname($pofile) . '/strings.php'; - if($argc > 2) { - if($argv[2] === 'rtl') - $rtl = true; - } + if ($argc > 2) { + if ($argv[2] === 'rtl') { + $rtl = true; + } + } - if(strstr($outfile,'util')) - $lang = 'en'; - else - $lang = str_replace('-','_',basename(dirname($pofile))); + if (strstr($outfile, 'util')) { + $lang = 'en'; + } else { + $lang = str_replace('-', '_', basename(dirname($pofile))); + } - if (!file_exists($pofile)){ - print "Unable to find '$pofile'\n"; - return; - } - - print "Out to '$outfile'\n"; - - $out=" ' - .preg_replace_callback($escape_s_exp,'escape_s',$match[2]) .",\n"; - } - - if (substr($l,0,6)== 'msgid_') { - $ink = False; - $out .= 'App::$strings["'.$k.'"] = '; - } + $infile = file($pofile); + $k = ''; + $v = ''; + $ctx = ''; + $arr = false; + $ink = false; + $inv = false; + $escape_s_exp = '|[^\\\\]\$[a-z]|'; + + function escape_s($match) + { + return str_replace('$', '\$', $match[0]); + } + + foreach ($infile as $l) { + $l = str_replace(array('$projectname','$Projectname'), array('\$projectname','\$Projectname'), $l); + $len = strlen($l); + if ($l[0] == '#') { + $l = ''; + } + if (substr($l, 0, 15) == '"Plural-Forms: ') { + $match = array(); + preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match); + $cond = str_replace('n', '$n', $match[2]); + $out .= 'if(! function_exists("' . 'string_plural_select_' . $lang . '")) {' . "\n"; + $out .= 'function string_plural_select_' . $lang . '($n){' . "\n"; + $out .= ' return ' . $cond . ';' . "\n"; + $out .= '}}' . "\n"; + + $out .= 'App::$rtl = ' . intval($rtl) ; + } + + if ($k != '' && substr($l, 0, 7) == 'msgstr ') { + if ($ink) { + $ink = false; + $out .= 'App::$strings["' . $k . '"] = '; + } + if ($inv) { + $inv = false; + $out .= '"' . $v . '"'; + } + + $v = substr($l, 8, $len - 10); + $v = preg_replace_callback($escape_s_exp, 'escape_s', $v); + $inv = true; + //$out .= $v; + } + if ($k != '' && substr($l, 0, 7) == 'msgstr[') { + if ($ink) { + $ink = false; + $out .= 'App::$strings["' . $k . '"] = '; + } + if ($inv) { + $inv = false; + $out .= '"' . $v . '"'; + } + if (!$arr) { + $arr = true; + $out .= "[\n"; + } + $match = array(); + preg_match('|\[([0-9]*)\] (.*)|', $l, $match); + $out .= "\t" . + preg_replace_callback($escape_s_exp, 'escape_s', $match[1]) + . ' => ' + . preg_replace_callback($escape_s_exp, 'escape_s', $match[2]) . ",\n"; + } + + if (substr($l, 0, 6) == 'msgid_') { + $ink = false; + $out .= 'App::$strings["' . $k . '"] = '; + } - if ($ink) { - $k .= trim_message($l); - $k = preg_replace_callback($escape_s_exp,'escape_s',$k); - //$out .= 'App::$strings['.$k.'] = '; - } - - if (substr($l,0,6)== 'msgid '){ - if ($inv) { $inv = False; $out .= '"'.$v.'"'; } - if ($k!= '') $out .= $arr?"];\n":";\n"; - $arr=False; - $k = str_replace('msgid ', '',$l); - $k = trim_message($k); - $k = $ctx.$k; - // echo $ctx ? $ctx."\nX\n":""; - $k = preg_replace_callback($escape_s_exp,'escape_s',$k); - $ctx = ''; - $ink = True; - } - - if ($inv && substr($l,0,6)!= 'msgstr' && substr($l,0,7)!= 'msgctxt') { - $v .= trim_message($l); - $v = preg_replace_callback($escape_s_exp,'escape_s',$v); - //$out .= 'App::$strings['.$k.'] = '; - } + if ($ink) { + $k .= trim_message($l); + $k = preg_replace_callback($escape_s_exp, 'escape_s', $k); + //$out .= 'App::$strings['.$k.'] = '; + } - if (substr($l,0,7)== 'msgctxt') { - $ctx = str_replace('msgctxt ', '',$l); - $ctx = trim_message($ctx); - $ctx = '__ctx:' .$ctx. '__ '; - $ctx = preg_replace_callback($escape_s_exp,'escape_s',$ctx); - } + if (substr($l, 0, 6) == 'msgid ') { + if ($inv) { + $inv = false; + $out .= '"' . $v . '"'; + } + if ($k != '') { + $out .= $arr ? "];\n" : ";\n"; + } + $arr = false; + $k = str_replace('msgid ', '', $l); + $k = trim_message($k); + $k = $ctx . $k; + // echo $ctx ? $ctx."\nX\n":""; + $k = preg_replace_callback($escape_s_exp, 'escape_s', $k); + $ctx = ''; + $ink = true; + } - } + if ($inv && substr($l, 0, 6) != 'msgstr' && substr($l, 0, 7) != 'msgctxt') { + $v .= trim_message($l); + $v = preg_replace_callback($escape_s_exp, 'escape_s', $v); + //$out .= 'App::$strings['.$k.'] = '; + } - if ($inv) { $inv = False; $out .= '"'.$v.'"'; } - if ($k!= '') $out .= $arr?"];\n":";\n"; - - file_put_contents($outfile, $out); - + if (substr($l, 0, 7) == 'msgctxt') { + $ctx = str_replace('msgctxt ', '', $l); + $ctx = trim_message($ctx); + $ctx = '__ctx:' . $ctx . '__ '; + $ctx = preg_replace_callback($escape_s_exp, 'escape_s', $ctx); + } + } + + if ($inv) { + $inv = false; + $out .= '"' . $v . '"'; + } + if ($k != '') { + $out .= $arr ? "];\n" : ";\n"; + } + + file_put_contents($outfile, $out); } -function trim_message($str) { - // Almost same as trim("\"\r\n") except that escaped quotes are preserved - $str = trim($str, "\r\n"); - $str = ltrim($str, "\""); - $str = preg_replace('/(?setTemplateDir($folders); - -$s->setCompileDir(TEMPLATE_BUILD_PATH . '/compiled/'); -$s->setConfigDir(TEMPLATE_BUILD_PATH . '/config/'); -$s->setCacheDir(TEMPLATE_BUILD_PATH . '/cache/'); - -$s->left_delimiter = '{{'; -$s->right_delimiter = '}}'; - -$s->compileAllTemplates('.tpl',true); \ No newline at end of file +setTemplateDir($folders); + +$s->setCompileDir(TEMPLATE_BUILD_PATH . '/compiled/'); +$s->setConfigDir(TEMPLATE_BUILD_PATH . '/config/'); +$s->setCacheDir(TEMPLATE_BUILD_PATH . '/cache/'); + +$s->left_delimiter = '{{'; +$s->right_delimiter = '}}'; + +$s->compileAllTemplates('.tpl', true); diff --git a/util/strings.php b/util/strings.php index 69fe5fadb..f368ed7d6 100644 --- a/util/strings.php +++ b/util/strings.php @@ -156,13 +156,13 @@ App::$strings['I disagree'] = ''; App::$strings['I abstain'] = ''; App::$strings['View all'] = ''; App::$strings['__ctx:noun__ Like'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Likes'] = ''; App::$strings['__ctx:noun__ Dislike'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Dislikes'] = ''; App::$strings['Save'] = ''; @@ -177,8 +177,8 @@ App::$strings['Repeat This'] = ''; App::$strings['Share this'] = ''; App::$strings['Delivery Report'] = ''; App::$strings['%d comment'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['%d unseen'] = ''; App::$strings["View %s's profile - %s"] = ''; @@ -444,12 +444,12 @@ App::$strings['New Password again'] = ''; App::$strings['Account language (for emails)'] = ''; App::$strings['Service class'] = ''; App::$strings['%s account blocked/unblocked'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['%s account deleted'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Account not found'] = ''; App::$strings["Account '%s' deleted"] = ''; @@ -594,16 +594,16 @@ App::$strings['Default: profiles'] = ''; App::$strings['Optional: site location'] = ''; App::$strings['Region or country'] = ''; App::$strings['%s channel censored/uncensored'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['%s channel code allowed/disallowed'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['%s channel deleted'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Channel not found'] = ''; App::$strings["Channel '%s' deleted"] = ''; @@ -1051,8 +1051,8 @@ App::$strings["Please join us on \$Projectname"] = ''; App::$strings['Invitation limit exceeded. Please contact your site administrator.'] = ''; App::$strings['%s : Message delivery failed.'] = ''; App::$strings['%d message sent.'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Send email invitations to join this network'] = ''; App::$strings['You have no more invitations available'] = ''; @@ -1940,8 +1940,8 @@ App::$strings['Remove Item Tag'] = ''; App::$strings['Select a tag to remove: '] = ''; App::$strings['No default suggestions were found.'] = ''; App::$strings['%d rating'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Gender: '] = ''; App::$strings['Status: '] = ''; @@ -2055,8 +2055,8 @@ App::$strings['Common Connections'] = ''; App::$strings['View all %d common connections'] = ''; App::$strings['Saved Folders'] = ''; App::$strings['%d invitation available'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Find Channels'] = ''; App::$strings['Enter name or interest'] = ''; @@ -2247,32 +2247,32 @@ App::$strings['never'] = ''; App::$strings['less than a second ago'] = ''; App::$strings["__ctx:e.g. 22 hours ago, 1 minute ago__ %1\$d %2\$s ago"] = ''; App::$strings['__ctx:relative_date__ year'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ month'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ week'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ day'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ hour'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ minute'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:relative_date__ second'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings["%1\$s's birthday"] = ''; App::$strings["Happy Birthday %1\$s"] = ''; @@ -2579,17 +2579,17 @@ App::$strings['Block author'] = ''; App::$strings['%s likes this.'] = ''; App::$strings["%s doesn't like this."] = ''; App::$strings["%2\$d people like this."] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings["%2\$d people don't like this."] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['and'] = ''; App::$strings[', and %d other people'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['%s like this.'] = ''; App::$strings["%s don't like this."] = ''; @@ -2626,28 +2626,28 @@ App::$strings['Find shareable objects (Zot)'] = ''; App::$strings['Post to Collections'] = ''; App::$strings['articles'] = ''; App::$strings['__ctx:noun__ Attending'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Not Attending'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Undecided'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Agree'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Disagree'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['__ctx:noun__ Abstain'] = [ - 0 => '', - 1 => '', + 0 => '', + 1 => '', ]; App::$strings['Source channel not found.'] = ''; App::$strings['Focus (Hubzilla default)'] = ''; diff --git a/util/typo.php b/util/typo.php index 41475e050..ccd004dfb 100644 --- a/util/typo.php +++ b/util/typo.php @@ -1,84 +1,86 @@