芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/www/wp-content/plugins/leco-client-portal/includes/class-project.php
'closed', 'post_author' => get_current_user_id(), 'post_status' => 'publish', 'post_title' => esc_html__( 'New Portal', 'leco-cp' ), 'post_type' => 'leco_client', 'meta_input' => array(), ); if ( isset( $args['template_id'] ) && ! empty( $args['template_id'] ) ) { $template = get_post( $args['template_id'] ); if ( ! $template ) { return new WP_Error( 'leco_cp_no_template', esc_html__( 'The template doesn\'t exist,', 'leco-cp' ) ); } if ( 'five' === $cp_template ) { $post_args['post_content'] = $template->post_content; } else { $post_args['meta_input']['leco_cp_template'] = $args['template_id']; } } if ( isset( $args['client_id'] ) && ! empty( $args['client_id'] ) ) { if ( ! user_can( $args['client_id'], 'leco_client' ) ) { return new WP_Error( 'leco_cp_not_leco_client', esc_html__( 'The user does not have a CP Client role. Cannot create a portal for them.', 'leco-cp' ) ); } $post_args['meta_input']['leco_cp_client'] = 'five' === $cp_template ? $args['client_id'] : array( $args['client_id'] ); // Get the client project title. if ( isset( $args['post_title'] ) ) { $post_args['post_title'] = $args['post_title']; } else { $project_title = get_user_meta( $args['client_id'], 'leco_cp_user_project_title', true ); if ( ! empty( $project_title ) ) { $post_args['post_title'] = $project_title; } } // Set up the post name with an extra suffix. $post_args['post_name'] = sanitize_title( $post_args['post_title'] ) . '-' . wp_generate_password( 4, false ); } return wp_insert_post( $post_args ); } /** * Get all current published project. * * @since 4.12 * * @return array */ public static function get_all( $match_template = false ) { $args = array( 'post_type' => 'leco_client', 'numberposts' => - 1, 'post_status' => 'publish', ); if ( $match_template ) { $args['meta_query'] = array( array( 'key' => 'leco_cp_part_0_title', 'compare' => leco_client_portal()->is_five() ? 'NOT EXISTS' : 'EXISTS', ), ); } $options = get_posts( $args ); return array_combine( wp_list_pluck( $options, 'ID' ), wp_list_pluck( $options, 'post_title' ) ); } /** * Get project URL. * * @since 4.15 * * @param int $project_id The project ID. * @param string $type The type of URL to get. * * @return false|string|WP_Error */ public static function get_project_url( $project_id, $type = 'client' ) { return 'admin' === $type ? add_query_arg( array( 'action' => 'edit', 'post' => $project_id, ), admin_url( 'post.php' ) ) : get_permalink( $project_id ); } /** * Extract phases from the content. * * @since 5.0 * * @param string $content The content to search for phases. * * @return array */ public static function get_phases( $content ) { $pattern = '//'; preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER ); $phases = []; foreach ( $matches as $match ) { $phases[ (int) $match[3] ] = [ 'title' => $match[1], 'phase' => $match[2], 'uid' => (int) $match[3], ]; } return $phases; } /** * Get the phase title. * * @since 4.15 * @since 5.0 Add support for Five. * * @param int $project_id The project ID. * @param int $phase_index The phase index. * * @return string */ public static function get_phase_title( $project_id, $phase_index ) { if ( leco_client_portal()->is_five( $project_id ) ) { $phases = self::get_phases( get_post_field( 'post_content', $project_id ) ); return $phases[ $phase_index ]['title']; } return get_post_meta( $project_id, "leco_cp_part_{$phase_index}_title", true ); } /** * Get modules. * * In Five, if no p * * @since 4.15 * @since 5.0 Add support for Five. * * @param int $project_id The project ID. * @param int|null $phase_index The phase index. Can be phaseUid in 5.0. * * @return mixed */ public static function get_modules( $project_id, $phase_index ) { if ( leco_client_portal()->is_five( $project_id ) ) { return self::five_get_modules( get_post_field( 'post_content', $project_id ), $phase_index ); } return get_post_meta( $project_id, "leco_cp_part_{$phase_index}_module", true ); } /** * Get modules from a portal content in Five. * * @since 5.0 * * @param string $content The post content. * @param int $phase_uid The uid of a phase. * * @return array */ private static function five_get_modules( $content, $phase_uid = null ) { $phases = []; // Pattern to find all phases. $phase_pattern = '/(.*?)/s'; preg_match_all( $phase_pattern, $content, $phase_matches, PREG_SET_ORDER ); foreach ( $phase_matches as $phase_match ) { $phase_data_str = '{' . $phase_match[1] . '}'; // Reconstruct the JSON string for phase data. $phase_data = json_decode( $phase_data_str, true ); // Extract UID from phase data for identification. $phaseUid = $phase_data['uid'] ?? null; if ( $phaseUid === null ) { continue; // Skip if UID is missing. } if ( $phase_uid ) { if ( $phase_uid !== $phaseUid ) { continue; // Skip if not the phase we want. } } $phase_title = $phase_data['title'] ?? ''; $phase_text = $phase_data['phase'] ?? ''; // Extract modules for this phase. $modulePattern = '//s'; preg_match_all( $modulePattern, $phase_match[2], $moduleMatches, PREG_SET_ORDER ); $modules = []; foreach ( $moduleMatches as $moduleMatch ) { $moduleStr = '{' . $moduleMatch[1] . '}'; // Reconstruct the JSON string for module data. $moduleData = json_decode( $moduleStr, true ); if ( $moduleData ) { // Ensure decoding success. // Add Phase data with it. $moduleData['phase_uid'] = $phaseUid; $moduleData['phase_title'] = $phase_title; $moduleData['phase_text'] = $phase_text; // Default values for missing module data. $moduleData['status'] = $moduleData['status'] ?? 'active'; $moduleData['icon'] = $moduleData['icon'] ?? 'suitcase'; if ( isset( $moduleData['phaseID'] ) ) { $modules[ self::get_new_module_index( $moduleData ) ] = self::restore_module_key_value( $moduleData ); // Add the module's uid to the key because duplicate modules have the same phaseID. } } } if ( $phase_uid === $phaseUid ) { return $modules; } $phases[ $phaseUid ] = $modules; } return $phases; } /** * Get the updated module index. * * @since 5.2.2 * * @param array $module_data The module data. * * @return string */ private static function get_new_module_index( $module_data ) { return $module_data['phaseID'] . $module_data['uid']; } /** * Get the module info. * * @since 4.15 * @since 5.0 Add support for Five. * * @param int $project_id The project ID. * @param int $phase_index The phase ID. * @param int|string $module_index The module ID or the phaseID attribute in Five. * @param string $field The field. * * @return false|mixed */ public static function get_module( $project_id, $phase_index, $module_index, $field = '' ) { if ( leco_client_portal()->is_five( $project_id ) ) { return self::five_get_module( get_post_field( 'post_content', $project_id ), $module_index, $field ); } $modules = self::get_modules( $project_id, $phase_index ); if ( ! $field ) { return isset( $modules[ $module_index ] ) ? $modules[ $module_index ] : false; } else { return isset( $modules[ $module_index ] ) && isset( $modules[ $module_index ][ $field ] ) ? $modules[ $module_index ][ $field ] : false; } } /** * Get a module by phaseID, and modify the module data to include phase data. * * @since 5.0 * * @param string $content The post content. * @param string $module_index The phase ID. * @param string $attribute The attribute to get. * * @return array|string|null */ private static function five_get_module( $content, $module_index, $attribute = '' ) { $all_modules = self::five_get_modules( $content ); foreach ( $all_modules as $phase_modules ) { foreach ( $phase_modules as $k => $module ) { // Module index has been updated to include the module's uid. // See: https://github.com/clientportal/leco-client-portal/blob/6ed62b2ee91108e84f767a21ab3cc9bd78926b3d/includes/class-project.php#L271. if ( $k === $module_index . $module['uid'] ) { if ( ! $attribute ) { return $module; } elseif ( isset( $module[ $attribute ] ) ) { return $module[ $attribute ]; } } } } } /** * Helper method to get module due date in timestamp format. Return 0 if no due date; return -1 if the due date has expired. * * @since 4.16 * * @param int $project_id The project ID. * @param int $phase The phase index. * @param int $module The module index. * @param bool|string $formatted If the value should be formatted. A PHP date format can be passed. * * @return int|string */ public static function get_module_due_date( $project_id, $phase, $module, $formatted = false ) { $due_date = self::get_module( $project_id, $phase, $module, 'due_date' ); if ( ! $due_date ) { return 0; } if ( ! leco_client_portal()->is_five( $project_id ) ) { $has_due_date = $due_date && $due_date['enabled'] && $due_date['date'] && $due_date['time'] && ( '0' !== $due_date['reminder'] ); if ( ! $has_due_date ) { return 0; } } $utc_time = Due_Date::date_create_from_format( $due_date, wp_timezone() ); if ( ! $utc_time ) { return 0; } $timestamp = $utc_time->getTimestamp(); if ( $timestamp < time() ) { return -1; } if ( $formatted ) { if ( true === $formatted ) { $formatted = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); } return wp_date( $formatted, $timestamp ); } return $timestamp; } /** * Get the client ID. * * @since 5.0 * * @param int $project_id The project ID. * * @return mixed */ public static function get_client( $project_id ) { return get_post_meta( $project_id, 'leco_cp_client', true ); } /** * Check if it's a valid project. * * @since 4.16 * * @param int $project_id The project ID. * * @return bool */ public static function is_valid( $project_id ) { $project = get_post( $project_id ); if ( ! $project || 'publish' !== $project->post_status || 'leco_client' !== $project->post_type ) { return false; } return true; } /** * Restore the module key. * * @since 5.0 * * @param array $module_data The module data. * * @return array */ private static function restore_module_key_value( $module_data ) { $new_tab = $module_data['openTab'] ?? ( 'current' != leco_cp_get_option( 'new_tab', 'new_tab' ) ? 'yes' : 'no' ); $module_data['new_tab'] = 'yes' === $new_tab ? 'new_tab' : 'current'; unset( $module_data['openTab'] ); $module_data['type'] = isset( $module_data['moduleType'] ) ? str_replace( 'module-', '', $module_data['moduleType'] ) : 'links'; unset( $module_data['moduleType'] ); foreach ( $module_data as $key => $value ) { $arr = array( 'modulePrivateFiles', 'moduleFiles', 'moduleClientUploads', 'moduleContentPage' ); if ( in_array( $key, $arr ) ) { $module_data[ str_replace( 'module_', '', self::camel_to_snake( $key ) ) ] = $value; unset( $module_data[ $key ] ); } } if ( isset( $module_data['moduleDueDate'] ) ) { $module_data['due_date'] = $module_data['moduleDueDate']; unset( $module_data['moduleDueDate'] ); } return $module_data; } /** * Update camel case to snake case. * * @since 5.0 * * @param string $string The string to convert. * * @return string */ private static function camel_to_snake( $string ) { // Use a regular expression to find capital letters within the string // and insert an underscore before them. $result = preg_replace( '/(?<=[a-z])([A-Z])/', '_$1', $string ); // Convert the entire result to lowercase. return strtolower( $result ); } /** * Get the module's URL. * * @todo Support the content page module. * * @since 5.2.1 * * @param array $module The module data. * * @return string */ public static function get_module_url( array $module ): string { $type = $module['type'] ?? 'links'; $url = get_permalink() . "#m_{$module['phase_uid']}_{$module['uid']}"; if ( 'links' !== $type ) { return $url; } if ( ! empty( $module['moduleLinks'] ) && count( $module['moduleLinks'] ) === 1 ) { $url = $module['moduleLinks'][0]['linkUrl']; } return $url; } }