diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/README.md b/README.md new file mode 120000 index 0000000..0d79d56 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +readme.txt \ No newline at end of file diff --git a/css/error-recovery.css b/css/error-recovery.css new file mode 100644 index 0000000..a0e0508 --- /dev/null +++ b/css/error-recovery.css @@ -0,0 +1,112 @@ +#sm-fatal-error-notice.loading { + position: relative; } + #sm-fatal-error-notice.loading #sm-curtain { + width: 100%; + height: 100%; + background: #ffffff; + opacity: .7; } + #sm-fatal-error-notice.loading #sm-spinner { + opacity: 1; } + +#sm-curtain { + position: absolute; + top: 0; + left: 0; + opacity: 0; + background: transparent; + transition: opacity .5s; } + #sm-curtain.dialog { + transition: none; + position: fixed; + z-index: 99999; + background: #fff; + opacity: .8; + width: 100%; + height: 100%; } + +#sm-spinner { + z-index: 10; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + left: 50%; + opacity: 0; + transition: opacity 1s; } + +#sm-disable-recovery-notice { + color: #e29300; } + #sm-disable-recovery-notice > a { + color: #a26300; } + +#sm-error { + background-color: #01354e; + color: #ffffff; + padding: .5rem; } + +.ui-dialog { + box-shadow: 0 -2px 25px 0 rgba(0, 0, 0, 0.15), 0 13px 25px 0 rgba(0, 0, 0, 0.3); + background-color: #FFFFFF; + margin: 0 auto; + width: auto; + height: auto; + border-radius: 2px 2px 0 0; + padding: 21px 24px 12px; + z-index: 100000; } + +.ui-dialog-titlebar { + font-family: 'Roboto', sans-serif; + font-weight: 500; + font-size: 20px; + color: rgba(0, 0, 0, 0.8); + line-height: 24px; + text-align: left; + letter-spacing: 0.03px; } + +.ui-dialog-content { + font-size: 13px; + color: rgba(0, 0, 0, 0.5); + line-height: 24px; + text-align: left; + letter-spacing: 0.03px; + padding: 14px 0 0; } + .ui-dialog-content textarea, .ui-dialog-content input[type="email"] { + width: 100%; } + +.ui-dialog-titlebar-close { + display: none; } + +.ui-dialog-buttonpane { + width: auto; + height: 48px; + background-color: #FFFFFF; + text-align: right; + border-radius: 0 0 2px 2px; + padding: 8px 0 0 16px; } + +.ui-dialog-buttonset > button { + display: inline-block; + height: 36px; + background-color: rgba(9, 9, 9, 0); + font-weight: 500; + font-size: 16px; + color: rgba(33, 150, 243, 0.9); + line-height: 36px; + text-align: center; + letter-spacing: 0.4px; + padding: 0 8px; + margin: 6px 4px; + text-transform: uppercase; + outline: none; + border: none; + cursor: pointer; + transition: all 0.2s ease; } + .ui-dialog-buttonset > button:last-child { + margin-right: 0; } + +.ui-dialog-buttonset > button:hover { + background-color: rgba(99, 99, 99, 0.2); } + +.ui-dialog-buttonset > button:active { + background-color: rgba(99, 99, 99, 0.4); } + +/*# sourceMappingURL=error-recovery.css.map */ diff --git a/css/error-recovery.css.map b/css/error-recovery.css.map new file mode 100644 index 0000000..d2b0bb1 --- /dev/null +++ b/css/error-recovery.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAAA,8BAA+B;EAC7B,QAAQ,EAAE,QAAQ;EAElB,0CAAY;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,OAAO;IACnB,OAAO,EAAE,EAAE;EAGb,0CAAY;IACV,OAAO,EAAE,CAAC;;AAId,WAAY;EACV,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,WAAW;EACvB,UAAU,EAAE,WAAW;EAEvB,kBAAS;IACP,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,KAAK;IACf,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;;AAIhB,WAAY;EACV,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,GAAG;EACR,SAAS,EAAE,qBAAqB;EAChC,IAAI,EAAE,GAAG;EACT,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,UAAU;;AAGxB,2BAA4B;EAC1B,KAAK,EAAE,OAAO;EAEd,+BAAI;IACF,KAAK,EAAE,OAAO;;AAIlB,SAAU;EACR,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,OAAO;EACd,OAAO,EAAE,KAAK;;AAGhB,UAAW;EACT,UAAU,EAAE,mEAAmE;EAC/E,gBAAgB,EAAE,OAAO;EACzB,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,aAAa,EAAE,WAAW;EAC1B,OAAO,EAAE,cAAc;EACvB,OAAO,EAAE,MAAM;;AAGjB,mBAAoB;EAClB,WAAW,EAAE,oBAAoB;EACjC,WAAW,EAAE,GAAG;EAChB,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,kBAAiB;EACxB,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,IAAI;EAChB,cAAc,EAAE,MAAM;;AAGxB,kBAAmB;EACjB,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,kBAAiB;EACxB,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,IAAI;EAChB,cAAc,EAAE,MAAM;EACtB,OAAO,EAAE,QAAQ;EAEjB,mEAA8B;IAC5B,KAAK,EAAE,IAAI;;AAIf,yBAA0B;EACxB,OAAO,EAAE,IAAI;;AAGf,qBAAsB;EACpB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,KAAK;EACjB,aAAa,EAAE,WAAW;EAC1B,OAAO,EAAE,YAAY;;AAGvB,6BAA8B;EAC5B,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,IAAI;EACZ,gBAAgB,EAAE,gBAAgB;EAClC,WAAW,EAAE,GAAG;EAChB,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,uBAAuB;EAC9B,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,MAAM;EAClB,cAAc,EAAE,KAAK;EACrB,OAAO,EAAE,KAAK;EACd,MAAM,EAAE,OAAO;EACf,cAAc,EAAE,SAAS;EACzB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,OAAO;EACf,UAAU,EAAE,aAAa;EAEzB,wCAAa;IACX,YAAY,EAAE,CAAC;;AAInB,mCAAoC;EAClC,gBAAgB,EAAE,qBAAqB;;AAGzC,oCAAqC;EACnC,gBAAgB,EAAE,qBAAqB", +"sources": ["error-recovery.scss"], +"names": [], +"file": "error-recovery.css" +} \ No newline at end of file diff --git a/css/error-recovery.scss b/css/error-recovery.scss new file mode 100644 index 0000000..30ddda4 --- /dev/null +++ b/css/error-recovery.scss @@ -0,0 +1,135 @@ +#sm-fatal-error-notice.loading { + position: relative; + + #sm-curtain { + width: 100%; + height: 100%; + background: #ffffff; + opacity: .7; + } + + #sm-spinner { + opacity: 1; + } +} + +#sm-curtain { + position: absolute; + top: 0; + left: 0; + opacity: 0; + background: transparent; + transition: opacity .5s; + + &.dialog { + transition: none; + position: fixed; + z-index: 99999; + background: #fff; + opacity: .8; + width: 100%; + height: 100%; + } +} + +#sm-spinner { + z-index: 10; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + left: 50%; + opacity: 0; + transition: opacity 1s; +} + +#sm-disable-recovery-notice { + color: #e29300; + + > a { + color: #a26300 + } +} + +#sm-error { + background-color: #01354e; + color: #ffffff; + padding: .5rem; +} + +.ui-dialog { + box-shadow: 0 -2px 25px 0 rgba(0, 0, 0, 0.15), 0 13px 25px 0 rgba(0, 0, 0, 0.3); + background-color: #FFFFFF; + margin: 0 auto; + width: auto; + height: auto; + border-radius: 2px 2px 0 0; + padding: 21px 24px 12px; + z-index: 100000; +} + +.ui-dialog-titlebar { + font-family: 'Roboto', sans-serif; + font-weight: 500; + font-size: 20px; + color: rgba(0, 0, 0, .8); + line-height: 24px; + text-align: left; + letter-spacing: 0.03px; +} + +.ui-dialog-content { + font-size: 13px; + color: rgba(0, 0, 0, .5); + line-height: 24px; + text-align: left; + letter-spacing: 0.03px; + padding: 14px 0 0; + + textarea, input[type="email"] { + width: 100%; + } +} + +.ui-dialog-titlebar-close { + display: none; +} + +.ui-dialog-buttonpane { + width: auto; + height: 48px; + background-color: #FFFFFF; + text-align: right; + border-radius: 0 0 2px 2px; + padding: 8px 0 0 16px; +} + +.ui-dialog-buttonset > button { + display: inline-block; + height: 36px; + background-color: rgba(9, 9, 9, 0); + font-weight: 500; + font-size: 16px; + color: rgba(33, 150, 243, 0.9); + line-height: 36px; + text-align: center; + letter-spacing: 0.4px; + padding: 0 8px; + margin: 6px 4px; + text-transform: uppercase; + outline: none; + border: none; + cursor: pointer; + transition: all 0.2s ease; + + &:last-child { + margin-right: 0; + } +} + +.ui-dialog-buttonset > button:hover { + background-color: rgba(99, 99, 99, 0.2); +} + +.ui-dialog-buttonset > button:active { + background-color: rgba(99, 99, 99, 0.4); +} diff --git a/css/sermon.css b/css/sermon.css index 99ebae7..630222a 100755 --- a/css/sermon.css +++ b/css/sermon.css @@ -139,6 +139,10 @@ display: block; } +.widget_recent_sermons .meta > span { + display: inline; +} + #sermon-navigation { padding-bottom: 15px; } diff --git a/includes/CMB2/includes/types/CMB2_Type_Text_Date.php b/includes/CMB2/includes/types/CMB2_Type_Text_Date.php index 327cfd0..cfd95f7 100755 --- a/includes/CMB2/includes/types/CMB2_Type_Text_Date.php +++ b/includes/CMB2/includes/types/CMB2_Type_Text_Date.php @@ -17,9 +17,10 @@ class CMB2_Type_Text_Date extends CMB2_Type_Picker_Base { public function render() { $args = $this->parse_args( 'text_date', array( 'class' => 'cmb2-text-small cmb2-datepicker', - 'value' => $this->field->get_timestamp_format(), + 'value' => isset( $_GET['post'] ) ? ( get_post_meta( $_GET['post'], 'sermon_date_auto', true ) ? '' : $this->field->get_timestamp_format() ) : '', 'desc' => $this->_desc(), 'js_dependencies' => array( 'jquery-ui-core', 'jquery-ui-datepicker' ), + 'placeholder' => isset( $_GET['post'] ) ? ( get_post_meta( $_GET['post'], 'sermon_date_auto', true ) ? $this->field->get_timestamp_format() : '' ) : $this->field->get_timestamp_format( 'date_format', time() ), ) ); if ( false === strpos( $args['class'], 'timepicker' ) ) { diff --git a/includes/admin-functions.php b/includes/admin-functions.php index a7f993a..b385dcb 100755 --- a/includes/admin-functions.php +++ b/includes/admin-functions.php @@ -121,19 +121,19 @@ function wpfc_sermon_updated_messages( $messages ) { $messages['wpfc_sermon'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __( 'Sermon updated. View sermon', 'sermon-manager' ), esc_url( get_permalink( $post_ID ) ) ), - 2 => __( 'Custom field updated.', 'sermon-manager' ), - 3 => __( 'Custom field deleted.', 'sermon-manager' ), - 4 => __( 'Sermon updated.', 'sermon-manager' ), + 1 => sprintf( __( 'Sermon updated. View sermon', 'sermon-manager-for-wordpress' ), esc_url( get_permalink( $post_ID ) ) ), + 2 => __( 'Custom field updated.', 'sermon-manager-for-wordpress' ), + 3 => __( 'Custom field deleted.', 'sermon-manager-for-wordpress' ), + 4 => __( 'Sermon updated.', 'sermon-manager-for-wordpress' ), /* translators: %s: date and time of the revision */ - 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Sermon restored to revision from %s', 'sermon-manager' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => sprintf( __( 'Sermon published. View sermon', 'sermon-manager' ), esc_url( get_permalink( $post_ID ) ) ), - 7 => __( 'Sermon saved.', 'sermon-manager' ), - 8 => sprintf( __( 'Sermon submitted. Preview sermon', 'sermon-manager' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), - 9 => sprintf( __( 'Sermon scheduled for: %1$s. Preview sermon', 'sermon-manager' ), + 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Sermon restored to revision from %s', 'sermon-manager-for-wordpress' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => sprintf( __( 'Sermon published. View sermon', 'sermon-manager-for-wordpress' ), esc_url( get_permalink( $post_ID ) ) ), + 7 => __( 'Sermon saved.', 'sermon-manager-for-wordpress' ), + 8 => sprintf( __( 'Sermon submitted. Preview sermon', 'sermon-manager-for-wordpress' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + 9 => sprintf( __( 'Sermon scheduled for: %1$s. Preview sermon', 'sermon-manager-for-wordpress' ), // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i', 'sermon-manager' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), - 10 => sprintf( __( 'Sermon draft updated. Preview sermon', 'sermon-manager' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + date_i18n( __( 'M j, Y @ G:i', 'sermon-manager-for-wordpress' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), + 10 => sprintf( __( 'Sermon draft updated. Preview sermon', 'sermon-manager-for-wordpress' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), ); return $messages; @@ -186,13 +186,14 @@ function wpfc_sermon_order( $vars ) { function wpfc_sermon_edit_columns() { $columns = array( "cb" => "", - "title" => __( 'Sermon Title', 'sermon-manager' ), - "preacher" => __( \SermonManager::getOption( 'preacher_label' ) ?: 'Preacher', 'sermon-manager' ), - "series" => __( 'Sermon Series', 'sermon-manager' ), - "topics" => __( 'Topics', 'sermon-manager' ), - "views" => __( 'Views', 'sermon-manager' ), - "preached" => __( 'Date Preached', 'sermon-manager' ), - "passage" => __( 'Bible Passage', 'sermon-manager' ), + "title" => __( 'Sermon Title', 'sermon-manager-for-wordpress' ), + /* Translators: %s: Preacher label (sentence case; singular) */ + "preacher" => sprintf( __( '%s', 'sermon-manager-for-wordpress' ), ucwords(\SermonManager::getOption( 'preacher_label' ) ) ?: 'Preacher' ), + "series" => __( 'Sermon Series', 'sermon-manager-for-wordpress' ), + "topics" => __( 'Topics', 'sermon-manager-for-wordpress' ), + "views" => __( 'Views', 'sermon-manager-for-wordpress' ), + "preached" => __( 'Date Preached', 'sermon-manager-for-wordpress' ), + "passage" => __( 'Bible Passage', 'sermon-manager-for-wordpress' ), ); return $columns; diff --git a/includes/class-sm-api.php b/includes/class-sm-api.php new file mode 100644 index 0000000..5ec785c --- /dev/null +++ b/includes/class-sm-api.php @@ -0,0 +1,147 @@ +data; + + $post_meta = wp_parse_args( get_post_meta( $data['id'] ), array( + 'sermon_audio' => array( '' ), + '_wpfc_sermon_duration' => array( '' ), + 'Views' => array( '' ), + 'bible_passage' => array( '' ), + 'sermon_description' => array( '' ), + 'sermon_video' => array( '' ), + 'sermon_video_link' => array( '' ), + 'sermon_bulletin' => array( '' ), + '_thumbnail_id' => array( '' ), + 'sermon_date_auto' => array( '' ), + ) ); + + $data['sermon_audio'] = $post_meta['sermon_audio'][0]; + $data['sermon_audio_duration'] = $post_meta['_wpfc_sermon_duration'][0]; + $data['_views'] = $post_meta['Views'][0]; + $data['bible_passage'] = $post_meta['bible_passage'][0]; + $data['sermon_description'] = $post_meta['sermon_description'][0]; + $data['sermon_video_embed'] = $post_meta['sermon_video'][0]; + $data['sermon_video_url'] = $post_meta['sermon_video_link'][0]; + $data['sermon_bulletin'] = $post_meta['sermon_bulletin'][0]; + $data['_featured_url'] = wp_get_attachment_url( $post_meta['_thumbnail_id'][0] ); + + if ( $date = SM_Dates::get( 'U', $data['id'] ) ) { + $data['sermon_date'] = intval( $date ); + $data['_sermon_date_auto'] = $post_meta['sermon_date_auto'][0] == 1 ? true : false; + } + + return $response; + } +} + +new SM_API(); \ No newline at end of file diff --git a/includes/class-sm-dates-wp.php b/includes/class-sm-dates-wp.php index 572050d..94e207b 100644 --- a/includes/class-sm-dates-wp.php +++ b/includes/class-sm-dates-wp.php @@ -1,4 +1,6 @@ post_date; + $GLOBALS['sm_original_sermon_date'] = get_post_meta( $post_ID, 'sermon_date', true ); + } + } + + /** + * Sets/updates date for posts if they are not user-defined + * + * @param int $post_ID Post ID. + * @param WP_Post $post Post object. + * @param bool $update Whether this is an existing post being updated or not. + * + * @since 2.7 + */ + public static function maybe_update_date( $post_ID, $post, $update ) { + $update_date = $auto = false; + + if ( $update ) { + // compare sermon date and if user changed it update sermon date and disable auto update + if ( ! empty( $GLOBALS['sm_original_sermon_date'] ) && ! empty( $_POST['sermon_date'] ) ) { + $dt = DateTime::createFromFormat( SermonManager::getOption( 'date_format' ) ?: 'm/d/Y', $_POST['sermon_date'] ); + if ( $dt instanceof DateTime && $dt->format( 'U' ) != $GLOBALS['sm_original_sermon_date'] ) { + update_post_meta( $post_ID, 'sermon_date_auto', 0 ); + } + } + + // compare published date and if user changed it update sermon date if auto update is set + if ( ! empty( $GLOBALS['sm_original_published_date'] ) ) { + if ( $post->post_date !== $GLOBALS['sm_original_published_date'] && + get_post_meta( $post_ID, 'sermon_date_auto', true ) == 1 ) { + $update_date = true; + } + } + } + + // if sermon date is blank (not set on sermon create or removed later on update), mark + // this post for auto updating and update date now + if ( isset( $_POST['sermon_date'] ) && $_POST['sermon_date'] == '' ) { + $update_date = true; + $auto = true; + } + + // if marked for date updating + if ( $update_date ) { + update_post_meta( $post_ID, 'sermon_date', mysql2date( 'U', $post->post_date ) ); + add_filter( 'cmb2_override_sermon_date_meta_save', '__return_true' ); + add_filter( 'cmb2_override_sermon_date_meta_remove', '__return_true' ); + } + + // if we should set it for auto date updating + if ( $auto ) { + update_post_meta( $post_ID, 'sermon_date_auto', '1' ); + } } } \ No newline at end of file diff --git a/includes/class-sm-dates.php b/includes/class-sm-dates.php index 646ad36..95b8864 100644 --- a/includes/class-sm-dates.php +++ b/includes/class-sm-dates.php @@ -1,4 +1,5 @@ post_date_gmt ) ); + $dt = DateTime::createFromFormat( 'U', mysql2date( 'U', $post->post_date ) ); $time = array( $dt->format( 'H' ), - $dt->format( 'm' ), + $dt->format( 'i' ), $dt->format( 's' ) ); diff --git a/includes/class-sm-error-recovery.php b/includes/class-sm-error-recovery.php new file mode 100644 index 0000000..b9a2b76 --- /dev/null +++ b/includes/class-sm-error-recovery.php @@ -0,0 +1,309 @@ +query( $sql ); + if ( $result->num_rows === 0 ) { + $sql = "INSERT INTO {$table_prefix}options (option_name, option_value, autoload) VALUES ('_sm_recovery_do_not_catch', '0', 'yes')"; + } else { + $sql = "UPDATE {$table_prefix}options SET option_value = '0' WHERE option_name = '_sm_recovery_do_not_catch'"; + } + $mysqli->query( $sql ); + } + + $sql = "SELECT option_value FROM {$table_prefix}options WHERE option_name = '_sm_recovery_do_not_catch'"; + $result = $mysqli->query( $sql ); + if ( $result->num_rows === 0 ) { + $does_not_exist = true; + $sm_do_not_catch = false; + } else { + $result = $result->fetch_assoc(); + $sm_do_not_catch = $result['option_value'] == 1; + } + + if ( $sm_do_not_catch ) { + return; + } + + self::$_error = error_get_last(); + + if ( self::_is_fatal() ) { + // check if it's caused by SM + self::_update_db(); + + if ( ! empty( $does_not_exist ) ) { + $sql = "INSERT INTO {$table_prefix}options (option_name, option_value, autoload) VALUES ('_sm_recovery_do_not_catch', '1', 'yes')"; + } else { + $sql = "UPDATE {$table_prefix}options SET option_value = '1' WHERE option_name = '_sm_recovery_do_not_catch'"; + } + $mysqli->query( $sql ); + + $headers = get_headers( get_site_url() ); + if ( substr( $headers[0], 9, 3 ) == 500 ) { + self::reset_db(); + } + + $mysqli->query( "UPDATE {$table_prefix}options SET option_value = '0' WHERE option_name = '_sm_recovery_do_not_catch'" ); + } + } + + /** + * Checks if PHP error is fatal + * + * @access private + * + * @return bool True if it is, false otherwise + */ + private static function _is_fatal() { + return in_array( self::$_error['type'], self::$_catch_errors ); + } + + /** + * Prevents Sermon Manager from running and saves error message for displaying + * + * @access private + */ + private static function _update_db() { + global $table_prefix; + $mysqli = new mysqli( DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); + + // check if set + $sql = "SELECT option_id FROM {$table_prefix}options WHERE option_name = '_sm_recovery_disable'"; + $result = $mysqli->query( $sql ); + if ( $result->num_rows === 0 ) { + $sql = "INSERT INTO {$table_prefix}options (option_name, option_value, autoload) VALUES ('_sm_recovery_disable', '1', 'yes')"; + } else { + $sql = "UPDATE {$table_prefix}options SET option_value = '1' WHERE option_name = '_sm_recovery_disable'"; + } + $mysqli->query( $sql ); + + // check if set + $sql = "SELECT option_id FROM {$table_prefix}options WHERE option_name = '_sm_recovery_last_fatal_error'"; + $result = $mysqli->query( $sql ); + if ( $result->num_rows === 0 ) { + $sql = "INSERT INTO {$table_prefix}options (option_name, option_value, autoload) VALUES ('_sm_recovery_last_fatal_error', '" . $mysqli->real_escape_string( self::_get_message() ) . "', 'yes')"; + } else { + $sql = "UPDATE {$table_prefix}options SET option_value = '" . $mysqli->real_escape_string( self::_get_message() ) . "' WHERE option_name = '_sm_recovery_last_fatal_error'"; + } + $mysqli->query( $sql ); + } + + /** + * Gets PHP error message + * + * @access private + * + * @return string + */ + private static function _get_message() { + return self::$_error['message']; + } + + /** + * Allows Sermon Manager to run again, called on plugin update or by user + */ + public static function reset_db() { + global $table_prefix; + $mysqli = new mysqli( DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); + + // check if set + $sql = "SELECT option_id FROM {$table_prefix}options WHERE option_name = '_sm_recovery_disable'"; + $result = $mysqli->query( $sql ); + if ( $result->num_rows === 0 ) { + $sql = "INSERT INTO {$table_prefix}options (option_name, option_value, autoload) VALUES ('_sm_recovery_disable', '0', 'yes')"; + } else { + $sql = "UPDATE {$table_prefix}options SET option_value = '0' WHERE option_name = '_sm_recovery_disable'"; + } + + $mysqli->query( $sql ); + } + + /** + * Displays WordPress admin error message + */ + public static function render_admin_message() { + $plugin_name = get_plugin_data( constant( self::$_plugin_main_file ) )['Name']; + $old_error = get_option( '_sm_recovery_last_fatal_error_hash' ) === md5( get_option( '_sm_recovery_last_fatal_error' ) ); + + ?> +
+

