Plugin Directory

Changeset 3472041


Ignore:
Timestamp:
03/01/2026 11:38:44 AM (4 weeks ago)
Author:
castromind
Message:

Release version 1.1.0

Location:
jorgecastro/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • jorgecastro/trunk/classes/Blog/Handler.php

    r3465575 r3472041  
    612612        }
    613613    }
     614
     615    /**
     616     * Update an existing blog post
     617     *
     618     * @param int $postId Post ID to update
     619     * @param array $postData New post data
     620     * @return int|\WP_Error Post ID on success, WP_Error on failure
     621     */
     622    public function updatePost($postId, $postData)
     623    {
     624        $post = get_post($postId);
     625        if (!$post || $post->post_type !== 'post') {
     626            return new \WP_Error('post_not_found', 'Post not found or invalid type');
     627        }
     628
     629        $postArgs = [
     630            'ID' => $postId,
     631        ];
     632
     633        if (isset($postData['title'])) {
     634            $postArgs['post_title'] = sanitize_text_field($postData['title']);
     635        }
     636       
     637        $postContent = null;
     638        if (isset($postData['content'])) {
     639            $postContent = wp_kses_post($postData['content']);
     640            $postArgs['post_content'] = $postContent;
     641        }
     642
     643        if (isset($postData['excerpt'])) {
     644            $postArgs['post_excerpt'] = sanitize_textarea_field($postData['excerpt']);
     645        }
     646
     647        if (isset($postData['status'])) {
     648            $allowedStatuses = ['publish', 'draft', 'pending', 'private', 'trash'];
     649            if (in_array($postData['status'], $allowedStatuses)) {
     650                $postArgs['post_status'] = $postData['status'];
     651            }
     652        }
     653
     654        if (isset($postData['date'])) {
     655            $postArgs['post_date'] = sanitize_text_field($postData['date']);
     656        }
     657       
     658        if (isset($postData['author_id'])) {
     659            $postArgs['post_author'] = (int) $postData['author_id'];
     660        }
     661
     662        // Update post basics
     663        $updatedId = wp_update_post($postArgs, true);
     664
     665        if (is_wp_error($updatedId)) {
     666            return $updatedId;
     667        }
     668
     669        // Set categories
     670        if (isset($postData['categories']) && is_array($postData['categories'])) {
     671            $this->setCategories($postId, $postData['categories']);
     672        }
     673
     674        // Set tags
     675        if (isset($postData['tags']) && is_array($postData['tags'])) {
     676            $this->setTags($postId, $postData['tags']);
     677        }
     678
     679        // Process images if content updated
     680        $hasFeaturedImage = isset($postData['featured_image'])
     681            && $postData['featured_image'] !== null
     682            && $postData['featured_image'] !== ''
     683            && !empty(trim($postData['featured_image']));
     684
     685        if ($postContent !== null) {
     686            $processedContent = $this->processContentImages($postContent, $postId, !$hasFeaturedImage && !has_post_thumbnail($postId));
     687            if ($processedContent !== $postContent) {
     688                wp_update_post([
     689                    'ID' => $postId,
     690                    'post_content' => wp_slash($processedContent)
     691                ]);
     692            }
     693        }
     694
     695        // Set featured image
     696        if ($hasFeaturedImage) {
     697            $this->setFeaturedImage($postId, $postData['featured_image']);
     698        }
     699
     700        // Set post meta
     701        if (isset($postData['meta']) && is_array($postData['meta'])) {
     702            $this->setPostMeta($postId, $postData['meta']);
     703        }
     704
     705        // Set SEO meta
     706        if (isset($postData['seo'])) {
     707            $this->setSEOMeta($postId, $postData['seo']);
     708        }
     709       
     710        // Update generation time meta flag
     711        update_post_meta($postId, '_jorgecastro_updated_at', current_time('mysql'));
     712
     713        return $postId;
     714    }
     715
     716    /**
     717     * Delete a blog post
     718     *
     719     * @param int $postId Post ID to delete
     720     * @param bool $force Force delete bypassing trash (default false)
     721     * @return bool|\WP_Error True on success, WP_Error on failure
     722     */
     723    public function deletePost($postId, $force = false)
     724    {
     725        $post = get_post($postId);
     726        if (!$post || $post->post_type !== 'post') {
     727            // Check if it's already deleted/invalid
     728            return new \WP_Error('post_not_found', 'Post not found or already deleted');
     729        }
     730
     731        $result = wp_delete_post($postId, $force);
     732       
     733        if ($result === false || $result === null) {
     734            return new \WP_Error('delete_failed', 'Failed to delete post');
     735        }
     736
     737        return true;
     738    }
    614739}
    615740
  • jorgecastro/trunk/jorgecastro.php

    r3467372 r3472041  
    22
    33/**
    4  * @link              https://your-saas-app.com/
     4 * @link              https://saas.jorgecastro.ai
    55 * @since             1.0.0
    66 * @package           jorgeCastro
     
    1010 * Plugin URI:        https://wordpress.org/plugins/jorgecastro/
    1111 * Description:       Modern SEO with AI – create SEO texts that rank and increase your visibility. Get more customers, even in AI-powered search results, without needing to know SEO.
    12  * Version:           1.0.0
     12 * Version:           1.1.0
    1313 * Author:            JorgeCastro
    1414 * Author URI:        https://jorgecastro.ai/
     
    3333        public $plugin_path;
    3434        public $plugin_url;
    35         public $version = '1.0.0';
     35        public $version = '1.1.0';
    3636       
    3737        /**
     
    180180                'methods' => 'POST',
    181181                'callback' => [$this, 'restBulkPosts'],
     182                'permission_callback' => [$this, 'jorgecastro_rest_permission_callback']
     183            ]);
     184            register_rest_route($this->getRestNamespace(), '/posts/update', [
     185                'methods' => 'POST',
     186                'callback' => [$this, 'restUpdatePost'],
     187                'permission_callback' => [$this, 'jorgecastro_rest_permission_callback']
     188            ]);
     189            register_rest_route($this->getRestNamespace(), '/posts/delete', [
     190                'methods' => 'POST',
     191                'callback' => [$this, 'restDeletePost'],
    182192                'permission_callback' => [$this, 'jorgecastro_rest_permission_callback']
    183193            ]);
     
    342352
    343353        /**
     354         * REST endpoint to update an existing blog post
     355         * API key validation handled by permission_callback
     356         *
     357         * @param WP_REST_Request $request
     358         * @return WP_REST_Response|WP_Error
     359         */
     360        public function restUpdatePost($request)
     361        {
     362            $post = $request->get_json_params();
     363
     364            // Sanitize input data
     365            $post = $this->sanitizeWebhookData($post);
     366
     367            if (!isset($post['post_id']) || !is_numeric($post['post_id'])) {
     368                return new WP_REST_Response([
     369                    'success' => false,
     370                    'error' => 'Valid Post ID is required'
     371                ], 400);
     372            }
     373
     374            if (!isset($post['post_data']) || !is_array($post['post_data'])) {
     375                return new WP_REST_Response([
     376                    'success' => false,
     377                    'error' => 'post_data array is required'
     378                ], 400);
     379            }
     380
     381            // Update post in WordPress
     382            require_once($this->plugin_path . 'classes/Blog/Handler.php');
     383            $blogHandler = new \JorgeCastro\Blog\Handler($this);
     384            $result = $blogHandler->updatePost((int) $post['post_id'], $post['post_data']);
     385
     386            if (is_wp_error($result)) {
     387                return new WP_REST_Response([
     388                    'success' => false,
     389                    'error' => $result->get_error_message()
     390                ], 400);
     391            }
     392
     393            return new WP_REST_Response([
     394                'success' => true,
     395                'post_id' => $result
     396            ], 200);
     397        }
     398
     399        /**
     400         * REST endpoint to delete an existing blog post
     401         * API key validation handled by permission_callback
     402         *
     403         * @param WP_REST_Request $request
     404         * @return WP_REST_Response|WP_Error
     405         */
     406        public function restDeletePost($request)
     407        {
     408            $post = $request->get_json_params();
     409
     410            // Sanitize input data
     411            $post = $this->sanitizeWebhookData($post);
     412
     413            if (!isset($post['post_id']) || !is_numeric($post['post_id'])) {
     414                return new WP_REST_Response([
     415                    'success' => false,
     416                    'error' => 'Valid Post ID is required'
     417                ], 400);
     418            }
     419
     420            $force = isset($post['force']) ? (bool) $post['force'] : false;
     421
     422            // Delete post in WordPress
     423            require_once($this->plugin_path . 'classes/Blog/Handler.php');
     424            $blogHandler = new \JorgeCastro\Blog\Handler($this);
     425            $result = $blogHandler->deletePost((int) $post['post_id'], $force);
     426
     427            if (is_wp_error($result)) {
     428                return new WP_REST_Response([
     429                    'success' => false,
     430                    'error' => $result->get_error_message()
     431                ], 400);
     432            }
     433
     434            return new WP_REST_Response([
     435                'success' => true,
     436                'message' => 'Post deleted successfully'
     437            ], 200);
     438        }
     439
     440        /**
    344441         * REST endpoint to get all WooCommerce products
    345442         * API key validation handled by permission_callback
  • jorgecastro/trunk/readme.txt

    r3467376 r3472041  
    55Requires at least: 5.0
    66Requires PHP: 7.2
    7 Stable tag: 1.0.0
     7Stable tag: 1.1.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    147147== Changelog ==
    148148
     149= 1.1.0 =
     150* Setup REST API endpoints to update blog posts dynamically.
     151* Setup REST API endpoints to delete blog posts.
     152
    149153= 1.0.0 =
    150154* Initial release.
     
    156160== Upgrade Notice ==
    157161
     162= 1.1.0 =
     163Added APIs to manage the lifecycle of blog posts automatically including updating and deleting.
     164
    158165= 1.0.0 =
    159166Initial release of JorgeCastro - The complete AI SEO Agent.
Note: See TracChangeset for help on using the changeset viewer.