diff --git a/assets/src/js/share-story.js b/assets/src/js/share-story.js new file mode 100644 index 000000000..00aed11c6 --- /dev/null +++ b/assets/src/js/share-story.js @@ -0,0 +1,24 @@ +(function($) { + + $( document ).ready( function() { + + // Copy the url + + var merge_tag_clipboard = new Clipboard( '#notification-story code' ); + + merge_tag_clipboard.on( 'success', function(e) { + + var $code = $( e.trigger ), + copy_text = $code.find( 'span' ).text(); + + $code.find( 'span' ).text( notification.i18n.copied ); + + setTimeout( function() { + $code.find( 'span' ).text( copy_text ); + }, 800 ); + + } ); + + } ); + +})(jQuery); diff --git a/assets/src/sass/partials/_admin-story.scss b/assets/src/sass/partials/_admin-story.scss new file mode 100644 index 000000000..b4af93bc6 --- /dev/null +++ b/assets/src/sass/partials/_admin-story.scss @@ -0,0 +1,93 @@ +/** + * The story styles + */ + +.notification_page_the-story #wpcontent { + padding-right: 10px; +} + +#notification-story { + max-width: 600px; + margin: 80px auto 0 auto; + + h1 { + font-size: 3rem; + color: #696969; + line-height: 3rem; + } + + p { + font-size: 1.1rem; + } + + .founder { + margin-top: 2rem; + + img { + float: left; + border-radius: 80px; + margin-right: 20px; + } + + .name { + padding-top: 20px; + font-size: 1.1rem; + font-weight: 500; + } + + } + + .skip { + clear: both; + padding-top: 1rem; + text-align: center; + + a { + color: #a0a0a0; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + } + + } + + code { + font-size: 1.1rem; + position: relative; + padding: 6px 10px; + cursor: pointer; + white-space: nowrap; + max-width: 100%; + + span { + display: none; + position: absolute; + right: -60px; + top: 3px; + font-size: 1rem; + background: #797979; + padding: 4px 4px; + line-height: 1rem; + border-radius: 5px; + color: white; + } + + &:hover span { + display: block; + } + + @media (max-width: 782px) { + overflow-x: auto; + display: block; + + span { + display: none; + } + } + + } + +} diff --git a/assets/src/sass/style.scss b/assets/src/sass/style.scss index d496b9a9c..914faec17 100644 --- a/assets/src/sass/style.scss +++ b/assets/src/sass/style.scss @@ -22,3 +22,4 @@ @import 'partials/settings'; @import 'partials/notifications-table'; @import 'partials/help'; +@import 'partials/admin-story'; diff --git a/class/Abstracts/MergeTag.php b/class/Abstracts/MergeTag.php index 152d33d40..dfd141ab0 100644 --- a/class/Abstracts/MergeTag.php +++ b/class/Abstracts/MergeTag.php @@ -83,13 +83,10 @@ public function __construct( $params = array() ) { trigger_error( 'Merge tag requires slug, name and resolver', E_USER_ERROR ); } - if ( ! is_callable( $params['resolver'] ) ) { - trigger_error( 'Merge tag resolver has to be callable', E_USER_ERROR ); - } + $this->slug = $params['slug']; + $this->name = $params['name']; - $this->slug = $params['slug']; - $this->name = $params['name']; - $this->resolver = $params['resolver']; + $this->set_resolver( $params['resolver'] ); if ( isset( $params['description'] ) ) { $this->description_example = isset( $params['example'] ) && $params['example']; @@ -203,6 +200,22 @@ public function set_trigger( Interfaces\Triggerable $trigger ) { $this->trigger = $trigger; } + /** + * Sets resolver function + * + * @since 5.2.2 + * @param mixed $resolver Resolver, can be either a closure or array or string. + */ + public function set_resolver( $resolver ) { + + if ( ! is_callable( $resolver ) ) { + trigger_error( 'Merge tag resolver has to be callable', E_USER_ERROR ); + } + + $this->resolver = $resolver; + + } + /** * Gets trigger object * @@ -236,7 +249,7 @@ public function is_hidden() { /** * Cleans the value * - * @since [Next] + * @since 5.2.2 * @return void */ public function clean_value() { diff --git a/class/Abstracts/Trigger.php b/class/Abstracts/Trigger.php index 0ee7093e4..cd33e2e98 100644 --- a/class/Abstracts/Trigger.php +++ b/class/Abstracts/Trigger.php @@ -281,7 +281,7 @@ private function resolve_fields() { /** * Cleans the merge tags. * - * @since [Next] + * @since 5.2.2 * @return void */ private function clean_merge_tags() { diff --git a/class/Admin/FieldsResolver.php b/class/Admin/FieldsResolver.php index 03ba520c5..2eef68ce5 100644 --- a/class/Admin/FieldsResolver.php +++ b/class/Admin/FieldsResolver.php @@ -129,7 +129,9 @@ public function resolve_match( $matches ) { return ''; } - return $this->merge_tags[ $tag_slug ]->resolve(); + $resolved = apply_filters( 'notificaiton/merge_tag/value/resolved', $this->merge_tags[ $tag_slug ]->resolve(), $this->merge_tags[ $tag_slug ] ); + + return $resolved; } diff --git a/class/Admin/Scripts.php b/class/Admin/Scripts.php index 097603ed1..3ea85e9c3 100644 --- a/class/Admin/Scripts.php +++ b/class/Admin/Scripts.php @@ -53,6 +53,7 @@ public function enqueue_scripts( $page_hook ) { $allowed_hooks = array( $this->runtime->admin_extensions->page_hook, $this->runtime->settings->page_hook, + $this->runtime->admin_share->page_hook, 'plugins.php', 'post-new.php', 'post.php' diff --git a/class/Admin/Settings.php b/class/Admin/Settings.php index a006455d2..94c96b7e5 100644 --- a/class/Admin/Settings.php +++ b/class/Admin/Settings.php @@ -300,6 +300,13 @@ public function triggers_settings( $settings ) { */ public function notifications_settings( $settings ) { + $sitename = strtolower( $_SERVER['SERVER_NAME'] ); + if ( substr( $sitename, 0, 4 ) == 'www.' ) { + $sitename = substr( $sitename, 4 ); + } + + $default_from_email = 'wordpress@' . $sitename; + $notifications = $settings->add_section( __( 'Notifications', 'notification' ), 'notifications' ); $notifications->add_group( __( 'Email', 'notification' ), 'email' ) @@ -325,6 +332,22 @@ public function notifications_settings( $settings ) { ), 'render' => array( new CoreFields\Select(), 'input' ), 'sanitize' => array( new CoreFields\Select(), 'sanitize' ), + ) ) + ->add_field( array( + 'name' => __( 'From Name', 'notification' ), + 'slug' => 'from_name', + 'default' => '', + 'render' => array( new CoreFields\Text(), 'input' ), + 'sanitize' => array( new CoreFields\Text(), 'sanitize' ), + 'description' => sprintf( __( 'Leave blank to use default value: %s', 'notification' ), 'WordPress' ), + ) ) + ->add_field( array( + 'name' => __( 'From Email', 'notification' ), + 'slug' => 'from_email', + 'default' => '', + 'render' => array( new CoreFields\Text(), 'input' ), + 'sanitize' => array( new CoreFields\Text(), 'sanitize' ), + 'description' => sprintf( __( 'Leave blank to use default value: %s', 'notification' ), '' . $default_from_email . '' ), ) ); $notifications->add_group( __( 'Webhook', 'notification' ), 'webhook' ) diff --git a/class/Admin/Share.php b/class/Admin/Share.php new file mode 100644 index 000000000..213194a32 --- /dev/null +++ b/class/Admin/Share.php @@ -0,0 +1,106 @@ +view = $view; + } + + /** + * Register Share page under plugin's menu. + * + * @action admin_menu 30 + * + * @return void + */ + public function register_page() { + + if ( ! notification_display_story() || isset( $_GET['notification-story-skip'] ) ) { + return; + } + + $this->page_hook = add_submenu_page( + 'edit.php?post_type=notification', + '', + __( 'The story', 'notification' ), + 'manage_options', + 'the-story', + array( $this, 'story_page' ) + ); + + } + + /** + * Redirects the user to story screen. + * + * @action current_screen + * + * @return void + */ + public function maybe_redirect() { + + if ( ! notification_display_story() ) { + return; + } + + $screen = get_current_screen(); + + if ( isset( $screen->post_type ) && $screen->post_type == 'notification' && $screen->id != 'notification_page_the-story' ) { + wp_safe_redirect( admin_url( 'edit.php?post_type=notification&page=the-story' ) ); + exit; + } + + } + + /** + * Saves the dismiss action in the options. + * + * @action admin_init + * + * @return void + */ + public function dismiss_story() { + + if ( isset( $_GET['notification-story-skip'] ) ) { + update_option( 'notification_story_dismissed', true ); + } + + } + + /** + * Displays the Story page. + * + * @return void + */ + public function story_page() { + + $this->view->get_view( 'story' ); + + } + +} diff --git a/class/Defaults/MergeTag/Taxonomy/TaxonomyName.php b/class/Defaults/MergeTag/Taxonomy/TaxonomyName.php index d3ebde225..b6d7ddca7 100644 --- a/class/Defaults/MergeTag/Taxonomy/TaxonomyName.php +++ b/class/Defaults/MergeTag/Taxonomy/TaxonomyName.php @@ -28,7 +28,7 @@ class TaxonomyName extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 * @param array $params merge tag configuration params. */ public function __construct( $params = array() ) { @@ -65,7 +65,7 @@ public function check_requirements() { /** * Gets nice, translated taxonomy name * - * @since [Next] + * @since 5.2.2 * @return string taxonomy nicename */ public function get_nicename() { diff --git a/class/Defaults/MergeTag/Taxonomy/TaxonomySlug.php b/class/Defaults/MergeTag/Taxonomy/TaxonomySlug.php index 23a6ded61..9f339ced6 100644 --- a/class/Defaults/MergeTag/Taxonomy/TaxonomySlug.php +++ b/class/Defaults/MergeTag/Taxonomy/TaxonomySlug.php @@ -28,7 +28,7 @@ class TaxonomySlug extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 * @param array $params merge tag configuration params. */ public function __construct( $params = array() ) { diff --git a/class/Defaults/MergeTag/Taxonomy/TermDescription.php b/class/Defaults/MergeTag/Taxonomy/TermDescription.php index a8a94ad8a..0e59e196b 100644 --- a/class/Defaults/MergeTag/Taxonomy/TermDescription.php +++ b/class/Defaults/MergeTag/Taxonomy/TermDescription.php @@ -21,7 +21,7 @@ class TermDescription extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 */ public function __construct() { diff --git a/class/Defaults/MergeTag/Taxonomy/TermID.php b/class/Defaults/MergeTag/Taxonomy/TermID.php index 29cfdee45..f0393e8ad 100644 --- a/class/Defaults/MergeTag/Taxonomy/TermID.php +++ b/class/Defaults/MergeTag/Taxonomy/TermID.php @@ -21,7 +21,7 @@ class TermID extends IntegerTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 */ public function __construct() { diff --git a/class/Defaults/MergeTag/Taxonomy/TermName.php b/class/Defaults/MergeTag/Taxonomy/TermName.php index c819aa8d6..81327ebeb 100644 --- a/class/Defaults/MergeTag/Taxonomy/TermName.php +++ b/class/Defaults/MergeTag/Taxonomy/TermName.php @@ -21,7 +21,7 @@ class TermName extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 */ public function __construct() { diff --git a/class/Defaults/MergeTag/Taxonomy/TermSlug.php b/class/Defaults/MergeTag/Taxonomy/TermSlug.php index 6aa0f4a42..a9e776d1c 100644 --- a/class/Defaults/MergeTag/Taxonomy/TermSlug.php +++ b/class/Defaults/MergeTag/Taxonomy/TermSlug.php @@ -21,7 +21,7 @@ class TermSlug extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 */ public function __construct() { diff --git a/class/Defaults/MergeTag/User/UserPasswordResetLink.php b/class/Defaults/MergeTag/User/UserPasswordResetLink.php index 9f47a395c..4c02bd956 100644 --- a/class/Defaults/MergeTag/User/UserPasswordResetLink.php +++ b/class/Defaults/MergeTag/User/UserPasswordResetLink.php @@ -35,7 +35,7 @@ class UserPasswordResetLink extends StringTag { /** * Merge tag constructor * - * @since [Next] + * @since 5.2.2 */ public function __construct() { diff --git a/class/Defaults/Trigger/Post/PostTrigger.php b/class/Defaults/Trigger/Post/PostTrigger.php index 6682791f3..ff30be946 100644 --- a/class/Defaults/Trigger/Post/PostTrigger.php +++ b/class/Defaults/Trigger/Post/PostTrigger.php @@ -78,6 +78,21 @@ public function merge_tags() { 'post_type' => $this->post_type, ) ) ); + if ( $this->post_type == 'post' ) { + $this->add_merge_tag( new MergeTag\StringTag( array( + 'slug' => $this->post_type . '_sticky', + // translators: singular post name. + 'name' => sprintf( __( '%s sticky status', 'notification' ), $post_name ), + 'resolver' => function( $trigger ) { + if ( is_admin() ) { + return isset( $_POST['sticky'] ) && ! empty( $_POST['sticky'] ) ? __( 'Sticky', 'notification' ) : __( 'Not sticky', 'notification' ); + } else { + return is_sticky( $trigger->{ $this->post_type }->ID ) ? __( 'Sticky', 'notification' ) : __( 'Not sticky', 'notification' ); + } + }, + ) ) ); + } + $taxonomies = get_object_taxonomies( $this->post_type, 'objects' ); if ( ! empty( $taxonomies ) ) { diff --git a/class/Defaults/Trigger/Post/PostUpdated.php b/class/Defaults/Trigger/Post/PostUpdated.php index 046c55a09..b6747f1c4 100644 --- a/class/Defaults/Trigger/Post/PostUpdated.php +++ b/class/Defaults/Trigger/Post/PostUpdated.php @@ -75,25 +75,6 @@ public function action( $post_id, $post, $post_before ) { } - /** - * Postponed action callback - * Return `false` if you want to abort the trigger execution - * - * @return mixed void or false if no notifications should be sent - */ - public function postponed_action() { - - if ( function_exists( 'acf' ) ) { - return; - } - - // fix for the action being called twice by WordPress. - if ( did_action( 'save_post' ) > 1 ) { - return false; - } - - } - /** * Registers attached merge tags * diff --git a/class/Defaults/Trigger/Taxonomy/TermTrigger.php b/class/Defaults/Trigger/Taxonomy/TermTrigger.php index 368914733..5a74729c8 100644 --- a/class/Defaults/Trigger/Taxonomy/TermTrigger.php +++ b/class/Defaults/Trigger/Taxonomy/TermTrigger.php @@ -61,7 +61,7 @@ public function merge_tags() { /** * Gets nice, translated taxonomy name * - * @since [Next] + * @since 5.2.2 * @return string taxonomy */ public function get_current_taxonomy_name() { @@ -71,7 +71,7 @@ public function get_current_taxonomy_name() { /** * Gets nice, translated taxonomy name for taxonomy slug * - * @since [Next] + * @since 5.2.2 * @param string $taxonomy taxonomy slug. * @return string taxonomy */ @@ -82,7 +82,7 @@ public static function get_taxonomy_name( $taxonomy ) { /** * Gets nice, translated singular taxonomy name for taxonomy slug * - * @since [Next] + * @since 5.2.2 * @param string $taxonomy taxonomy slug. * @return string taxonomy */ diff --git a/class/Integration/WordPress.php b/class/Integration/WordPress.php new file mode 100644 index 000000000..0781c5302 --- /dev/null +++ b/class/Integration/WordPress.php @@ -0,0 +1,49 @@ +admin_scripts = new Admin\Scripts( $this, $this->files ); $this->admin_screen = new Admin\ScreenHelp( $this->view() ); $this->admin_cron = new Admin\Cron(); + $this->admin_share = new Admin\Share( $this->view() ); + $this->integration_wp = new Integration\WordPress(); } @@ -94,6 +96,8 @@ public function actions() { $this->add_hooks( $this->admin_scripts ); $this->add_hooks( $this->admin_screen ); $this->add_hooks( $this->admin_cron ); + $this->add_hooks( $this->admin_share ); + $this->add_hooks( $this->integration_wp ); notification_register_settings( array( $this->settings, 'general_settings' ) ); notification_register_settings( array( $this->settings, 'triggers_settings' ), 20 ); diff --git a/inc/functions/general.php b/inc/functions/general.php index 88bd66d61..22ce3ccff 100644 --- a/inc/functions/general.php +++ b/inc/functions/general.php @@ -8,7 +8,7 @@ /** * Adds handlers for doc hooks to an object * - * @since [Next] + * @since 5.2.2 * @param object $object Object to create the hooks. * @return object */ @@ -17,3 +17,20 @@ function notification_add_doc_hooks( $object ) { $dochooks->add_hooks( $object ); return $object; } + +/** + * Checks if the story should be displayed. + * + * @since 5.2.2 + * @return boolean + */ +function notification_display_story() { + + $counter = wp_count_posts( 'notification' ); + $count = 0; + $count += isset( $counter->publish ) ? $counter->publish : 0; + $count += isset( $counter->draft ) ? $counter->draft : 0; + + return ! notification_is_whitelabeled() && ! get_option( 'notification_story_dismissed' ) && $count > 2; + +} diff --git a/notification.php b/notification.php index 91522bd06..47d8db1ab 100644 --- a/notification.php +++ b/notification.php @@ -4,7 +4,7 @@ * Description: Customisable email and webhook notifications with powerful developer friendly API for custom triggers and notifications. Send alerts easily. * Author: BracketSpace * Author URI: https://bracketspace.com - * Version: 5.2.1 + * Version: 5.2.2 * License: GPL3 * Text Domain: notification * Domain Path: /languages @@ -43,7 +43,7 @@ function notification_autoload( $class ) { * Requirements check */ $requirements = new BracketSpace\Notification\Utils\Requirements( __( 'Notification', 'notification' ), array( - 'php' => '5.3', + 'php' => '5.3.9', 'wp' => '4.6', 'function_collision' => array( 'register_trigger', 'register_notification' ), ) ); diff --git a/package.json b/package.json index 9326c2b47..b22f70f80 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,16 @@ "license": "ISC", "devDependencies": { "browser-sync": "^2.14.3", + "grunt": "^1.0.2", + "grunt-cli": "^1.2.0", + "grunt-contrib-compress": "^1.4.3", + "grunt-wp-i18n": "^1.0.1", + "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.1", "gulp-concat": "^2.6.0", "gulp-order": "^1.1.1", "gulp-sass": "^2.3.2", "gulp-sourcemaps": "^1.6.0", - "gulp-uglify": "^2.0.0", - "grunt": "^1.0.2", - "grunt-cli": "^1.2.0", - "grunt-contrib-compress": "^1.4.3", - "grunt-wp-i18n": "^1.0.1" + "gulp-uglify": "^2.0.0" } } diff --git a/readme.txt b/readme.txt index 9ff028861..5e109329e 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Donate link: https://www.paypal.me/underDEV/ Tags: notification, notify, alert, email, mail, webhook, API, developer, framework Requires at least: 4.6 Tested up to: 4.9.5 -Stable tag: 5.2.1 +Stable tag: 5.2.2 Requires PHP: 5.3 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -209,6 +209,15 @@ Yes, you can. [See the detailed guide](https://docs.bracketspace.com/docs/includ == Changelog == += [Next] = +* [Fixed] Post Updated Trigger postponing. +* [Added] `notificaiton/merge_tag/value/resolved` filter. +* [Added] `post_sticky` status Merge Tag only for Post. +* [Added] Email From Name and From Email settings. +* [Added] The story screen. +* [Changed] Merge Tag resolver is now set via `set_resolver` method. +* [Changed] PHP version requirement to 5.3.9. + = 5.2.1 = * [Fixed] Not existing post type. * [Fixed] Merge tag values are cleaned when Trigger is executed second time in the same run. diff --git a/tests/core/test-main.php b/tests/core/test-main.php new file mode 100644 index 000000000..bd0bfa39c --- /dev/null +++ b/tests/core/test-main.php @@ -0,0 +1,59 @@ +notification = notification_runtime(); + } + + /** + * Test Runtime instance + * + * @since [Next] + */ + public function test_runtime() { + $this->assertInstanceOf( 'BracketSpace\Notification\Runtime', $this->notification ); + } + + /** + * Test boot method + * + * @since [Next] + */ + public function test_boot() { + + // Instances. + $this->assertInstanceOf( 'BracketSpace\Notification\Utils\View', $this->notification->view() ); + $this->assertInstanceOf( 'BracketSpace\Notification\Utils\Ajax', $this->notification->ajax() ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\BoxRenderer', $this->notification->boxrenderer() ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\FormRenderer', $this->notification->formrenderer() ); + $this->assertInstanceOf( 'BracketSpace\Notification\Utils\Files', $this->notification->files ); + $this->assertInstanceOf( 'BracketSpace\Notification\Internationalization', $this->notification->internationalization ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Settings', $this->notification->settings ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\PostData', $this->notification->post_data ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Trigger', $this->notification->admin_trigger ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Notifications', $this->notification->admin_notifications ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\PostType', $this->notification->admin_post_type ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\PostTable', $this->notification->admin_post_table ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\MergeTags', $this->notification->admin_merge_tags ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Scripts', $this->notification->admin_scripts ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Recipients', $this->notification->admin_recipients ); + $this->assertInstanceOf( 'BracketSpace\Notification\Admin\Extensions', $this->notification->admin_extensions ); + + } + +} diff --git a/tests/test-sample.php b/tests/test-sample.php deleted file mode 100644 index a784834a1..000000000 --- a/tests/test-sample.php +++ /dev/null @@ -1,20 +0,0 @@ -assertTrue( true ); - } -} diff --git a/uninstall.php b/uninstall.php index d6301f81d..fbd6e7268 100644 --- a/uninstall.php +++ b/uninstall.php @@ -56,3 +56,6 @@ delete_option( 'notification_licenses' ); } + +// remove other things. +delete_option( 'notification_story_dismissed' ); diff --git a/views/story.php b/views/story.php new file mode 100644 index 000000000..f9dfa97ea --- /dev/null +++ b/views/story.php @@ -0,0 +1,38 @@ + + +
+ +

Wait a moment...

+ +

+ +

+ +

+ +

+ +

+ +

https://wordpress.org/plugins/notification/

+ +

+ +
+ +
Jakub Mikita
+
+
+ + + +