���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!PK]E\O<FFrequire-file-helper.phpnuW+Ashow_errors; $wpdb->show_errors = false; } $indexable_table = Model::get_table_name( 'Indexable' ); $delete_query = "DELETE FROM $indexable_table WHERE object_type = 'post' AND object_sub_type = 'attachment'"; // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already. $wpdb->query( $delete_query ); // phpcs:enable if ( $suppress_errors ) { $wpdb->show_errors = $show_errors; } } /** * Cleans all attachment links in the links table from target indexable ids. * * @param bool $suppress_errors Whether to suppress db errors when running the cleanup query. * * @return void */ public function clean_attachment_links_from_target_indexable_ids( $suppress_errors ) { global $wpdb; if ( $suppress_errors ) { // If migrations haven't been completed successfully the following may give false errors. So suppress them. $show_errors = $wpdb->show_errors; $wpdb->show_errors = false; } $links_table = Model::get_table_name( 'SEO_Links' ); $query = "UPDATE $links_table SET target_indexable_id = NULL WHERE type = 'image-in'"; // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already. $wpdb->query( $query ); // phpcs:enable if ( $suppress_errors ) { $wpdb->show_errors = $show_errors; } } } PK]E\qUswordpress-helper.phpnuW+Aoptions_helper = $options_helper; $this->indexing_helper = $indexing_helper; $this->show_alternate_message = false; } /** * Determines whether and where the "First-time SEO Configuration" admin notice should be displayed. * * @return bool Whether the "First-time SEO Configuration" admin notice should be displayed. */ public function should_display_first_time_configuration_notice() { if ( ! $this->options_helper->get( 'dismiss_configuration_workout_notice', false ) === false ) { return false; } if ( ! $this->on_wpseo_admin_page_or_dashboard() ) { return false; } return $this->first_time_configuration_not_finished(); } /** * Gets the first time configuration title based on the show_alternate_message boolean * * @return string */ public function get_first_time_configuration_title() { return ( ! $this->show_alternate_message ) ? \__( 'First-time SEO configuration', 'wordpress-seo' ) : \__( 'SEO configuration', 'wordpress-seo' ); } /** * Determines if the first time configuration is completely finished. * * @return bool */ public function first_time_configuration_not_finished() { if ( ! $this->user_can_do_first_time_configuration() ) { return false; } if ( $this->is_first_time_configuration_finished() ) { return false; } if ( $this->options_helper->get( 'first_time_install', false ) !== false ) { return ! $this->are_site_representation_name_and_logo_set() || $this->indexing_helper->get_unindexed_count() > 0; } if ( $this->indexing_helper->is_initial_indexing() === false ) { return false; } if ( $this->indexing_helper->is_finished_indexables_indexing() === true ) { return false; } $this->show_alternate_message = true; return ! $this->are_site_representation_name_and_logo_set(); } /** * Whether the user can do the first-time configuration. * * @return bool Whether the current user can do the first-time configuration. */ private function user_can_do_first_time_configuration() { return \current_user_can( 'wpseo_manage_options' ); } /** * Whether the user is currently visiting one of our admin pages or the WordPress dashboard. * * @return bool Whether the current page is a Yoast SEO admin page */ private function on_wpseo_admin_page_or_dashboard() { $pagenow = $GLOBALS['pagenow']; // Show on the WP Dashboard. if ( $pagenow === 'index.php' ) { return true; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. if ( isset( $_GET['page'] ) && \is_string( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information and only comparing the variable in a condition. $page_from_get = \wp_unslash( $_GET['page'] ); // Show on Yoast SEO pages, with some exceptions. if ( $pagenow === 'admin.php' && \strpos( $page_from_get, 'wpseo' ) === 0 ) { $exceptions = [ 'wpseo_installation_successful', 'wpseo_installation_successful_free', ]; if ( ! \in_array( $page_from_get, $exceptions, true ) ) { return true; } } } return false; } /** * Whether all steps of the first-time configuration have been finished. * * @return bool Whether the first-time configuration has been finished. */ private function is_first_time_configuration_finished() { $configuration_finished_steps = $this->options_helper->get( 'configuration_finished_steps', [] ); return \count( $configuration_finished_steps ) === 3; } /** * Whether the site representation name and logo have been set. * * @return bool Whether the site representation name and logo have been set. */ private function are_site_representation_name_and_logo_set() { $company_or_person = $this->options_helper->get( 'company_or_person', '' ); if ( $company_or_person === '' ) { return false; } if ( $company_or_person === 'company' ) { return ! empty( $this->options_helper->get( 'company_name' ) ) && ! empty( $this->options_helper->get( 'company_logo', '' ) ); } return ! empty( $this->options_helper->get( 'company_or_person_user_id' ) ) && ! empty( $this->options_helper->get( 'person_logo', '' ) ); } /** * Getter for the show alternate message boolean. * * @return bool */ public function should_show_alternate_message() { return $this->show_alternate_message; } } PK]E\X##indexable-helper.phpnuW+A [ 'default_value' => null, ], 'description' => [ 'default_value' => null, ], 'open_graph_title' => [ 'default_value' => null, ], 'open_graph_description' => [ 'default_value' => null, ], 'twitter_title' => [ 'default_value' => null, ], 'twitter_description' => [ 'default_value' => null, ], 'canonical' => [ 'default_value' => null, ], 'primary_focus_keyword' => [ 'default_value' => null, ], 'is_robots_noindex' => [ 'default_value' => null, ], 'is_robots_nofollow' => [ 'default_value' => false, ], 'is_robots_noarchive' => [ 'default_value' => null, ], 'is_robots_noimageindex' => [ 'default_value' => null, ], 'is_robots_nosnippet' => [ 'default_value' => null, ], ]; /** * Indexable_Helper constructor. * * @param Options_Helper $options_helper The options helper. * @param Environment_Helper $environment_helper The environment helper. * @param Indexing_Helper $indexing_helper The indexing helper. */ public function __construct( Options_Helper $options_helper, Environment_Helper $environment_helper, Indexing_Helper $indexing_helper ) { $this->options_helper = $options_helper; $this->environment_helper = $environment_helper; $this->indexing_helper = $indexing_helper; } /** * Sets the indexable repository. Done to avoid circular dependencies. * * @required * * @param Indexable_Repository $repository The indexable repository. * * @return void */ public function set_indexable_repository( Indexable_Repository $repository ) { $this->repository = $repository; } /** * Returns the page type of an indexable. * * @param Indexable $indexable The indexable. * * @return string|false The page type. False if it could not be determined. */ public function get_page_type_for_indexable( $indexable ) { switch ( $indexable->object_type ) { case 'post': $front_page_id = (int) \get_option( 'page_on_front' ); if ( $indexable->object_id === $front_page_id ) { return 'Static_Home_Page'; } $posts_page_id = (int) \get_option( 'page_for_posts' ); if ( $indexable->object_id === $posts_page_id ) { return 'Static_Posts_Page'; } return 'Post_Type'; case 'term': return 'Term_Archive'; case 'user': return 'Author_Archive'; case 'home-page': return 'Home_Page'; case 'post-type-archive': return 'Post_Type_Archive'; case 'date-archive': return 'Date_Archive'; case 'system-page': if ( $indexable->object_sub_type === 'search-result' ) { return 'Search_Result_Page'; } if ( $indexable->object_sub_type === '404' ) { return 'Error_Page'; } } return false; } /** * Resets the permalinks of the indexables. * * @param string|null $type The type of the indexable. * @param string|null $subtype The subtype. Can be null. * @param string $reason The reason that the permalink has been changed. * * @return void */ public function reset_permalink_indexables( $type = null, $subtype = null, $reason = Indexing_Reasons::REASON_PERMALINK_SETTINGS ) { $result = $this->repository->reset_permalink( $type, $subtype ); $this->indexing_helper->set_reason( $reason ); if ( $result !== false && $result > 0 ) { \delete_transient( Indexable_Post_Indexation_Action::UNINDEXED_COUNT_TRANSIENT ); \delete_transient( Indexable_Post_Type_Archive_Indexation_Action::UNINDEXED_COUNT_TRANSIENT ); \delete_transient( Indexable_Term_Indexation_Action::UNINDEXED_COUNT_TRANSIENT ); } } /** * Determines whether indexing the specific indexable is appropriate at this time. * * @param Indexable $indexable The indexable. * * @return bool Whether indexing the specific indexable is appropriate at this time. */ public function should_index_indexable( $indexable ) { $intend_to_save = $this->should_index_indexables(); /** * Filter: 'wpseo_should_save_indexable' - Allow developers to enable / disable * saving the indexable when the indexable is updated. Warning: overriding * the intended action may cause problems when moving from a staging to a * production environment because indexable permalinks may get set incorrectly. * * @param bool $intend_to_save True if YoastSEO intends to save the indexable. * @param Indexable $indexable The indexable to be saved. */ return \apply_filters( 'wpseo_should_save_indexable', $intend_to_save, $indexable ); } /** * Determines whether indexing indexables is appropriate at this time. * * @return bool Whether the indexables should be indexed. */ public function should_index_indexables() { // Currently, the only reason to index is when we're on a production website. $should_index = $this->environment_helper->is_production_mode(); /** * Filter: 'Yoast\WP\SEO\should_index_indexables' - Allow developers to enable / disable * creating indexables. Warning: overriding * the intended action may cause problems when moving from a staging to a * production environment because indexable permalinks may get set incorrectly. * * @since 18.2 * * @param bool $should_index Whether the site's indexables should be created. */ return (bool) \apply_filters( 'Yoast\WP\SEO\should_index_indexables', $should_index ); } /** * Returns whether or not dynamic permalinks should be used. * * @return bool Whether or not the dynamic permalinks should be used. */ public function dynamic_permalinks_enabled() { /** * Filters the value of the `dynamic_permalinks` option. * * @param bool $value The value of the `dynamic_permalinks` option. */ return (bool) \apply_filters( 'wpseo_dynamic_permalinks_enabled', $this->options_helper->get( 'dynamic_permalinks', false ) ); } /** * Sets a boolean to indicate that the indexing of the indexables has completed. * * @return void */ public function finish_indexing() { $this->options_helper->set( 'indexables_indexing_completed', true ); } /** * Checks whether the indexable has default values in given fields. * * @param Indexable $indexable The Yoast indexable that we're checking. * @param array $fields The Yoast indexable fields that we're checking against. * * @return bool Whether the indexable has default values. */ public function check_if_default_indexable( $indexable, $fields ) { foreach ( $fields as $field ) { $is_default = $this->check_if_default_field( $indexable, $field ); if ( ! $is_default ) { break; } } return $is_default; } /** * Checks if an indexable field contains the default value. * * @param Indexable $indexable The Yoast indexable that we're checking. * @param string $field The field that we're checking. * * @return bool True if default value. */ public function check_if_default_field( $indexable, $field ) { $defaults = $this->default_values; if ( ! isset( $defaults[ $field ] ) ) { return false; } if ( $indexable->$field === $defaults[ $field ]['default_value'] ) { return true; } return false; } /** * Saves and returns an indexable (on production environments only). * * Moved from Yoast\WP\SEO\Builders\Indexable_Builder. * * @param Indexable $indexable The indexable. * @param Indexable|null $indexable_before The indexable before possible changes. * * @return bool True if default value. */ public function save_indexable( $indexable, $indexable_before = null ) { if ( ! $this->should_index_indexable( $indexable ) ) { return $indexable; } // Save the indexable before running the WordPress hook. $indexable->save(); if ( $indexable_before ) { /** * Action: 'wpseo_save_indexable' - Allow developers to perform an action * when the indexable is updated. * * @param Indexable $indexable The saved indexable. * @param Indexable $indexable_before The indexable before saving. */ \do_action( 'wpseo_save_indexable', $indexable, $indexable_before ); } return $indexable; } } PK]E\*+author-archive-helper.phpnuW+Aoptions_helper = $options_helper; $this->post_type_helper = $post_type_helper; } /** * Gets the array of post types that are shown on an author's archive. * * @return array The post types that are shown on an author's archive. */ public function get_author_archive_post_types() { /** * Filters the array of post types that are shown on an author's archive. * * @param array $args The post types that are shown on an author archive. */ return \apply_filters( 'wpseo_author_archive_post_types', [ 'post' ] ); } /** * Returns whether the author has at least one public post. * * @param int $author_id The author ID. * * @return bool|null Whether the author has at least one public post. */ public function author_has_public_posts( $author_id ) { // First check if the author has at least one public post. $has_public_post = $this->author_has_a_public_post( $author_id ); if ( $has_public_post ) { return true; } // Then check if the author has at least one post where the status is the same as the global setting. $has_public_post_depending_on_the_global_setting = $this->author_has_a_post_with_is_public_null( $author_id ); if ( $has_public_post_depending_on_the_global_setting ) { return null; } return false; } /** * Returns whether the author has at least one public post. * * **Note**: It uses WP_Query to determine the number of posts, * not the indexables table. * * @param string $user_id The user ID. * * @return bool Whether the author has at least one public post. */ public function author_has_public_posts_wp( $user_id ) { $post_types = \array_intersect( $this->get_author_archive_post_types(), $this->post_type_helper->get_indexable_post_types() ); $public_post_stati = \array_values( \array_filter( \get_post_stati(), 'is_post_status_viewable' ) ); $args = [ 'post_type' => $post_types, 'post_status' => $public_post_stati, 'author' => $user_id, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'no_found_rows' => true, 'fields' => 'ids', 'posts_per_page' => 1, ]; $query = new WP_Query( $args ); if ( $query->have_posts() ) { return true; } return false; } /** * Checks whether author archives are disabled. * * @return bool `true` if author archives are disabled, `false` if not. */ public function are_disabled() { return $this->options_helper->get( 'disable-author' ); } /** * Returns whether the author has at least one public post. * * @codeCoverageIgnore It looks for the first ID through the ORM and converts it to a boolean. * * @param int $author_id The author ID. * * @return bool Whether the author has at least one public post. */ protected function author_has_a_public_post( $author_id ) { $cache_key = 'author_has_a_public_post_' . $author_id; $indexable_exists = \wp_cache_get( $cache_key ); if ( $indexable_exists === false ) { $indexable_exists = Model::of_type( 'Indexable' ) ->select( 'id' ) ->where( 'object_type', 'post' ) ->where_in( 'object_sub_type', $this->get_author_archive_post_types() ) ->where( 'author_id', $author_id ) ->where( 'is_public', 1 ) ->find_one(); if ( $indexable_exists === false ) { // Cache no results to prevent full table scanning on authors with no public posts. \wp_cache_set( $cache_key, 0, '', \wp_rand( ( 2 * \HOUR_IN_SECONDS ), ( 4 * \HOUR_IN_SECONDS ) ) ); } } return (bool) $indexable_exists; } /** * Returns whether the author has at least one post with the is public null. * * @codeCoverageIgnore It looks for the first ID through the ORM and converts it to a boolean. * * @param int $author_id The author ID. * * @return bool Whether the author has at least one post with the is public null. */ protected function author_has_a_post_with_is_public_null( $author_id ) { $cache_key = 'author_has_a_post_with_is_public_null_' . $author_id; $indexable_exists = \wp_cache_get( $cache_key ); if ( $indexable_exists === false ) { $indexable_exists = Model::of_type( 'Indexable' ) ->select( 'id' ) ->where( 'object_type', 'post' ) ->where_in( 'object_sub_type', $this->get_author_archive_post_types() ) ->where( 'author_id', $author_id ) ->where_null( 'is_public' ) ->find_one(); if ( $indexable_exists === false ) { // Cache no results to prevent full table scanning on authors with no is public null posts. \wp_cache_set( $cache_key, 0, '', \wp_rand( ( 2 * \HOUR_IN_SECONDS ), ( 4 * \HOUR_IN_SECONDS ) ) ); } } return (bool) $indexable_exists; } } PK]E\S>schema/html-helper.phpnuW+Ais_non_empty_string_or_stringable( $html ) ) { if ( \is_int( $html ) || \is_float( $html ) ) { return (string) $html; } return ''; } return \strip_tags( $html, '