X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=windowsphonepush%2Fwindowsphonepush.php;h=8f289d124a1a1b1a7435936bcb535f91903be84d;hb=1e60ac18cf6d7f776ee6460db7f083c03391de44;hp=3aaf1d3092e90434cf12eb25cd10bde10da3a8ae;hpb=ab0f359602052bc82035335cb47c3e40f2474141;p=friendica-addons.git diff --git a/windowsphonepush/windowsphonepush.php b/windowsphonepush/windowsphonepush.php index 3aaf1d30..8f289d12 100644 --- a/windowsphonepush/windowsphonepush.php +++ b/windowsphonepush/windowsphonepush.php @@ -29,10 +29,15 @@ use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; -use Friendica\Core\Addon; -use Friendica\Core\L10n; -use Friendica\Core\PConfig; +use Friendica\Core\Hook; +use Friendica\Core\Logger; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Model\User; +use Friendica\Network\HTTPException\UnauthorizedException; function windowsphonepush_install() { @@ -40,29 +45,17 @@ function windowsphonepush_install() * The first is within cron - so the push notifications will be * sent every 10 minutes (or whatever is set in crontab). */ - Addon::registerHook('cron', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_cron'); + Hook::register('cron', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_cron'); /* Then we'll attach into the addon settings page, and also the * settings post hook so that we can create and update * user preferences. User shall be able to activate the addon and * define whether he allows pushing first characters of item text */ - Addon::registerHook('addon_settings', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings'); - Addon::registerHook('addon_settings_post', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings_post'); + Hook::register('addon_settings', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings'); + Hook::register('addon_settings_post', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings_post'); - logger("installed windowsphonepush"); -} - -function windowsphonepush_uninstall() -{ - /* uninstall unregisters any hooks created with register_hook - * during install. Don't delete data in table `pconfig`. - */ - Addon::unregisterHook('cron', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_cron'); - Addon::unregisterHook('addon_settings', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings'); - Addon::unregisterHook('addon_settings_post', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings_post'); - - logger("removed windowsphonepush"); + Logger::notice("installed windowsphonepush"); } /* declare the windowsphonepush function so that /windowsphonepush url requests will land here */ @@ -78,66 +71,44 @@ function windowsphonepush_module() */ function windowsphonepush_settings_post($a, $post) { - if (!local_user() || (!x($_POST, 'windowsphonepush-submit'))) { + if (!local_user() || empty($_POST['windowsphonepush-submit'])) { return; } $enable = intval($_POST['windowsphonepush']); - PConfig::set(local_user(), 'windowsphonepush', 'enable', $enable); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'enable', $enable); if ($enable) { - PConfig::set(local_user(), 'windowsphonepush', 'counterunseen', 0); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'counterunseen', 0); } - PConfig::set(local_user(), 'windowsphonepush', 'senditemtext', intval($_POST['windowsphonepush-senditemtext'])); - - info(L10n::t('WindowsPhonePush settings updated.') . EOL); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'senditemtext', intval($_POST['windowsphonepush-senditemtext'])); } /* Called from the Addon Setting form. * Add our own settings info to the page. */ -function windowsphonepush_settings(&$a, &$s) +function windowsphonepush_settings(App &$a, array &$data) { if (!local_user()) { return; } - /* Add our stylesheet to the page so we can make our settings look nice */ - $a->page['htmlhead'] .= '' . "\r\n"; - - /* Get the current state of our config variables */ - $enabled = PConfig::get(local_user(), 'windowsphonepush', 'enable'); - $checked_enabled = (($enabled) ? ' checked="checked" ' : ''); - - $senditemtext = PConfig::get(local_user(), 'windowsphonepush', 'senditemtext'); - $checked_senditemtext = (($senditemtext) ? ' checked="checked" ' : ''); - - $device_url = PConfig::get(local_user(), 'windowsphonepush', 'device_url'); - - /* Add some HTML to the existing form */ - $s .= '
'; - $s .= '

' . L10n::t('WindowsPhonePush Settings') . '

'; - - $s .= '
'; - $s .= ''; - $s .= ''; - $s .= '
'; - - $s .= '
'; - $s .= ''; - $s .= ''; - $s .= '
'; - - /* provide a submit button - enable und senditemtext can be changed by the user */ - $s .= '
'; - - /* provide further read-only information concerning the addon (useful for */ - $s .= '
'; - $s .= ''; - $s .= ''; - $s .= '
'; - - return; + $enabled = DI::pConfig()->get(local_user(), 'windowsphonepush', 'enable'); + $senditemtext = DI::pConfig()->get(local_user(), 'windowsphonepush', 'senditemtext'); + $device_url = DI::pConfig()->get(local_user(), 'windowsphonepush', 'device_url'); + + $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/windowsphonepush/'); + $html = Renderer::replaceMacros($t, [ + '$enabled' => ['windowsphonepush', DI::l10n()->t('Enable WindowsPhonePush Addon'), $enabled], + '$senditemtext' => ['windowsphonepush-senditemtext', DI::l10n()->t('Push text of new item'), $senditemtext], + '$device_url' => ['', DI::l10n()->t('Device URL'), $device_url, '', false, ' readonly'], + ]); + + $data = [ + 'addon' => 'windowsphonepush', + 'title' => DI::l10n()->t('WindowsPhonePush Settings'), + 'html' => $html, + ]; } /* Cron function used to regularly check all users on the server with active windowsphonepushaddon and send @@ -146,90 +117,88 @@ function windowsphonepush_settings(&$a, &$s) function windowsphonepush_cron() { // retrieve all UID's for which the addon windowsphonepush is enabled and loop through every user - $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'windowsphonepush' AND `k` = 'enable' AND `v` = 1"); - if (count($r)) { - foreach ($r as $rr) { - // load stored information for the user-id of the current loop - $device_url = PConfig::get($rr['uid'], 'windowsphonepush', 'device_url'); - $lastpushid = PConfig::get($rr['uid'], 'windowsphonepush', 'lastpushid'); - - // pushing only possible if device_url (the URI on Microsoft server) is available or not "NA" (which will be sent - // by app if user has switched the server setting in app - sending blank not possible as this would return an update error) - if (( $device_url == "" ) || ( $device_url == "NA" )) { - // no Device-URL for the user availabe, but addon is enabled --> write info to Logger - logger("WARN: windowsphonepush is enable for user " . $rr['uid'] . ", but no Device-URL is specified for the user."); - } else { - // retrieve the number of unseen items and the id of the latest one (if there are more than - // one new entries since last poller run, only the latest one will be pushed) - $count = q("SELECT count(`id`) as count, max(`id`) as max FROM `item` WHERE `unseen` = 1 AND `type` <> 'activity' AND `uid` = %d", intval($rr['uid'])); - - // send number of unseen items to the device (the number will be displayed on Start screen until - // App will be started by user) - this update will be sent every 10 minutes to update the number to 0 if - // user has loaded the timeline through app or website - $res_tile = send_tile_update($device_url, "", $count[0]['count'], ""); - switch (trim($res_tile)) { - case "Received": - // ok, count has been pushed, let's save it in personal settings - PConfig::set($rr['uid'], 'windowsphonepush', 'counterunseen', $count[0]['count']); - break; - case "QueueFull": - // maximum of 30 messages reached, server rejects any further push notification until device reconnects - logger("INFO: Device-URL '" . $device_url . "' returns a QueueFull."); - break; - case "Suppressed": - // notification received and dropped as something in app was not enabled - logger("WARN. Device-URL '" . $device_url . "' returns a Suppressed. Unexpected error in Mobile App?"); - break; - case "Dropped": - // mostly combines with Expired, in that case Device-URL will be deleted from pconfig (function send_push) - break; - default: - // error, mostly called by "" which means that the url (not "" which has been checked) - // didn't not received Microsoft Notification Server -> wrong url - logger("ERROR: specified Device-URL '" . $device_url . "' didn't produced any response."); - } + $pconfigs = DBA::selectToArray('pconfig', ['uid'], ['cat' => 'windowsphonepush', 'k' => 'enable', 'v' => true]); + foreach ($pconfigs as $rr) { + // load stored information for the user-id of the current loop + $device_url = DI::pConfig()->get($rr['uid'], 'windowsphonepush', 'device_url'); + $lastpushid = DI::pConfig()->get($rr['uid'], 'windowsphonepush', 'lastpushid'); + + // pushing only possible if device_url (the URI on Microsoft server) is available or not "NA" (which will be sent + // by app if user has switched the server setting in app - sending blank not possible as this would return an update error) + if (( $device_url == "" ) || ( $device_url == "NA" )) { + // no Device-URL for the user availabe, but addon is enabled --> write info to Logger + Logger::notice("WARN: windowsphonepush is enable for user " . $rr['uid'] . ", but no Device-URL is specified for the user."); + } else { + // retrieve the number of unseen items and the id of the latest one (if there are more than + // one new entries since last poller run, only the latest one will be pushed) + $count = DBA::fetchFirst("SELECT count(`id`) AS count, max(`id`) AS max FROM `post-view` WHERE `unseen` AND `type` != ? AND `uid` = ?", 'activity', $rr['uid']); + + // send number of unseen items to the device (the number will be displayed on Start screen until + // App will be started by user) - this update will be sent every 10 minutes to update the number to 0 if + // user has loaded the timeline through app or website + $res_tile = send_tile_update($device_url, "", $count['count'], ""); + switch (trim($res_tile)) { + case "Received": + // ok, count has been pushed, let's save it in personal settings + DI::pConfig()->set($rr['uid'], 'windowsphonepush', 'counterunseen', $count['count']); + break; + case "QueueFull": + // maximum of 30 messages reached, server rejects any further push notification until device reconnects + Logger::notice("INFO: Device-URL '" . $device_url . "' returns a QueueFull."); + break; + case "Suppressed": + // notification received and dropped as something in app was not enabled + Logger::notice("WARN. Device-URL '" . $device_url . "' returns a Suppressed. Unexpected error in Mobile App?"); + break; + case "Dropped": + // mostly combines with Expired, in that case Device-URL will be deleted from pconfig (function send_push) + break; + default: + // error, mostly called by "" which means that the url (not "" which has been checked) + // didn't not received Microsoft Notification Server -> wrong url + Logger::notice("ERROR: specified Device-URL '" . $device_url . "' didn't produced any response."); + } - // additionally user receives the text of the newest item (function checks against last successfully pushed item) - if (intval($count[0]['max']) > intval($lastpushid)) { - // user can define if he wants to see the text of the item in the push notification - // this has been implemented as the device_url is not a https uri (not so secure) - $senditemtext = PConfig::get($rr['uid'], 'windowsphonepush', 'senditemtext'); - if ($senditemtext == 1) { - // load item with the max id - $item = q("SELECT `author-name` as author, `body` as body FROM `item` where `id` = %d", intval($count[0]['max'])); - - // as user allows to send the item, we want to show the sender of the item in the toast - // toasts are limited to one line, therefore place is limited - author shall be in - // max. 15 chars (incl. dots); author is displayed in bold font - $author = $item[0]['author']; - $author = ((strlen($author) > 12) ? substr($author, 0, 12) . "..." : $author); - - // normally we show the body of the item, however if it is an url or an image we cannot - // show this in the toast (only test), therefore changing to an alternate text - // Otherwise BBcode-Tags will be eliminated and plain text cutted to 140 chars (incl. dots) - // BTW: information only possible in English - $body = $item[0]['body']; - if (substr($body, 0, 4) == "[url") { - $body = "URL/Image ..."; - } else { - $body = BBCode::convert($body, false, 2, true); - $body = HTML::toPlaintext($body, 0); - $body = ((strlen($body) > 137) ? substr($body, 0, 137) . "..." : $body); - } + // additionally user receives the text of the newest item (function checks against last successfully pushed item) + if (intval($count['max']) > intval($lastpushid)) { + // user can define if he wants to see the text of the item in the push notification + // this has been implemented as the device_url is not a https uri (not so secure) + $senditemtext = DI::pConfig()->get($rr['uid'], 'windowsphonepush', 'senditemtext'); + if ($senditemtext == 1) { + // load item with the max id + $item = Post::selectFirst(['author-name', 'body', 'uri-id'], ['id' => $count['max']]); + + // as user allows to send the item, we want to show the sender of the item in the toast + // toasts are limited to one line, therefore place is limited - author shall be in + // max. 15 chars (incl. dots); author is displayed in bold font + $author = $item['author-name']; + $author = ((strlen($author) > 12) ? substr($author, 0, 12) . "..." : $author); + + // normally we show the body of the item, however if it is an url or an image we cannot + // show this in the toast (only test), therefore changing to an alternate text + // Otherwise BBcode-Tags will be eliminated and plain text cutted to 140 chars (incl. dots) + // BTW: information only possible in English + $body = $item['body']; + if (substr($body, 0, 4) == "[url") { + $body = "URL/Image ..."; } else { - // if user wishes higher privacy, we only display "Friendica - New timeline entry arrived" - $author = "Friendica"; - $body = "New timeline entry arrived ..."; - } - // only if toast push notification returns the Notification status "Received" we will update th settings with the - // new indicator max-id is checked against (QueueFull, Suppressed, N/A, Dropped shall qualify to resend - // the push notification some minutes later (BTW: if resulting in Expired for subscription status the - // device_url will be deleted (no further try on this url, see send_push) - // further log information done on count pushing with send_tile (see above) - $res_toast = send_toast($device_url, $author, $body); - if (trim($res_toast) === 'Received') { - PConfig::set($rr['uid'], 'windowsphonepush', 'lastpushid', $count[0]['max']); + $body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::API); + $body = HTML::toPlaintext($body, 0); + $body = ((strlen($body) > 137) ? substr($body, 0, 137) . "..." : $body); } + } else { + // if user wishes higher privacy, we only display "Friendica - New timeline entry arrived" + $author = "Friendica"; + $body = "New timeline entry arrived ..."; + } + // only if toast push notification returns the Notification status "Received" we will update th settings with the + // new indicator max-id is checked against (QueueFull, Suppressed, N/A, Dropped shall qualify to resend + // the push notification some minutes later (BTW: if resulting in Expired for subscription status the + // device_url will be deleted (no further try on this url, see send_push) + // further log information done on count pushing with send_tile (see above) + $res_toast = send_toast($device_url, $author, $body); + if (trim($res_toast) === 'Received') { + DI::pConfig()->set($rr['uid'], 'windowsphonepush', 'lastpushid', $count['max']); } } } @@ -302,8 +271,8 @@ function send_push($device_url, $headers, $msg) // and log this fact $subscriptionStatus = get_header_value($output, 'X-SubscriptionStatus'); if ($subscriptionStatus == "Expired") { - PConfig::set(local_user(), 'windowsphonepush', 'device_url', ""); - logger("ERROR: the stored Device-URL " . $device_url . "returned an 'Expired' error, it has been deleted now."); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'device_url', ""); + Logger::notice("ERROR: the stored Device-URL " . $device_url . "returned an 'Expired' error, it has been deleted now."); } // the notification status shall be returned to windowsphonepush_cron (will @@ -328,25 +297,25 @@ function windowsphonepush_content(App $a) // Login with the specified Network credentials (like in api.php) windowsphonepush_login($a); - $path = $a->argv[0]; - $path2 = $a->argv[1]; + $path = DI::args()->getArgv()[0]; + $path2 = DI::args()->getArgv()[1]; if ($path == "windowsphonepush") { switch ($path2) { case "show_settings": windowsphonepush_showsettings($a); - killme(); + exit(); break; case "update_settings": $ret = windowsphonepush_updatesettings($a); header("Content-Type: application/json; charset=utf-8"); echo json_encode(['status' => $ret]); - killme(); + exit(); break; case "update_counterunseen": $ret = windowsphonepush_updatecounterunseen(); header("Content-Type: application/json; charset=utf-8"); echo json_encode(['status' => $ret]); - killme(); + exit(); break; default: echo "Fehler"; @@ -361,11 +330,11 @@ function windowsphonepush_showsettings() return; } - $enable = PConfig::get(local_user(), 'windowsphonepush', 'enable'); - $device_url = PConfig::get(local_user(), 'windowsphonepush', 'device_url'); - $senditemtext = PConfig::get(local_user(), 'windowsphonepush', 'senditemtext'); - $lastpushid = PConfig::get(local_user(), 'windowsphonepush', 'lastpushid'); - $counterunseen = PConfig::get(local_user(), 'windowsphonepush', 'counterunseen'); + $enable = DI::pConfig()->get(local_user(), 'windowsphonepush', 'enable'); + $device_url = DI::pConfig()->get(local_user(), 'windowsphonepush', 'device_url'); + $senditemtext = DI::pConfig()->get(local_user(), 'windowsphonepush', 'senditemtext'); + $lastpushid = DI::pConfig()->get(local_user(), 'windowsphonepush', 'lastpushid'); + $counterunseen = DI::pConfig()->get(local_user(), 'windowsphonepush', 'counterunseen'); $addonversion = "2.0"; if (!$device_url) { @@ -396,7 +365,7 @@ function windowsphonepush_updatesettings() } // no updating if user hasn't enabled the addon - $enable = PConfig::get(local_user(), 'windowsphonepush', 'enable'); + $enable = DI::pConfig()->get(local_user(), 'windowsphonepush', 'enable'); if (!$enable) { return "Plug-in not enabled"; } @@ -404,7 +373,7 @@ function windowsphonepush_updatesettings() // check if sent url is empty - don't save and send return code to app $device_url = $_POST['deviceurl']; if ($device_url == "") { - logger("ERROR: no valid Device-URL specified - client transferred '" . $device_url . "'"); + Logger::notice("ERROR: no valid Device-URL specified - client transferred '" . $device_url . "'"); return "No valid Device-URL specified"; } @@ -412,20 +381,15 @@ function windowsphonepush_updatesettings() // the user on the Windows Phone device and that device url is no longer true for the other user, so we // et the device_url for the OTHER user blank (should normally not occur as App should include User/server // in url request to Microsoft Push Notification server) - $r = q("SELECT * FROM `pconfig` WHERE `uid` <> " . local_user() . " AND - `cat` = 'windowsphonepush' AND - `k` = 'device_url' AND - `v` = '" . $device_url . "'"); - if (count($r)) { - foreach ($r as $rr) { - PConfig::set($rr['uid'], 'windowsphonepush', 'device_url', ''); - logger("WARN: the sent URL was already registered with user '" . $rr['uid'] . "'. Deleted for this user as we expect to be correct now for user '" . local_user() . "'."); - } + $pconfigs = DBA::selectToArray('pconfig', ['uid'], ["`uid` != ? AND `cat` = ? AND `k` = ? AND `v` = ?", local_user(), 'windowsphonepush', 'device_url', $device_url]); + foreach ($pconfigs as $rr) { + DI::pConfig()->set($rr['uid'], 'windowsphonepush', 'device_url', ''); + Logger::notice("WARN: the sent URL was already registered with user '" . $rr['uid'] . "'. Deleted for this user as we expect to be correct now for user '" . local_user() . "'."); } - PConfig::set(local_user(), 'windowsphonepush', 'device_url', $device_url); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'device_url', $device_url); // output the successfull update of the device URL to the logger for error analysis if necessary - logger("INFO: Device-URL for user '" . local_user() . "' has been updated with '" . $device_url . "'"); + Logger::notice("INFO: Device-URL for user '" . local_user() . "' has been updated with '" . $device_url . "'"); return "Device-URL updated successfully!"; } @@ -437,12 +401,12 @@ function windowsphonepush_updatecounterunseen() } // no updating if user hasn't enabled the addon - $enable = PConfig::get(local_user(), 'windowsphonepush', 'enable'); + $enable = DI::pConfig()->get(local_user(), 'windowsphonepush', 'enable'); if (!$enable) { return "Plug-in not enabled"; } - PConfig::set(local_user(), 'windowsphonepush', 'counterunseen', 0); + DI::pConfig()->set(local_user(), 'windowsphonepush', 'counterunseen', 0); return "Counter set to zero"; } @@ -452,25 +416,20 @@ function windowsphonepush_updatecounterunseen() function windowsphonepush_login(App $a) { if (!isset($_SERVER['PHP_AUTH_USER'])) { - logger('API_login: ' . print_r($_SERVER, true), LOGGER_DEBUG); + Logger::info('API_login: ' . print_r($_SERVER, true)); header('WWW-Authenticate: Basic realm="Friendica"'); - header('HTTP/1.0 401 Unauthorized'); - die('This api requires login'); + throw new UnauthorizedException('This api requires login'); } - $user_id = User::authenticate($_SERVER['PHP_AUTH_USER'], trim($_SERVER['PHP_AUTH_PW'])); - - if ($user_id) { - $record = dba::selectFirst('user', [], ['uid' => $user_id]); - } else { - logger('API_login failure: ' . print_r($_SERVER, true), LOGGER_DEBUG); + try { + $user_id = User::getIdFromPasswordAuthentication($_SERVER['PHP_AUTH_USER'], trim($_SERVER['PHP_AUTH_PW'])); + $record = DBA::selectFirst('user', [], ['uid' => $user_id]); + DI::auth()->setForUser($a, $record); + DI::session()->set('allow_api', true); + Hook::callAll('logged_in', $record); + } catch (Exception $ex) { + Logger::info('API_login failure: ' . print_r($_SERVER, true)); header('WWW-Authenticate: Basic realm="Friendica"'); - header('HTTP/1.0 401 Unauthorized'); - die('This api requires login'); + throw new UnauthorizedException('This api requires login'); } - - require_once 'include/security.php'; - authenticate_success($record); - $_SESSION["allow_api"] = true; - Addon::callHooks('logged_in', $a->user); }