+ + %s encountered a fatal error and recovered successfully.', 'sermon-manager-for-wordpress' ), $plugin_name ) ?> + + + +

+

+ + + + + + + + + + + +

+ + +
+ + +
+ urlencode( str_replace( ABSPATH, '~/', get_option( '_sm_recovery_last_fatal_error' ) ) ), + 'environment_info' => 'WordPress: ' . $GLOBALS['wp_version'] . '; Server: ' . ( function_exists( 'apache_get_version' ) ? apache_get_version() : 'N/A' ) . '; PHP: ' . PHP_VERSION . '; Sermon Manager:' . SERMON_MANAGER_VERSION . ';', + 'plugin_name' => get_plugin_data( constant( self::$_plugin_main_file ) )['Name'], + + ) ); + wp_enqueue_style( 'sm-error-recovery', SERMON_MANAGER_URL . 'css/error-recovery.css', array(), SERMON_MANAGER_VERSION ); + } + + /** + * Disables send report button. + */ + public static function disable_send_report_button() { + update_option( '_sm_recovery_last_fatal_error_hash', md5( get_option( '_sm_recovery_last_fatal_error' ) ) ); + update_option( '_sm_recovery_disable_send', '1' ); + + return true; + } + + /** + * Re-allow recovery to work on update + */ + public static function upgrade_check() { + $db_version = get_option( 'sm_version' ); + if ( empty( $db_version ) || $db_version != SERMON_MANAGER_VERSION ) { + update_option( '_sm_recovery_do_not_catch', 0 ); + update_option( '_sm_recovery_disable', 0 ); + update_option( 'sm_version', SERMON_MANAGER_VERSION ); + } + } + + public function init() { + $this->_hook(); + } + + /** + * Hooks into PHP error handing function and WordPress if plugin detected an error + * + * @access private + */ + private function _hook() { + register_shutdown_function( array( get_class(), 'do_catch' ) ); + add_action( 'plugins_loaded', array( get_class(), 'upgrade_check' ) ); + + if ( get_option( '_sm_recovery_disable' ) ) { + $this->_register_wp_hooks(); + define( 'sm_break', true ); + } + } + + /** + * Hooks into WP + * + * @access private + */ + private function _register_wp_hooks() { + add_action( 'admin_enqueue_scripts', array( get_class(), 'enqueue_scripts_styles' ) ); + add_action( 'admin_notices', array( get_class(), 'render_admin_message' ), 0 ); + add_action( 'wp_ajax_sm_clear_fatal_error', array( get_class(), 'reset_db' ) ); + add_action( 'wp_ajax_sm_recovery_disable_send_report', array( get_class(), 'disable_send_report_button' ) ); + } +} \ No newline at end of file diff --git a/includes/class-sm-post-types.php b/includes/class-sm-post-types.php new file mode 100644 index 0000000..58a77b3 --- /dev/null +++ b/includes/class-sm-post-types.php @@ -0,0 +1,274 @@ + false, + /* Translators: %s: Preachers label (sentence case; plural) */ + 'label' => sprintf( __( '%s', 'sermon-manager-for-wordpress' ), ucwords( $preacher_label ) . 's'), + 'labels' => array( + /* Translators: %s: Preachers label (sentence case; plural) */ + 'name' => sprintf( __( '%s', 'sermon-manager-for-wordpress' ), ucwords( $preacher_label ) . 's' ), + /* Translators: %s: Preacher label (sentence case; singular) */ + 'singular_name' => sprintf( __( '%s', 'sermon-manager-for-wordpress' ), ucwords( $preacher_label ) ), + /* Translators: %s: Preachers label (sentence case; plural) */ + 'menu_name' => sprintf( _x( '%s', 'Admin menu name', 'sermon-manager' ), ucwords( $preacher_label ). 's' ), + /* Translators: %s: Preachers label (lowercase; plural) */ + 'search_items' => sprintf( __( 'Search %s', 'sermon-manager-for-wordpress' ), $preacher_label . 's' ), + /* Translators: %s: Preachers label (lowercase; plural) */ + 'all_items' => sprintf( __( 'All %s', 'sermon-manager-for-wordpress' ), $preacher_label . 's' ), + 'parent_item' => null, // it's not hierarchical + 'parent_item_colon' => null, // it's not hierarchical + /* Translators: %s: Preacher label (lowercase; singular) */ + 'edit_item' => sprintf( __( 'Edit %s', 'sermon-manager-for-wordpress' ), $preacher_label ), + /* Translators: %s: Preacher label (lowercase; singular) */ + 'update_item' => sprintf( __( 'Update %s', 'sermon-manager-for-wordpress' ), $preacher_label ), + /* Translators: %s: Preacher label (lowercase; singular) */ + 'add_new_item' => sprintf( __( 'Add new %s', 'sermon-manager-for-wordpress' ), $preacher_label ), + /* Translators: %s: Preacher label (lowercase; singular) */ + 'new_item_name' => sprintf( __( 'New %s name', 'sermon-manager-for-wordpress' ), $preacher_label ), + /* Translators: %s: Preacher label (lowercase; singular) */ + 'not_found' => sprintf( __( 'No %s found', 'sermon-manager-for-wordpress' ), $preacher_label ), + ), + 'show_ui' => true, + 'query_var' => true, + 'show_in_rest' => true, + 'rewrite' => array( 'slug' => $permalinks['wpfc_preacher'], 'with_front' => false ), + ) ) ); + + register_taxonomy( 'wpfc_sermon_series', + apply_filters( 'sm_taxonomy_objects_wpfc_sermon_series', array( 'wpfc_sermon' ) ), + apply_filters( 'sm_taxonomy_args_wpfc_sermon_series', array( + 'hierarchical' => false, + 'label' => __( 'Series', 'sermon-manager-for-wordpress' ), + 'labels' => array( + 'name' => __( 'Series', 'sermon-manager-for-wordpress' ), + 'singular_name' => __( 'Series', 'sermon-manager-for-wordpress' ), + 'menu_name' => _x( 'Series', 'Admin menu name', 'sermon-manager' ), + 'search_items' => __( 'Search series', 'sermon-manager-for-wordpress' ), + 'all_items' => __( 'All series', 'sermon-manager-for-wordpress' ), + 'parent_item' => null, // it's not hierarchical + 'parent_item_colon' => null, // it's not hierarchical + 'edit_item' => __( 'Edit series', 'sermon-manager-for-wordpress' ), + 'update_item' => __( 'Update series', 'sermon-manager-for-wordpress' ), + 'add_new_item' => __( 'Add new series', 'sermon-manager-for-wordpress' ), + 'new_item_name' => __( 'New series name', 'sermon-manager-for-wordpress' ), + 'not_found' => __( 'No series found', 'sermon-manager-for-wordpress' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'show_in_rest' => true, + 'rewrite' => array( 'slug' => $permalinks['wpfc_sermon_series'], 'with_front' => false ), + ) ) ); + + register_taxonomy( 'wpfc_sermon_topics', + apply_filters( 'sm_taxonomy_objects_wpfc_sermon_topics', array( 'wpfc_sermon' ) ), + apply_filters( 'sm_taxonomy_args_wpfc_sermon_topics', array( + 'hierarchical' => false, + 'label' => __( 'Topics', 'sermon-manager-for-wordpress' ), + 'labels' => array( + 'name' => __( 'Topics', 'sermon-manager-for-wordpress' ), + 'singular_name' => __( 'Topic', 'sermon-manager-for-wordpress' ), + 'menu_name' => _x( 'Topics', 'Admin menu name', 'sermon-manager' ), + 'search_items' => __( 'Search topics', 'sermon-manager-for-wordpress' ), + 'all_items' => __( 'All topics', 'sermon-manager-for-wordpress' ), + 'parent_item' => null, + 'parent_item_colon' => null, + 'edit_item' => __( 'Edit topic', 'sermon-manager-for-wordpress' ), + 'update_item' => __( 'Update topic', 'sermon-manager-for-wordpress' ), + 'add_new_item' => __( 'Add new topic', 'sermon-manager-for-wordpress' ), + 'new_item_name' => __( 'New topic name', 'sermon-manager-for-wordpress' ), + 'not_found' => __( 'No topics found', 'sermon-manager-for-wordpress' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'show_in_rest' => true, + 'rewrite' => array( 'slug' => $permalinks['wpfc_sermon_topics'], 'with_front' => false ), + ) ) ); + + register_taxonomy( 'wpfc_bible_book', + apply_filters( 'sm_taxonomy_objects_wpfc_bible_book', array( 'wpfc_sermon' ) ), + apply_filters( 'sm_taxonomy_args_wpfc_bible_book', array( + 'hierarchical' => false, + 'label' => __( 'Books', 'sermon-manager-for-wordpress' ), + 'labels' => array( + 'name' => __( 'Bible books', 'sermon-manager-for-wordpress' ), + 'singular_name' => __( 'Book', 'sermon-manager-for-wordpress' ), + 'menu_name' => _x( 'Books', 'Admin menu name', 'sermon-manager' ), + 'search_items' => __( 'Search books', 'sermon-manager-for-wordpress' ), + 'all_items' => __( 'All books', 'sermon-manager-for-wordpress' ), + 'parent_item' => null, + 'parent_item_colon' => null, + 'edit_item' => __( 'Edit book', 'sermon-manager-for-wordpress' ), + 'update_item' => __( 'Update book', 'sermon-manager-for-wordpress' ), + 'add_new_item' => __( 'Add new book', 'sermon-manager-for-wordpress' ), + 'new_item_name' => __( 'New book name', 'sermon-manager-for-wordpress' ), + 'not_found' => __( 'No books found', 'sermon-manager-for-wordpress' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'show_in_rest' => true, + 'rewrite' => array( 'slug' => $permalinks['wpfc_bible_book'], 'with_front' => false ), + ) ) ); + + register_taxonomy( 'wpfc_service_type', + apply_filters( 'sm_taxonomy_objects_wpfc_service_type', array( 'wpfc_sermon' ) ), + apply_filters( 'sm_taxonomy_args_wpfc_service_type', array( + 'hierarchical' => false, + 'label' => __( 'Service Types', 'sermon-manager-for-wordpress' ), + 'labels' => array( + 'name' => __( 'Service Types', 'sermon-manager-for-wordpress' ), + 'singular_name' => __( 'Service Type', 'sermon-manager-for-wordpress' ), + 'menu_name' => _x( 'Service Types', 'Admin menu name', 'sermon-manager' ), + 'search_items' => __( 'Search service types', 'sermon-manager-for-wordpress' ), + 'all_items' => __( 'All service types', 'sermon-manager-for-wordpress' ), + 'parent_item' => null, + 'parent_item_colon' => null, + 'edit_item' => __( 'Edit service type', 'sermon-manager-for-wordpress' ), + 'update_item' => __( 'Update service type', 'sermon-manager-for-wordpress' ), + 'add_new_item' => __( 'Add new service type', 'sermon-manager-for-wordpress' ), + 'new_item_name' => __( 'New service type name', 'sermon-manager-for-wordpress' ), + 'not_found' => __( 'No service types found', 'sermon-manager-for-wordpress' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'show_in_rest' => true, + 'rewrite' => array( 'slug' => $permalinks['wpfc_service_type'], 'with_front' => false ), + ) ) ); + + do_action( 'sm_after_register_taxonomy' ); + } + + /** + * Register core post types. + */ + public static function register_post_types() { + if ( ! is_blog_installed() || post_type_exists( 'wpfc_sermon' ) ) { + return; + } + + do_action( 'sm_register_post_type' ); + + $permalinks = sm_get_permalink_structure(); + + register_post_type( 'wpfc_sermon', apply_filters( 'sm_register_post_type_wpfc_sermon', array( + 'labels' => array( + 'name' => __( 'Sermons', 'sermon-manager-for-wordpress' ), + 'singular_name' => __( 'Sermon', 'sermon-manager-for-wordpress' ), + 'all_items' => __( 'All Sermons', 'sermon-manager-for-wordpress' ), + 'menu_name' => _x( 'Sermons', 'Admin menu name', 'sermon-manager' ), + 'add_new' => __( 'Add New', 'sermon-manager-for-wordpress' ), + 'add_new_item' => __( 'Add new sermon', 'sermon-manager-for-wordpress' ), + 'edit' => __( 'Edit', 'sermon-manager-for-wordpress' ), + 'edit_item' => __( 'Edit sermon', 'sermon-manager-for-wordpress' ), + 'new_item' => __( 'New sermon', 'sermon-manager-for-wordpress' ), + 'view' => __( 'View sermon', 'sermon-manager-for-wordpress' ), + 'view_item' => __( 'View sermon', 'sermon-manager-for-wordpress' ), + 'search_items' => __( 'Search sermon', 'sermon-manager-for-wordpress' ), + 'not_found' => __( 'No sermons found', 'sermon-manager-for-wordpress' ), + 'not_found_in_trash' => __( 'No sermons found in trash', 'sermon-manager-for-wordpress' ), + 'featured_image' => __( 'Sermon image', 'sermon-manager-for-wordpress' ), + 'set_featured_image' => __( 'Set sermon image', 'sermon-manager-for-wordpress' ), + 'remove_featured_image' => __( 'Remove sermon image', 'sermon-manager-for-wordpress' ), + 'use_featured_image' => __( 'Use as sermon image', 'sermon-manager-for-wordpress' ), + 'insert_into_item' => __( 'Insert to sermon', 'sermon-manager-for-wordpress' ), + 'uploaded_to_this_item' => __( 'Uploaded to this sermon', 'sermon-manager-for-wordpress' ), + 'filter_items_list' => __( 'Filter sermon', 'sermon-manager-for-wordpress' ), + 'items_list_navigation' => __( 'Sermon navigation', 'sermon-manager-for-wordpress' ), + 'items_list' => __( 'Sermon list', 'sermon-manager-for-wordpress' ), + ), + 'description' => __( 'This is where you can add new sermons to your website.', 'sermon-manager-for-wordpress' ), + 'public' => true, + 'show_ui' => true, + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'publicly_queryable' => true, + 'exclude_from_search' => false, + 'show_in_menu' => true, + 'menu_icon' => SERMON_MANAGER_URL . 'includes/img/sm-icon.svg', + 'hierarchical' => false, + 'rewrite' => array( 'slug' => $permalinks['wpfc_sermon'], 'with_front' => false ), + 'query_var' => true, + 'show_in_nav_menus' => true, + 'show_in_rest' => true, + 'has_archive' => true, + 'supports' => array( + 'title', + 'thumbnail', + 'publicize', + 'wpcom-markdown', + 'comments', + 'entry-views', + ) + ) ) ); + + do_action( 'sm_after_register_post_type' ); + } + + /** + * Flush rewrite rules. + */ + public static function flush_rewrite_rules() { + flush_rewrite_rules(); + } + + /** + * Add Sermon Support to Jetpack Omnisearch. + */ + public static function support_jetpack_omnisearch() { + if ( class_exists( 'Jetpack_Omnisearch_Posts' ) ) { + new Jetpack_Omnisearch_Posts( 'wpfc_sermon' ); + } + } + + /** + * Add sermon support for Jetpack related posts. + * + * @param array $post_types + * + * @return array + */ + public static function rest_api_allowed_post_types( $post_types ) { + $post_types[] = 'wpfc_sermon'; + + return $post_types; + } +} + +SM_Post_Types::init(); diff --git a/includes/class-sm-search.php b/includes/class-sm-search.php new file mode 100644 index 0000000..4430c70 --- /dev/null +++ b/includes/class-sm-search.php @@ -0,0 +1,85 @@ +posts}.post_status = 'publish')"; + } + + return $where; + } + + /** + * Include taxonomies to default search + * + * @global $wpdb + * + * @param string $join + * + * @return string + */ + public function join( $join ) { + global $wpdb; + + if ( is_search() ) { + $join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id"; + } + + return $join; + } + + /** + * + * @global $wpdb + * + * @param int $groupby + * + * @return string + */ + public function groupby( $groupby ) { + global $wpdb; + + // we need to group on post ID + $groupby_id = "{$wpdb->posts}.ID"; + if ( ! is_search() || strpos( $groupby, $groupby_id ) !== false ) { + return $groupby; + } + // groupby was empty, use ours + if ( ! strlen( trim( $groupby ) ) ) { + return $groupby_id; + } + + // wasn't empty, append ours + return $groupby . ", " . $groupby_id; + } +} + +$search = new SM_Search; +$search->hook(); diff --git a/includes/helper-functions.php b/includes/helper-functions.php index 1ae2e46..41fa94e 100644 --- a/includes/helper-functions.php +++ b/includes/helper-functions.php @@ -190,7 +190,7 @@ function wpfc_get_sermon_series_html( $id ) { $series = wpfc_get_sermon_series( $id ); $series_html = ''; - $series_html .= __( 'Series: ', 'sermon-manager' ); + $series_html .= __( 'Series: ', 'sermon-manager-for-wordpress' ); $series_html .= $series; $series_html .= ''; diff --git a/includes/options.php b/includes/options.php index b5271f5..a8d82fb 100755 --- a/includes/options.php +++ b/includes/options.php @@ -26,6 +26,13 @@ static function wpfc_validate_options( $input ) { $input['archive_title'] = wp_filter_nohtml_kses( $input['archive_title'] ); // Sanitize textbox input (strip html tags, and escape characters) $input['podcasts_per_page'] = intval( $input['podcasts_per_page'] ); + if ( isset( $input['sm_do_not_catch'] ) && $input['sm_do_not_catch'] === 'on' ) { + update_option( 'sm_do_not_catch', '1' ); + unset( $input['sm_do_not_catch'] ); + } else { + update_option( '_sm_recovery_do_not_catch', '0' ); + } + if ( SermonManager::getOption( 'archive_slug' ) != $input['archive_slug'] || SermonManager::getOption( 'preacher_label' ) != $input['preacher_label'] ) { update_option( 'sm_flush_rewrite_rules', '1' ); @@ -71,7 +78,7 @@ function wpfc_init() { // Plugin Meta Links. function wpfc_add_options_page() { - $page = add_submenu_page( 'edit.php?post_type=wpfc_sermon', __( 'Sermon Manager Settings', 'sermon-manager' ), __( 'Settings', 'sermon-manager' ), 'manage_options', __FILE__, array( + $page = add_submenu_page( 'edit.php?post_type=wpfc_sermon', __( 'Sermon Manager Settings', 'sermon-manager' ), __( 'Settings', 'sermon-manager-for-wordpress' ), 'manage_options', __FILE__, array( $this, 'wpfc_sermon_options_render_form' ) ); @@ -91,12 +98,12 @@ function wpfc_sermon_manager_plugin_row_meta( $links, $file ) { return $links; } - $link = wpfc_sermon_manager_settings_page_link( __( 'Settings', 'sermon-manager' ) ); + $link = wpfc_sermon_manager_settings_page_link( __( 'Settings', 'sermon-manager-for-wordpress' ) ); if ( ! empty( $link ) ) { $links[] = $link; } - $links[] = '' . __( 'Support', 'sermon-manager' ) . ''; + $links[] = '' . __( 'Support', 'sermon-manager-for-wordpress' ) . ''; return $links; } @@ -105,7 +112,7 @@ function wpfc_sermon_manager_plugin_row_meta( $links, $file ) { function wpfc_sermon_manager_settings_page_link( $link_text = '' ) { if ( empty( $link_text ) ) { - $link_text = __( 'Manage Settings', 'sermon-manager' ); + $link_text = __( 'Manage Settings', 'sermon-manager-for-wordpress' ); } $link = ''; @@ -195,7 +202,6 @@ function wpfc_sermon_options_render_form() {

- '; print_r($sermon_settings); echo ''; ?>