Plugin Directory

Changeset 3231549


Ignore:
Timestamp:
01/29/2025 08:16:00 PM (13 months ago)
Author:
bikkel
Message:

tagging version 2.3.0

Location:
news-parser
Files:
642 added
25 edited

Legend:

Unmodified
Added
Removed
  • news-parser/trunk/bootstrap.php

    r3205095 r3231549  
    4646
    4747    $app->middleware->add('NewsParserPlugin\Parser\HTMLRaw:parse:parse',array(
    48       $app->DI_container->get(Modifiers\RemoveLineBreaks::class),
    4948      $app->DI_container->get(Modifiers\ReplaceRelativePathWithAbsolute::class),
    50       $app->DI_container->get(Modifiers\ImagePrepare::class)
     49      $app->DI_container->get(Modifiers\ImagePrepare::class),
     50      $app->DI_container->get(Modifiers\ReplaceYoutubeFrames::class),
     51      $app->DI_container->get(Modifiers\RemoveLineBreaks::class)
    5152   ));
    5253
     
    8687    $app->event->on('posts:data',array(Controller\PostController::class,'getPostsData'));
    8788    $app->event->on('posts:update',array(Controller\PostController::class,'update'));
     89    $app->event->on('posts:delete',array(Controller\PostController::class,'delete'));
     90    $app->event->on('template:test',array(Controller\TestSettingsController::class,'testTemplate'));
    8891   
    8992
  • news-parser/trunk/inc/Api/Ajax/AjaxApiEndpoint.php

    r3049937 r3231549  
    22namespace NewsParserPlugin\Api\Ajax;
    33
    4 use NewsParserPlugin\Traits\ValidateDataTrait;
    5 use NewsParserPlugin\Traits\SanitizeDataTrait;
    64use NewsParserPlugin\Ajax\Ajax;
     5use NewsParserPlugin\Exception\MyException;
    76use NewsParserPlugin\Interfaces\EventControllerInterface;
    87use NewsParserPlugin\Message\Errors;
    98use NewsParserPlugin\Message\Success;
    10 use NewsParserPlugin\Exception\MyException;
     9use NewsParserPlugin\Traits\SanitizeDataTrait;
     10use NewsParserPlugin\Traits\ValidateDataTrait;
    1111
    1212/**
     
    5858    protected function __construct(EventControllerInterface $event)
    5959    {
    60         $this->event=$event;
     60        $this->event = $event;
    6161        $this->init();
    62         $this->formatter=$this->getFormatter();
     62        $this->formatter = $this->getFormatter();
    6363    }
    6464    /**
     
    7070    public static function create(EventControllerInterface $event)
    7171    {
    72        
     72
    7373        if (static::$instance) {
    7474            return static::$instance;
     
    8686    protected function init()
    8787    {
    88         \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_list', array($this, 'parsingListApi'));
    89         \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_html', array($this, 'parsingHTMLApi'));
    90         \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_page', array($this, 'parsingPageApi'));
     88        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API . '_list', array($this, 'parsingListApi'));
     89        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API . '_html', array($this, 'parsingHTMLApi'));
     90        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API . '_test_template', array($this, 'testTemplateApi'));
     91        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API . '_page', array($this, 'parsingPageApi'));
    9192        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_MEDIA_API, array($this, 'mediaApi'));
    9293        \add_action('wp_ajax_' . NEWS_PARSER_PLUGIN_AJAX_TEMPLATE_API, array($this, 'templateApi'));
    9394    }
    94  
     95
    9596    /**
    9697     * Check if user have relevant rights  and check nonce.
     
    105106            return new \WP_Error('ajax_forbidden', Errors::text('NO_RIGHTS_TO_PUBLISH'));
    106107        }
    107         if (!\wp_verify_nonce($request_args['_wpnonce'], $action)||!\is_admin()) {
     108        if (!\wp_verify_nonce($request_args['_wpnonce'], $action) || !\is_admin()) {
    108109            return new \WP_Error('ajax_forbidden', Errors::text('NO_RIGHTS_TO_PUBLISH'));
    109110        }
    110111        return true;
    111112    }
    112     protected function sendErrorResponse(MyException $e){
    113         $error_data=$this->formatter->error($e->getCode())->message('error', $e->getMessage())->get('array');
    114         $error_code=$e->getCode()?$e->getCode():500;
    115         $this->sendError($error_data,$error_code);
     113    protected function sendErrorResponse(MyException $e)
     114    {
     115        $error_data = $this->formatter->error($e->getCode())->message('error', $e->getMessage())->get('array');
     116        $error_code = $e->getCode() ? $e->getCode() : 500;
     117        $this->sendError($error_data, $error_code);
    116118    }
    117119    /**
     
    130132        $json_post = $this->getJsonFromInput();
    131133        $this->checkPermission('parsing_news_api', $json_post);
    132         $request=$this->prepareArgs($json_post, array(
    133                 'url'=>array(
    134                     'description'=>'Featured image url.',
    135                     'type'=>'string',
    136                     'validate_callback'=>array($this,'validateImageUrl'),
    137                     'sanitize_callback'=>function ($input_url) {
    138                         return esc_url_raw($input_url);
    139                     }
    140                 ),
    141                 'options'=>array(
    142                     'description'=>'Featured image options.',
    143                     'type'=>'array',
    144                     'validate_callback'=>array($this,'validateMediaOptions'),
    145                     'sanitize_callback'=>array($this,'sanitizeMediaOptions')
    146                 )
    147         ));
    148         try {
    149             $media_id=$this->event->trigger('media:create', array($request['url'],$request['options']['post_id'],$request['options']['alt']));
     134        $request = $this->prepareArgs($json_post, array(
     135            'url' => array(
     136                'description' => 'Featured image url.',
     137                'type' => 'string',
     138                'validate_callback' => array($this, 'validateImageUrl'),
     139                'sanitize_callback' => function ($input_url) {
     140                    return esc_url_raw($input_url);
     141                },
     142            ),
     143            'options' => array(
     144                'description' => 'Featured image options.',
     145                'type' => 'array',
     146                'validate_callback' => array($this, 'validateMediaOptions'),
     147                'sanitize_callback' => array($this, 'sanitizeMediaOptions'),
     148            ),
     149        ));
     150        try {
     151            $media_id = $this->event->trigger('media:create', array($request['url'], $request['options']['post_id'], $request['options']['alt']));
    150152            $this->sendResponse($this->formatter->media($media_id)->message('success', Success::text('FEATURED_IMAGE_SAVED'))->get('array'));
    151153        } catch (MyException $e) {
     
    153155        }
    154156    }
    155    
     157
    156158    /**
    157159     * Callback that handles parsing list of posts from RSS api requests.
     
    166168        $this->checkPermission('parsing_news_api', $json_post);
    167169        //ToDo:Make redirect to main page when parameter is missing.
    168      
    169         $request=$this->prepareArgs($json_post, array(
    170             'url'=>array(
    171                 'description'=>'Parsing RSS XML list url',
    172                 'type'=>'string',
    173                 'validate_callback'=>function ($url) {
    174                     return wp_http_validate_url($url);
    175                 },
    176                 'sanitize_callback'=>function ($input_url) {
    177                     return esc_url_raw($input_url);
    178                 }
    179             )
    180         ));
    181        
    182 
    183         try{
     170
     171        $request = $this->prepareArgs($json_post, array(
     172            'url' => array(
     173                'description' => 'Parsing RSS XML list url',
     174                'type' => 'string',
     175                'validate_callback' => function ($url) {
     176                    return wp_http_validate_url($url);
     177                },
     178                'sanitize_callback' => function ($input_url) {
     179                    return esc_url_raw($input_url);
     180                },
     181            ),
     182        ));
     183
     184        try {
    184185            $response = $this->event->trigger('list:get', array($request['url']));
    185186            $this->sendResponse($this->formatter->rss($response)->message('success', Success::text('RSS_LIST_PARSED'))->get('array'));
    186         }catch (MyException $e){
    187             $this->sendErrorResponse($e);
    188         }
    189     }
    190    
    191      /**
     187        } catch (MyException $e) {
     188            $this->sendErrorResponse($e);
     189        }
     190    }
     191
     192    /**
    192193     * Callback that handles parsing single page api requests and returns HTML of the page.
    193194     *
     
    201202        $this->checkPermission('parsing_news_api', $json_post);
    202203        //ToDo:Make redirect to main page when parameter is missing.
    203      
    204         $request=$this->prepareArgs($json_post, array(
    205             'url'=>array(
    206                 'description'=>'Parsing page url',
    207                 'type'=>'string',
    208                 'validate_callback'=>function ($url) {
    209                     return wp_http_validate_url($url);
    210                 },
    211                 'sanitize_callback'=>function ($input_url) {
    212                     return esc_url_raw($input_url);
    213                 }
    214             )
    215         ));
    216         $request_url=$request['url'];
    217         try{
     204
     205        $request = $this->prepareArgs($json_post, array(
     206            'url' => array(
     207                'description' => 'Parsing page url',
     208                'type' => 'string',
     209                'validate_callback' => function ($url) {
     210                    return wp_http_validate_url($url);
     211                },
     212                'sanitize_callback' => function ($input_url) {
     213                    return esc_url_raw($input_url);
     214                },
     215            ),
     216        ));
     217        $request_url = $request['url'];
     218        try {
    218219            $html = $this->event->trigger('html:get', array($request_url));
    219             $response=array(
    220                 'html'=>$html,
    221                 'url'=>$request_url
     220            $response = array(
     221                'html' => $html,
     222                'url' => $request_url,
    222223            );
    223224            $this->sendResponse($this->formatter->rawHTML($response)->get('array'));
    224         }catch (MyException $e){
    225             $this->sendErrorResponse($e);
    226         }
    227        
    228     }
    229      /**
     225        } catch (MyException $e) {
     226            $this->sendErrorResponse($e);
     227        }
     228
     229    }
     230    /**
     231     * Callback that handles parsing single page to test template settings.
     232     *
     233     * @uses EventController::trigger()
     234     * @return void
     235     */
     236    public function testTemplateApi()
     237    {
     238        //Get application\json encode data
     239        $json_post = $this->getJsonFromInput();
     240        $this->checkPermission('parsing_news_api', $json_post);
     241        //ToDo:Make redirect to main page when parameter is missing.
     242
     243        $request = $this->prepareArgs($json_post, array(
     244            'url' => array(
     245                'description' => 'Parsing page url',
     246                'type' => 'string',
     247                'validate_callback' => function ($url) {
     248                    return wp_http_validate_url($url);
     249                },
     250                'sanitize_callback' => function ($input_url) {
     251                    return esc_url_raw($input_url);
     252                },
     253            ),
     254            'template' => array(
     255                'description' => 'Parsing page template',
     256                'type' => 'array',
     257                'validate_callback' => function ($template) {
     258                    return $template;
     259                },
     260                'sanitize_callback' => function ($template) {
     261                    return $template;
     262                },
     263            ),
     264        ));
     265        $request_url = $request['url'];
     266        $template = $request['template'];
     267        try {
     268            $post = $this->event->trigger('template:test', array($request_url, $template));
     269            $response = array(
     270                'title' => $post['title'],
     271                'image' => $post['image'],
     272                'body' => $post['body']
     273            );
     274            $this->sendResponse($this->formatter->postTest($response)->get('array'));
     275        } catch (MyException $e) {
     276            $this->sendErrorResponse($e);
     277        }
     278
     279    }
     280    /**
    230281     * Callback that handles parsing single page api requests and create WP post draft using saved parsing templates.
    231282     * If there is no template for that domain name returns error.
     
    240291        $this->checkPermission('parsing_news_api', $json_post);
    241292        //ToDo:Make redirect to main page when parameter is missing.
    242      
    243         $request=$this->prepareArgs($json_post, array(
    244             'url'=>array(
    245                 'description'=>'Parsing page url',
    246                 'type'=>'string',
    247                 'validate_callback'=>function ($url) {
    248                     return wp_http_validate_url($url);
    249                 },
    250                 'sanitize_callback'=>function ($input_url) {
    251                     return esc_url_raw($input_url);
    252                 }
    253             ),
    254             '_id'=>array(
    255                 'description'=>'Front end requested page index',
    256                 'type'=>'integer',
    257                 'validate_callback'=>function ($_id) {
     293
     294        $request = $this->prepareArgs($json_post, array(
     295            'url' => array(
     296                'description' => 'Parsing page url',
     297                'type' => 'string',
     298                'validate_callback' => function ($url) {
     299                    return wp_http_validate_url($url);
     300                },
     301                'sanitize_callback' => function ($input_url) {
     302                    return esc_url_raw($input_url);
     303                },
     304            ),
     305            '_id' => array(
     306                'description' => 'Front end requested page index',
     307                'type' => 'integer',
     308                'validate_callback' => function ($_id) {
    258309                    preg_match('/[^0-9]/i', $_id, $matches);
    259310                    if (empty($matches)) {
     
    263314                    }
    264315                },
    265                 'sanitize_callback'=>function ($_id) {
     316                'sanitize_callback' => function ($_id) {
    266317                    return preg_replace('/[^0-9]/i', '', $_id);
    267                 }
    268             ),
    269             'templateUrl'=>array(
    270                 'description'=>'Url that identifies template',
    271                 'type'=>'string',
    272                 'validate_callback'=>function ($url) {
    273                     return wp_http_validate_url($url);
    274                 },
    275                 'sanitize_callback'=>function ($input_url) {
    276                     return esc_url_raw($input_url);
    277                 }
    278             ),
    279         ));
    280         try{
    281             $response=$this->event->trigger('post:create', array($request['url'],$request['_id'],$request['templateUrl']));
     318                },
     319            ),
     320            'templateUrl' => array(
     321                'description' => 'Url that identifies template',
     322                'type' => 'string',
     323                'validate_callback' => function ($url) {
     324                    return wp_http_validate_url($url);
     325                },
     326                'sanitize_callback' => function ($input_url) {
     327                    return esc_url_raw($input_url);
     328                },
     329            ),
     330        ));
     331        try {
     332            $response = $this->event->trigger('post:create', array($request['url'], $request['_id'], $request['templateUrl']));
    282333            $this->sendResponse($this->formatter->post($response)->message('success', sprintf(Success::text('POST_SAVED'), $response['title']))->addCustomData('_id', $request['_id'])->get('array'));
    283334        } catch (MyException $e) {
  • news-parser/trunk/inc/Config/di-config.php

    r3205095 r3231549  
    1212    Parser\XMLParser::class=>[],
    1313    Parser\HTMLRaw::class=>[],
    14     Parser\HTMLPatternParser::class=>[],
     14    Parser\HTMLPatternParser::class=>[[new Parser\ParserSyntaxExtenders\TextContent()]],
    1515    Models\TemplateModel::class=>[],
    1616    Models\AIOptionsModel::class=>[],
     
    3939    Modifiers\ReplaceRelativePathWithAbsolute::class=>[],
    4040    Modifiers\ImagePrepare::class=>[],
     41    Modifiers\ReplaceYoutubeFrames::class=>[],
    4142    Parser\Modifiers\PostModifiers\AddPostThumbnailModifier::class=>[],
    4243    Controller\PostController::class=>[Parser\HTMLPatternParser::class,Utils\AdapterGuttenberg::class,Models\TemplateModel::class,Models\PostModel::class],
     
    4445    Controller\VisualConstructorController::class=>[Parser\HTMLRaw::class],
    4546    Controller\MediaController::class=>[Models\PostModel::class],
     47    Controller\TestSettingsController::class=>[Parser\HTMLPatternParser::class,Utils\AdapterGuttenberg::class]
    4648);
  • news-parser/trunk/inc/Config/global-variables-config-dev.php

    r3201219 r3231549  
    2323    'list'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_list')),
    2424    'rawHTML'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_html')),
     25    'templateTest'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_test_template')),
    2526    NEWS_PARSER_PLUGIN_PARSER_RSS.'.page'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_page')),
    2627    NEWS_PARSER_PLUGIN_VISUAL_CONSTRUCTOR.'.template'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_TEMPLATE_API)),
     
    7071        )
    7172    ),
     73    /*
     74    $menu_config->menu->subs[3]->menu_slug=>array(
     75        array(
     76            'script_name'=>'main-parser-edit-template-bundle',
     77            'position'=>'before',
     78            'data'=>"window.newsParserSettings=".json_encode($nonce)
     79        ),
     80        array(
     81            'script_name'=>'main-parser-edit-template-bundle',
     82            'position'=>'before',
     83            'data'=>"window.newsParserApiEndpoints=".json_encode($rest_api_endpoints)
     84        )
     85    ),
     86    */
    7287    $menu_config->menu->subs[3]->menu_slug=>array(
    7388   
  • news-parser/trunk/inc/Config/global-variables-config.php

    r3201219 r3231549  
    2323    'list'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_list')),
    2424    'rawHTML'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_html')),
     25    'templateTest'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_test_template')),
    2526    NEWS_PARSER_PLUGIN_PARSER_RSS.'.page'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_PARSING_API.'_page')),
    2627    NEWS_PARSER_PLUGIN_VISUAL_CONSTRUCTOR.'.template'=>esc_url_raw(admin_url('admin-ajax.php?action=' . NEWS_PARSER_PLUGIN_AJAX_TEMPLATE_API)),
     
    8283        )
    8384    ),
     85    /*
     86    $menu_config->menu->subs[3]->menu_slug=>array(
     87        array(
     88            'script_name'=>'main-parser-edit-template-bundle',
     89            'position'=>'before',
     90            'data'=>"window.newsParserSettings=".json_encode($nonce)
     91        ),
     92        array(
     93            'script_name'=>'main-parser-edit-template-bundle',
     94            'position'=>'before',
     95            'data'=>"window.newsParserApiEndpoints=".json_encode($rest_api_endpoints)
     96        )
     97    ),
     98    */
    8499    $menu_config->menu->subs[3]->menu_slug=>array(
    85100   
  • news-parser/trunk/inc/Config/menu-config.php

    r3201219 r3231549  
    4040                'template' => NEWS_PARSER_PLUGIN_DIR . '/template/menu/autopilot-page-menu.php',
    4141            ),
     42            /*
    4243             array(
     44                'page_title' => 'SEO Integration',
     45                'parent_slug' => NEWS_PARSER_PLUGIN_SLUG . '-main-menu',
     46                'menu_title' => __('SEO Integration', 'news-parser'),
     47                'capability' => 'manage_options',
     48                'menu_slug' => NEWS_PARSER_PLUGIN_SLUG . '-menu-seo-integration',
     49                'template' => NEWS_PARSER_PLUGIN_DIR . '/template/menu/seo-integration-menu.php',
     50            ),
     51            */
     52            array(
    4353                'page_title' => 'About News Parser',
    4454                'parent_slug' => NEWS_PARSER_PLUGIN_SLUG . '-main-menu',
  • news-parser/trunk/inc/Config/scripts-config-dev.php

    r3201219 r3231549  
    3030        )
    3131    ),
     32    /*
     33    $menu_config->menu->subs[3]->menu_slug=>array(
     34        'main-parser-edit-template-bundle'=>array(
     35            'path'=>NEWS_PARSER_PLUGIN_URL.'/public/js/seo_integration-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
     36            'depends_on'=>array('wp-i18n')
     37        )
     38    ),
     39    */
    3240    $menu_config->menu->subs[3]->menu_slug=>array(
    3341   
  • news-parser/trunk/inc/Config/scripts-config.php

    r3205095 r3231549  
    1010    'global'=>array(),
    1111    'shared'=> array(
    12         NEWS_PARSER_PLUGIN_SLUG . '-179-chunk'=>array(
    13             'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/179-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
     12        NEWS_PARSER_PLUGIN_SLUG . '-277-chunk'=>array(
     13            'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/277-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
     14            'depends_on'=>array()
     15        ),
     16        NEWS_PARSER_PLUGIN_SLUG . '-479-chunk'=>array(
     17            'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/479-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
    1418            'depends_on'=>array()
    1519        ),
     
    1822            'depends_on'=>array()
    1923        ),
    20         NEWS_PARSER_PLUGIN_SLUG . '-675-chunk'=>array(
    21             'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/675-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
    22             'depends_on'=>array()
    23         ),
    24         NEWS_PARSER_PLUGIN_SLUG . '-931-chunk'=>array(
    25             'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/931-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
     24        NEWS_PARSER_PLUGIN_SLUG . '-707-chunk'=>array(
     25            'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/707-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
    2626            'depends_on'=>array()
    2727        ),
     
    4949        )
    5050    ),
     51    /*
     52    $menu_config->menu->subs[3]->menu_slug=>array(
     53        'main-parser-edit-template-bundle'=>array(
     54            'path'=>NEWS_PARSER_PLUGIN_URL . '/public/js/seo_integration-'.NEWS_PARSER_PLUGIN_VERSION.'.bundle.js',
     55            'depends_on'=>array('wp-i18n')
     56        )
     57    ),
     58    */
    5159    $menu_config->menu->subs[3]->menu_slug=>array(
    5260   
  • news-parser/trunk/inc/Config/scripts-translation-config.php

    r3201219 r3231549  
    1313        'main-parser-autopilot-bundle'=>NEWS_PARSER_PLUGIN_SLUG
    1414    ),
     15    /*
     16    $menu_config->menu->subs[3]->menu_slug=>array(
     17        'main-parser-seo-integration-bundle'=>NEWS_PARSER_PLUGIN_SLUG
     18    ),
     19    */
    1520    $menu_config->menu->subs[3]->menu_slug=>array(
    1621    )
  • news-parser/trunk/inc/Config/styles-config-dev.php

    r3201219 r3231549  
    2626        NEWS_PARSER_PLUGIN_SLUG . '-autopilot'=>NEWS_PARSER_PLUGIN_URL.'/public/css/autopilot-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
    2727    ),
     28    /*
     29    $menu_config->menu->subs[3]->menu_slug=>array(
     30        NEWS_PARSER_PLUGIN_SLUG . '-seo_integration'=>NEWS_PARSER_PLUGIN_URL.'/public/css/seo_integration-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
     31    ),
     32    */   
    2833    $menu_config->menu->subs[3]->menu_slug=>array(
    2934        NEWS_PARSER_PLUGIN_SLUG . '-style-about'=>NEWS_PARSER_PLUGIN_URL . '/public/css/about-news-parser.css'
  • news-parser/trunk/inc/Config/styles-config.php

    r3201219 r3231549  
    1515        NEWS_PARSER_PLUGIN_SLUG . '-bootstrap'=>'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css',
    1616        NEWS_PARSER_PLUGIN_SLUG . '-bootstrap-icons'=> 'https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css',
    17         NEWS_PARSER_PLUGIN_SLUG . '-media_views'=>NEWS_PARSER_PLUGIN_URL . '/public/css/media-views.css'
     17        NEWS_PARSER_PLUGIN_SLUG . '-media_views'=>NEWS_PARSER_PLUGIN_URL . '/public/css/media-views.css',
     18        NEWS_PARSER_PLUGIN_SLUG . '-277-'=>NEWS_PARSER_PLUGIN_URL . '/public/css/277-'.NEWS_PARSER_PLUGIN_VERSION.'.css',
    1819    ),
    1920    $menu_config->menu->subs[0]->menu_slug=>array(
    20         NEWS_PARSER_PLUGIN_SLUG . '-parser-rss'=> NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
     21      //  NEWS_PARSER_PLUGIN_SLUG . '-parser-rss'=> NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
    2122    ),
    2223    $menu_config->menu->subs[1]->menu_slug=>array(
    23         NEWS_PARSER_PLUGIN_SLUG . '-parser-page'=>NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
     24     //   NEWS_PARSER_PLUGIN_SLUG . '-parser-page'=>NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
    2425    ),
    2526    $menu_config->menu->subs[2]->menu_slug=>array(
    2627        NEWS_PARSER_PLUGIN_SLUG . '-autopilot'=>NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
    2728    ),
     29    /*
     30    $menu_config->menu->subs[3]->menu_slug=>array(
     31        NEWS_PARSER_PLUGIN_SLUG . '-seo_integration'=>NEWS_PARSER_PLUGIN_URL.'/public/css/parser_rss-'.NEWS_PARSER_PLUGIN_VERSION.'.css'
     32    ),
     33    */
    2834    $menu_config->menu->subs[3]->menu_slug=>array(
    2935        NEWS_PARSER_PLUGIN_SLUG . '-style-about'=>NEWS_PARSER_PLUGIN_URL . '/public/css/about-news-parser.css'
  • news-parser/trunk/inc/Controller/PostController.php

    r3205095 r3231549  
    88use NewsParserPlugin\Interfaces\ModelInterface;
    99use NewsParserPlugin\Message\Errors;
    10 use NewsParserPlugin\Models\PostCacheModel;
    1110use NewsParserPlugin\Models\PostModel;
    1211use NewsParserPlugin\Models\TemplateModel;
     
    4140    protected $adapter;
    4241
    43 
    4442    public function __construct(AbstractParseContent $parser, AdapterInterface $adapter, ModelInterface $template_model, PostModel $post_model)
    4543    {
     
    4846        $this->templateModel = $template_model;
    4947        $this->postModel = $post_model;
    50        
     48
    5149    }
    5250    /**
    5351     *  Method that handels post parsing request.
    54      * 
     52     *
    5553     * @param string $url The url of the post.
    5654     * @param string $_id Frontend id of the post.
     
    7876    /**
    7977     * Method that handels post parsing request from CronController.
    80      * 
     78     *
    8179     * @param string $url The url of the post.
    8280     * @param string $template_url The url of the template.
     
    9997    /**
    10098     * Method create post form given parsed data.
    101      * 
     99     *
    102100     * @param string $url The url of the post.
    103101     * @param string $_id Frontend id of the post.
     
    124122    /**
    125123     * Handle posts in progerss requests.
    126      * 
     124     *
    127125     * @param string $template_url The url of the template.
    128126     * @param string $post_url The url of the post.
     
    182180            $this->formatPostMeta([
    183181                'status' => self::PARSING_STATUS_PARSED,
    184                 'image' => isset($post_update['image'])?$post_update['image']:null,
     182                'image' => isset($post_update['image']) ? $post_update['image'] : null,
    185183            ])
    186184        ));
     
    199197        ]);
    200198    }
    201 
     199    /**
     200     * Delete post
     201     */
     202    public function delete($post_id)
     203    {
     204        $this->postModel->delete($post_id);
     205    }
    202206    /**
    203207     * Apply body adapter to parsed data
     
    323327        if (isset($post_options['postDate'])) {
    324328            $time_format = 'Y-m-d H:i:s';
    325             $timestamp=strtotime($post_options['postDate']);
     329            $timestamp = strtotime($post_options['postDate']);
    326330            $formated_post_options['post_date'] = wp_date($time_format, $timestamp);
    327331            $formated_post_options['post_modified'] = wp_date($time_format, $timestamp);
     
    329333        return $formated_post_options;
    330334    }
     335
    331336}
  • news-parser/trunk/inc/Controller/TemplateController.php

    r3049937 r3231549  
    5555    public function get($url)
    5656    {
     57
    5758        $template_data=$this->templateModel->findByID($url);
    5859        if(is_array($template_data)){
  • news-parser/trunk/inc/Models/AIOptionsModel.php

    r3205095 r3231549  
    1313     */
    1414    protected const AI_OPTIONS_TABLE_NAME = NEWS_PURSER_PLUGIN_AI_OPTIONS_TABLE_NAME;
    15    
     15    protected const AI_OPTIONS_TTL=3600;
    1616    public function __construct()
    1717    {
     
    3535        $ai_providers_options=$this->getAll();
    3636        $ai_providers_options[$ai_provider_name]=$ai_provider_options_array;   
    37         return update_option(self::AI_OPTIONS_TABLE_NAME, $ai_providers_options);
     37        return update_option(self::AI_OPTIONS_TABLE_NAME, $ai_providers_options, self::AI_OPTIONS_TTL);
    3838    }
    3939   
     
    4545            unset($ai_providers_options[$ai_provider_name]);
    4646        }
    47         return update_option(self::AI_OPTIONS_TABLE_NAME, $ai_providers_options);
     47        return update_option(self::AI_OPTIONS_TABLE_NAME, $ai_providers_options, self::AI_OPTIONS_TTL);
    4848    }
    4949   
  • news-parser/trunk/inc/Parser/HTMLParser.php

    r3049937 r3231549  
    6262    public function initParser($data)
    6363    {
     64        /*
    6465        $clean_html=$this->pipe($data)
    6566            ->removeScriptTags()
    6667            ->removeStyleTags()
    6768            ->get();
     69            */
     70        $clean_html=apply_filters('NewsParserPlugin\Parser\HTMLParser:parse',$data);
    6871        $this->dom = $this->createDOM($clean_html);
    6972        $this->rawHTML = $clean_html;
     
    208211    public function find($query)
    209212    {
     213       
    210214        $result = $this->dom->find($query);
    211215        return !empty($result) ? $result : false;
    212216    }
     217   
     218    /**
     219     * Method exclude from the result of the search query those elements that are in the exclude query.
     220     *
     221     * @param string $query Search query.
     222     * @param string $exclude Search query.
     223     *
     224     * @return false|array of HtmlDomParser objects if found.
     225     */
     226    public function exclude($query, $exclude)
     227    {
     228        $result = $this->dom->find($query);
     229        if (empty($result)||!is_array($result)) {
     230            return false;
     231        }
     232        $excluded=this->find($exclude);
     233        if (empty($excluded)||!is_array($excluded)) {
     234            return $result;
     235        }
     236        return array_filter($result, function ($item) use ($excluded) {
     237            return !in_array($item, $excluded);
     238        });
     239    }
    213240    /**
    214241     * Remove HTML tags from the text.
  • news-parser/trunk/inc/Parser/HTMLPatternParser.php

    r3205095 r3231549  
    1414{
    1515
    16 
     16    protected $query_extenders = [];
    1717    /**
    1818     * HTMLPatternParser constructor.
     
    2020     * @param int              $cache_expiration  Cache expiration time in seconds.
    2121     */
    22     public function __construct($cache_expiration = 3600)
    23     {
     22    public function __construct($query_extenders = [], $cache_expiration = 3600)
     23    {
     24        $this->query_extenders = $query_extenders;
    2425        parent::__construct($cache_expiration);
    2526    }
     
    3435    public function postBody()
    3536    {
    36         $search_template = '';
    37         if (!isset($this->options['template'])) {
    38             throw new \Exception('Parsing template patterns should be set.');
    39         }
    40         $template = $this->options['template'];
    41         foreach ($template['children'] as $child_element) {
    42             // Create search template for Sunra\HtmlDomParser::find method
    43             // https://simplehtmldom.sourceforge.io/docs/1.9/manual/finding-html-elements/ How to find HTML elements? section.
    44             $search_template .= $child_element['searchTemplate'] . ',';
    45         }
    46         $search_template = substr($search_template, 0, -1);
    47         $container = $this->find($template['searchTemplate']);
     37        $search_template = $this->createBodyElementsSearchTemplate($this->options['template']);
     38
     39        $exclude_template = $this->createBodyElementsExcludeTemplate($this->options['template']);
     40
     41        $container_search_template = $this->getContainerSearchTemplate($this->options['template']);
     42
     43        $container = $this->find($container_search_template);
    4844
    4945        if (empty($container)) {
    5046            return '';
    5147        }
    52         if(count($container)>1){
    53             $elements=[];
    54             foreach ($container as $container_element){
    55                 $elements=array_merge($elements,$container_element->find($search_template));
    56             }
    57         }else{
    58             $elements = $container[0]->find($search_template);
    59         }
    60        
     48
     49        $elements = [];
     50        foreach ($container as $container_element) {
     51            $elements = array_merge($elements, $this->find($search_template, $container_element));
     52        }
     53
     54        $elements = $exclude_template ? $this->excludeElements($container, $elements, $exclude_template) : $elements;
     55
    6156        $body = $this->parseContainer($elements);
    62         return $body ? $body: '';
     57        return $body ? $body : '';
    6358    }
    6459
     
    8984                        // If the lazy load attribute data-src exists, take that as the source of the image. If none, take the src attribute.
    9085                        'src' => $image_srcset !== false ? $this->srcSetSplit($image_srcset) : ((is_array($el->attr) && array_key_exists('data-src', $el->attr)) ? $this->srcSetSplit($el->attr['data-src']) : $el->src),
    91                         'srcSet' => $image_srcset!==false ? $image_srcset : '',
    92                         'sizes'=>''
     86                        'srcSet' => $image_srcset !== false ? $image_srcset : '',
     87                        'sizes' => '',
    9388                    );
    9489                    break;
     
    110105                    }
    111106                    break;
    112                 case 'iframe':
     107                case 'video':
    113108                    // Find the YouTube video ID.
    114                     preg_match('/youtube\.com\/embed\/([a-zA-Z0-9\_]*)/i', $el->src, $match);
     109                    $video_hash=$el->getAttribute('data-hash');
    115110                    // Remove any symbols except those that are allowed.
    116                     $el_data['content'] = array_key_exists(1, $match) ? $match[1] : false;
     111                    $el_data['content'] = $video_hash;
    117112                    break;
    118113                default:
    119                     $el_data['tagName']='p';
     114                    $el_data['tagName'] = 'p';
    120115                    $el_data['content'] = $this->removeTags(trim($el->innertext));
    121116            }
     
    127122        return $body;
    128123    }
    129 
     124    protected function getContainerSearchTemplate($template)
     125    {
     126        if (!$template) {
     127            throw new \Exception('Template is not set.');
     128        }
     129        return $template['searchTemplate'];
     130    }
     131    /**
     132     * Exclude elements from container by template.
     133     *
     134     * @param array $container Array of HtmlDomParser element objects.
     135     * @param array $elements Array of HtmlDomParser element objects.
     136     *
     137     * @return array
     138     */
     139    protected function excludeElements($containter, $elements, $exclude_template)
     140    {
     141        $exclude_templates=explode(',',$exclude_template);
     142        if (!count($exclude_templates)) {
     143            return $elements;
     144        }
     145        $elements_to_exclude = [];
     146        foreach ($containter as $container_element) {
     147            $elements_to_exclude_in_container = [ ...array_map(function ($exclude_template) use ($container_element) {
     148                return $this->find($exclude_template, $container_element);
     149            }, $exclude_templates)];
     150            $elements_to_exclude = array_merge($elements_to_exclude, ...$elements_to_exclude_in_container);
     151        }
     152        $elements_to_exclude_id = array_map(function ($element) {
     153            return $element->tag_start;
     154        }, $elements_to_exclude);
     155        return array_filter($elements, function ($element) use ($elements_to_exclude_id) {
     156            return !in_array($element->tag_start, $elements_to_exclude_id);
     157        });
     158
     159    }
     160    /**
     161     * Create search for post body children elements template for Sunra\HtmlDomParser::find method
     162     *
     163     * @param array $template Parsing template
     164     *
     165     * @return string
     166     */
     167    protected function createBodyElementsSearchTemplate($template)
     168    {
     169        if ($template['elementsTemplate']) {
     170            return $template['elementsTemplate'];
     171        }
     172        $search_template = '';
     173        if (!$template) {
     174            throw new \Exception('Parsing template patterns should be set.');
     175        }
     176        foreach ($template['children'] as $child_element) {
     177            // Create search template for Sunra\HtmlDomParser::find method
     178            // https://simplehtmldom.sourceforge.io/docs/1.9/manual/finding-html-elements/ How to find HTML elements? section.
     179            $search_template .= $child_element['searchTemplate'] . ',';
     180        }
     181        return substr($search_template, 0, -1);
     182    }
     183    /**
     184     * Create exclude elements template for Sunra\HtmlDomParser::find method
     185     *
     186     * @param array $template Parsing template
     187     *
     188     * @return string
     189     *
     190     */
     191    protected function createBodyElementsExcludeTemplate($template)
     192    {
     193        return !$template ? [] : $template['excludeTemplate'];
     194    }
    130195    /**
    131196     * Parse the source image tag.
     
    177242        return end($array);
    178243    }
     244    /**
     245     * Provide finding elements with extended syntax.
     246     *
     247     * @param string $query The query string.
     248     * @return array The array of elements.
     249     */
     250    public function find($query, $container_element = null)
     251    {
     252        if ($this->hasExtededSyntax($query)) {
     253            return $this->findWithExtendedSyntax($query, $container_element);
     254        }
     255        return $container_element ? $container_element->find($query) : parent::find($query);
     256    }
     257    /**
     258     * Check if the query has extended syntax.
     259     *
     260     * @param string $query The query string.
     261     */
     262    protected function hasExtededSyntax($query)
     263    {
     264        if (!count($this->query_extenders)) {
     265            return false;
     266        }
     267        foreach ($this->query_extenders as $extender) {
     268            if ($extender->checkSyntax($query)) {
     269                return true;
     270            }
     271        }
     272    }
     273    /**
     274     * Remove extended syntax from the query.
     275     *
     276     * @param string $query The query string.
     277     */
     278    protected function removeExtendedSyntax($query)
     279    {
     280        return array_reduce($this->query_extenders, function ($carry, $extender) use ($query) {
     281            return $extender->removeExtendedSyntax($query, $carry);
     282        }, $query);
     283    }
     284    /**
     285     * Find elements with extended syntax.
     286     *
     287     * @param string $query The query string.
     288     *
     289     * @return array The array of elements.
     290     */
     291    protected function findWithExtendedSyntax($query, $container_element)
     292    {
     293        $initElements = $this->find($this->removeExtendedSyntax($query), $container_element);
     294        return array_reduce($this->query_extenders, function ($carry, $extender) use ($query) {
     295            return $extender->find($query, $carry);
     296        }, $initElements);
     297    }
    179298
    180299    /**
  • news-parser/trunk/inc/Parser/HTMLRaw.php

    r3049937 r3231549  
    3434    protected function parse($html)
    3535    {
    36        
     36        
    3737        $html=apply_filters('NewsParserPlugin\Parser\HTMLRaw:parse:parse',$html,$this->url);
    38        
     38        
    3939        if (is_array($this->options)&&array_key_exists('remove_scripts', $this->options)&&$this->options['remove_scripts']) {
    4040            return $this->removeScriptTags($html);
  • news-parser/trunk/inc/Parser/Modifiers/AdapterModifiers/Before/GeneratePostBodyWithAI.php

    r3206548 r3231549  
    88    public $aiServeceProviders;
    99    public $aiServeceProvider;
    10     const IMG_SYMBOL = '[image]';
    11     const HEADER_SYMBOL = '***';
     10    const HEADER_SYMBOL = '**';
     11    const OUTPUT_FORMAT_PROMPT='I need that you provide your answer in a proper JSON format. Where tagName is html tag name and content is html tag text content.';
    1212    public function __construct($ai_service_providers)
    1313    {
     
    3636        }
    3737
    38         $parsed_data['body'] = $save_post_structure ? $response : $this->replaceOriginalContent($response, $parsed_data['body']);
     38        $parsed_data['body'] = $response;
    3939        return $parsed_data;
    4040    }
     
    5252    private function preparePostBody($body, $savePostStructure)
    5353    {
    54         return $savePostStructure ? $this->mergeParagraphs($body) : $this->encodeBody($body);
     54        return $savePostStructure ? $this->encodeBodyWithStructure($body) : $this->encodeBody($body);
    5555    }
    5656
     
    5858    private function processPipelines($model, $pipelines, $post_body, $title)
    5959    {
    60         return array_reduce($pipelines, function ($body, $current_prompt) use ($model,$title) {
     60        $result= array_reduce($pipelines, function ($body, $current_prompt) use ($model,$title) {
    6161            $ai_request_options = $this->getAIRequestOptions($model);
    62 
    63             if (is_array($body)) {
    64                 return $this->processBodyArray($ai_request_options, $current_prompt, $body, $title);
    65             } else {
    66                 return $this->processBodyString($ai_request_options, $current_prompt, $body, $title);
    67             }
     62            return $this->processBodyArray($ai_request_options, $current_prompt, $body, $title);
     63           
    6864        }, $post_body);
     65        return $this->decodeBody($this->unwrapBody($result));
    6966    }
    7067    protected function getAIRequestOptions($model)
     
    7471            'messages' => [
    7572                [
     73                   
    7674                    'role' => 'user',
    7775                    'content' => '',
     
    8684        $ai_request_options['messages'][0]['content'] = $this->preparePrompt($prompt, $body, $title);
    8785        $ai_response = $this->aiServeceProvider->chat($ai_request_options);
    88         return $this->decodeBody($ai_response);
     86        return $this->$this->decodeBody($ai_response);
    8987    }
    9088    protected function processBodyArray($ai_request_options, $prompt, $body, $title)
    9189    {
    9290        $result = [];
    93         foreach ($body as $element) {
    94             if ($element['tagName'] === 'p' || $element['tagName'] === 'div') {
    95                 $ai_request_options['messages'][0]['content'] = $this->preparePrompt($prompt, $element['content'], $title);
    96                 $result = array_merge($result, $this->decodeParagraph($this->aiServeceProvider->chat($ai_request_options)));
    97             } elseif (in_array($element['tagName'], ['h2', 'h3', 'h4'])) {
    98                 $ai_request_options['messages'][0]['content'] = $this->preparePrompt($prompt, $element['content'], $title);
    99                 $element['content']=$this->aiServeceProvider->chat($ai_request_options);
    100                 $result[] = $element;
    101             } else {
    102                 $result[] = $element;
     91        foreach ($body as $block) {
     92            if ($block['ai']) {
     93                $ai_request_options['messages'][0]['content'] = $this->preparePrompt($prompt, $block['content'], $title);
     94                $result[] =  [
     95                    'ai' => true,
     96                    'content'=>$this->aiServeceProvider->chat($ai_request_options)
     97                ];
     98            } else {
     99                $result[] = $block;
    103100            }
    104101        }
     
    117114    {
    118115        $full_prompt = str_replace('${post}', $post_body, $prompt);
    119         $full_prompt = str_replace('${title}', $post_body, $full_prompt);
     116        $full_prompt = str_replace('${title}', $post_title, $full_prompt);
    120117        //$full_prompt = str_replace('${headers}', $this->extractHeadins($parsed_data['body']), $full_prompt);
    121118        //$full_prompt = str_replace('${paragraphs}', $this->countParagraphs($parsed_data['body']), $full_prompt);
     
    124121    protected function decodeBody($body)
    125122    {
    126         $result_body_array = [];
    127         $body_array = explode(PHP_EOL, $body);
    128         foreach ($body_array as $el) {
    129             if ($el == '') {
     123        $header_patter='/\*\*(.+?)\*\*/i';
     124        $result=[];
     125       
     126       
     127        foreach ($body as $el){
     128            if (is_array($el)){
     129                $result[]=$el;
    130130                continue;
    131131            }
    132 
    133             if (strpos($el, self::HEADER_SYMBOL) !== false) {
    134                 $result_body_array[] = array(
    135                     'tagName' => 'h3',
    136                     'content' => str_replace(self::HEADER_SYMBOL, '', $el),
     132            $el_array = explode(PHP_EOL, $el);
     133            $sub_result_array = [];
     134            foreach ($el_array as $el_part) {
     135                if ($el_part == '') {
     136                    continue;
     137                }
     138
     139                if (preg_match($header_patter, $el_part, $matches)!==0) {
     140                    $sub_result_array[] = array(
     141                        'tagName' => 'h2',
     142                        'content' => $matches[1],
     143                    );
     144                    continue;
     145                }
     146           
     147                $sub_result_array[] = array(
     148                    'tagName' => 'p',
     149                    'content' => $el_part,
    137150                );
     151            }
     152            $result = array_merge($result, $sub_result_array);
     153        }
     154        return $result;
     155    }
     156    protected function unwrapBody($body){
     157       return array_map(function ($el) {
     158            return $el['content'];
     159        }, $body);
     160    }
     161    protected function encodeBody($body)
     162    {
     163        $mergedBody = [];
     164        $contentBlock='';
     165        foreach ($body as $element) {
     166            if ($element['tagName'] === 'p'||$element['tagName'] === 'span') {
     167                $contentBlock.=PHP_EOL.$element['content'];
     168            } else if ($element['tagName'] === 'h1' || $element['tagName'] === 'h2' || $element['tagName'] === 'h3' || $element['tagName'] === 'h4') {
     169                $contentBlock.=PHP_EOL.self::HEADER_SYMBOL.$element['content'].self::HEADER_SYMBOL.PHP_EOL;
     170            } else {
     171                if ($contentBlock!=='') {
     172                    $mergedBody[] =[
     173                        'ai'=>true,
     174                        'content'=>$contentBlock
     175                    ];
     176                }
     177                $mergedBody[] =['ai'=>false,
     178                    'content'=>$element
     179                ];
     180            }
     181        }
     182        if ($contentBlock!=='') {
     183            $mergedBody[] =[
     184                'ai'=>true,
     185                'content'=>$contentBlock
     186            ];
     187        }
     188        return $mergedBody;
     189    }
     190    protected function encodeBodyWithStructure($body)
     191    {
     192        $mergedBody = [];
     193        $contentBlock='';
     194        foreach ($body as $element) {
     195            if ($element['tagName'] === 'p'||$element['tagName'] === 'span') {
     196                $contentBlock=$element['content'];
     197            } else if ($element['tagName'] === 'h1' || $element['tagName'] === 'h2' || $element['tagName'] === 'h3' || $element['tagName'] === 'h4') {
     198                $contentBlock=self::HEADER_SYMBOL.$element['content'].self::HEADER_SYMBOL.PHP_EOL;
     199            } else {
     200                $mergedBody[] =['ai'=>false,
     201                    'content'=>$element
     202                ];
    138203                continue;
    139204            }
    140             if (strpos($el, self::IMG_SYMBOL) !== false) {
    141                 $result_body_array[] = array(
    142                     'tagName' => 'img',
    143                     'content' => '',
    144                 );
    145                 continue;
    146             }
    147             $result_body_array[] = array(
    148                 'tagName' => 'p',
    149                 'content' => $el,
    150             );
    151         }
    152         return $result_body_array;
    153     }
    154     protected function encodeBody($body)
    155     {
    156         $body_string = '';
    157         foreach ($body as $el) {
    158             switch ($el['tagName']) {
    159                 case 'h1':
    160                 case 'h2':
    161                 case 'h3':
    162                 case 'span':
    163                 case 'p':
    164                     $body_string .= $el['content'] . PHP_EOL;
    165                     break;
    166                 case 'img':
    167                     $body_string .= self::IMG_SYMBOL;
    168             }
    169 
    170         }
    171         return $body_string;
     205            $mergedBody[] =['ai'=>true,
     206                'content'=>$contentBlock
     207            ];
     208        }
     209        return $mergedBody;
    172210    }
    173211    protected function replaceOriginalContent($body, $original_content)
    174212    {
    175         $result = [];
     213        if (is_array($body)) {
     214            return $this->replaceOriginalContentArray($body, $original_content);
     215        } else {
     216            return $this->replaceOriginalContentString($body, $original_content);
     217        }
     218    }
     219    protected function replaceOriginalContentString($body, $original_content)
     220    {
    176221        $images = array_filter($original_content, function ($el) {
    177222            return $el['tagName'] == 'img';
    178223        });
    179         foreach ($body as $el) {
    180             if ($el['tagName'] == 'img') {
    181                 $el=array_shift($images);
    182                 if($el===null) continue;
    183             }
    184             $result[] = $el;
    185         }
    186         return array_merge($result, $images);
     224        $result = [[
     225                'tagName' => 'p',
     226                'content' => $body
     227            ]];
     228        $result = array_merge($result, $images);
     229        return $result;
     230    }
     231    protected function replaceOriginalContentArray($body, $original_content)
     232    {
     233        $result = [];
     234        foreach ($original_content as $index=>$el) {
     235            if ($el['tagName'] !== 'p'||$el['tagName'] !== 'span'||$el['tagName'] !== 'h1'||$el['tagName'] !== 'h2'||$el['tagName'] !== 'h3'||$el['tagName'] !== 'h4') {
     236                $result[] = $body[$index];
     237            } else {
     238                $result[] = $original_content[$index];   
     239            }
     240           
     241        }
     242        return $result;
    187243    }
    188244    protected function extractHeadins($body)
     
    203259        return $body_string;
    204260    }
    205     protected function mergeParagraphs($body)
    206     {
    207         $mergedBody = [];
    208         $previousElement = null;
    209 
    210         foreach ($body as $element) {
    211             if ($element['tagName'] === 'p') {
    212                 if ($previousElement !== null && $previousElement['tagName'] == 'p') {
    213                     $previousElement['content'] .= ' ' . $element['content'] . PHP_EOL;
    214                 } else {
    215                     $previousElement = $element;
    216                 }
    217             } else {
    218                 if ($previousElement !== null) {
    219                     $mergedBody[] = $previousElement;
    220                 }
    221 
    222                 $mergedBody[] = $element;
    223                 $previousElement = null;
    224             }
    225         }
    226         if ($previousElement !== null) {
    227             $mergedBody[] = $previousElement;
    228         }
    229 
    230         return $mergedBody;
     261   
     262    public function encondeParagraph($paragraph)
     263    {
     264       
     265        return json_encode($paragraph);
    231266    }
    232267    public function decodeParagraph($paragraph)
    233268    {
    234         $result = [];
    235         $paragraphArray = explode(PHP_EOL, $paragraph);
    236         foreach ($paragraphArray as $el) {
    237             if ($el == '') {
    238                 continue;
    239             }
    240 
    241             $result[] = array(
    242                 'tagName' => 'p',
    243                 'content' => $el,
    244             );
    245         }
    246         return $result;
     269        $clean_json=str_replace('```json', '', $paragraph);
     270        return json_decode($clean_json, true);
    247271    }
    248272    protected function countParagraphs($body)
  • news-parser/trunk/inc/Service/AI/GeminiAIServiceProvider.php

    r3206548 r3231549  
    3636            return false;
    3737        }
     38       
     39        $options=$this->fetchOptions();
     40       
     41       
    3842        return [
    3943            'featuredImage'=>false,
    4044            'postTitle' => [
    41                 'models' => ['gemini-pro'],
     45                'models' => $options,
    4246            ],
    4347            'postBody' => [
    44                 'models' => ['gemini-pro']
     48                'models' => $options
    4549            ]
    4650        ];
     
    5862                    );
    5963                return $responce->text();
    60             } catch (\Exception $e) {
     64            } catch (\Exception |\ValueError $e) {
    6165                if ($attempts == $max_attempts) {
    6266                    throw new MyException($e->getMessage(), $e->getCode());
     
    6872        }
    6973    }
     74   
     75    protected function fetchOptions(){
     76        try{
     77        $response = $this->geminiClient->models()->list(pageSize: 3);
     78        }catch(\Exception $e){
     79            throw new MyException($e->getMessage(), $e->getCode());
     80        }
     81        $models=$response->models;
     82        return array_map(fn ($model)=>$model->name,$models);
     83    }
    7084    public function isAPIKeyDefined()
    7185    {
  • news-parser/trunk/inc/Service/AI/OpenAIServiceProvider.php

    r3206548 r3231549  
    4747            'featuredImage' => [
    4848                'models' => ['dall-e-2', 'dall-e-3'],
    49                 'sizes' =>['1024x1024', '1024x1792', '1792x1024']
     49                'sizes' => ['1024x1024', '1024x1792', '1792x1024'],
    5050            ],
    5151            'postTitle' => [
     
    6565        $max_attempts = self::RETRY_COUNT;
    6666        while ($attempts <= $max_attempts) {
    67             $responce = json_decode($this->openAIClient->chat($chat_options_array));
     67            try {
     68                $responce = json_decode($this->openAIClient->chat($chat_options_array));
     69            } catch (\Exception |\ValueError $e) {
     70                throw new MyException($e->getMessage(), $e->getCode());
     71            }
    6872            if (property_exists($responce, 'error')) {
    6973                if ($responce->error->code == 'rate_limit_exceeded') {
     
    7276                    }
    7377                    $attempts++;
    74                     sleep(($this->lockDuration+rand(1,5))*(1+$attempts/5));
     78                    sleep(($this->lockDuration + rand(1, 5)) * (1 + $attempts / 5));
    7579                } else {
    7680                    throw new MyException($responce->error->message, $responce->error->code);
     
    96100                    }
    97101                    $counter++;
    98                     sleep(($this->lockDuration+rand(1,5))*(1+$counter/5));
     102                    sleep(($this->lockDuration + rand(1, 5)) * (1 + $counter / 5));
    99103                } else {
    100104                    throw new MyException($responce->error->message, $responce->error->code);
  • news-parser/trunk/inc/Traits/SanitizeDataTrait.php

    r3049937 r3231549  
    124124                    break;
    125125                case 'searchTemplate':
    126                     $clean_data[$key]=preg_replace('/[^a-zA-Z0-9\=\s\_\-\.\]\[]/i', '', $param);
     126                case 'excludeTemplate':
     127                case 'elementsTemplate':
     128                    $clean_data[$key]=preg_replace('/[^a-zA-Z0-9\=\s\_\-\.\,\]\[\p{L}\*\^\$\!]/u', '', $param);
    127129                    break;
    128130                case 'position':
  • news-parser/trunk/inc/Utils/AdapterGuttenberg.php

    r3201219 r3231549  
    5151                    $post_content.=$this->listBlock($el);
    5252                    break;
    53                 case 'iframe':
     53                case 'video':
    5454                    $post_content.=$this->youtubeVideo($el);
    5555                    break;
     
    7272    {
    7373        $hash=$element['content'];
     74        /*
    7475        $video='<!-- wp:core-embed/youtube {"url":"https://youtu.be/%1$s","type":"video","providerNameSlug":"youtube","className":"wp-embed-aspect-16-9 wp-has-aspect-ratio"} -->'.
    7576            '<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">'.
    7677            'https://youtu.be/%1$s</div></figure><!-- /wp:core-embed/youtube -->';
     78        */
     79        $video='<!-- wp:embed {"url":"https://youtu.be/%1$s","type":"video","providerNameSlug":"youtube","className":"wp-embed-aspect-16-9 wp-has-aspect-ratio"} --><figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"><iframe src="https://www.youtube.com/embed/%1$s" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe></div></figure><!-- /wp:core-embed/youtube -->';
    7780        return sprintf(
    7881            $video,
  • news-parser/trunk/inc/Utils/ResponseFormatter.php

    r3049937 r3231549  
    164164    {
    165165        return $this->data['code'];
     166
     167    }
     168     /**
     169      * Return answer data in array|object|json format
     170      *
     171      * @param array $data
     172      */
     173    public function postTest($data)
     174    {
     175        $this->data=$data;
     176        return $this;
    166177    }
    167178    /**
  • news-parser/trunk/news-parser.php

    r3206548 r3231549  
    44Plugin URI: https://www.news-parser.com
    55Description: Parse full text news from RSS Feed
    6 Version: 2.2.3
     6Version: 2.3.0
    77Author: Evgeny S.Zalevskiy <[email protected]>
    88Author URI: https://github.com/zalevsk1y/
     
    1515
    1616
    17 define('NEWS_PARSER_PLUGIN_VERSION', '2.2.3');
     17define('NEWS_PARSER_PLUGIN_VERSION', '2.3.0');
    1818define ("NEWS_PARSER_PLUGIN_MODE","production");
    1919
  • news-parser/trunk/readme.txt

    r3206548 r3231549  
    44Author: Evgeniy Zalevskiy
    55Tags: scraper,rss,news,autopilot,ai
    6 Requires PHP: 8.2
     6Requires PHP: 8.1
    77Requires at least: 5.2.0
    88Tested up to: 6.7.1
    9 Stable tag: 2.2.3
     9Stable tag: 2.3.0
    1010License: MIT
    1111License URI: https://opensource.org/licenses/MIT
     
    115115New Features:
    116116
    117 *  Autopilot Logging: You can now enable logging to monitor Autopilot activity. To activate logging, add the following line to your `wp-config.php` file: `define('NEWS_PARSER_CRON_LOGGER', true);`. Log files will be stored in `wp-content/plugins/news-parser/logs/cron_log.txt`.
    118117*  Unlimited Autopilot Runs and Posts: The previous limitations on the number of Autopilot runs and parsed posts have been removed. You can now parse as many posts as needed.
    119118*  Posts Per Run: Control the number of posts parsed per Autopilot run. This setting is configurable in the Autopilot settings page. This helps manage server resources and prevents timeouts for feeds with a large number of posts.
     
    172171== Changelog ==
    173172
     173= 2.3.0 - 09-12-24 =
     174
     175* Added: Visual Constructor shows saved template data.
     176* Fix: some bugs.
    174177
    175178= 2.2.3 - 09-12-24 =
     
    178181
    179182= 2.2.2 - 09-12-24 =
    180 
    181 * Fix: some bugs.
    182 
    183 = 2.2.1 - 09-12-24 =
    184183
    185184* Fix: some bugs.
Note: See TracChangeset for help on using the changeset viewer.