Файловый менеджер - Редактировать - /home/digilove/public_html/administrator/components/com_jmap/models/aigenerator.php
Назад
<?php // namespace administrator\components\com_jmap\models; /** * * @package JMAP::AIGENERATOR::administrator::components::com_jmap * @subpackage models * @author Joomla! Extensions Store * @copyright (C) 2021 - Joomla! Extensions Store * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html */ defined ( '_JEXEC' ) or die ( 'Restricted access' ); /** * Google model responsibilities for access Google Analytics and Webmasters Tools API * * @package JMAP::AIGENERATOR::administrator::components::com_jmap * @subpackage models * @since 3.1 */ interface IModelAIGenerator { /** * Generate data method for the AI contents API * * @access public * @param string $keywordPhrase * @param string $selectedApi * @return mixed string */ public function generateAIContentData($keywordPhrase, $selectedApi); } /** * Sources model concrete implementation <<testable_behavior>> * * @package JMAP::GOOGLE::administrator::components::com_jmap * @subpackage models * @since 3.1 */ class JMapModelAIGenerator extends JMapModel implements IModelAIGenerator { /** * Google_Client object * * @access private * @var Google_Client */ private $client; /** * Build list entities query * * @access protected * @return string */ protected function buildListQuery() { // WHERE $where = array (); $whereString = null; $orderString = null; // TEXT FILTER if ($this->state->get ( 'searchword' )) { $where [] = "(s.keywords_phrase LIKE " . $this->_db->quote("%" . $this->state->get ( 'searchword' ) . "%") . ")"; } // LANGUAGE FILTER $language = $this->state->get ( 'language' ); if ($language && $language != '*' && $this->getLanguagePluginEnabled()) { $where [] = "(s.language = " . $this->_db->quote($this->state->get ( 'language' )) . ")"; } // API FILTER $contentsApi = $this->state->get ( 'contentsapi' ); if ($contentsApi) { $where [] = "(s.api = " . $this->_db->quote($this->state->get ( 'contentsapi' )) . ")"; } if (count ( $where )) { $whereString = "\n WHERE " . implode ( "\n AND ", $where ); } // ORDERBY if ($this->state->get ( 'order' )) { $orderString = "\n ORDER BY " . $this->state->get ( 'order' ) . " "; } // ORDERDIR if ($this->state->get ( 'order_dir' )) { $orderString .= $this->state->get ( 'order_dir' ); } $query = "SELECT s.*, u.name AS editor" . "\n FROM #__jmap_aigenerator AS s" . "\n LEFT JOIN #__users AS u" . "\n ON s.checked_out = u.id" . $whereString . $orderString; return $query; } /** * Function to purify common contents pitfalls and contents * * @acceess private * @param string $contents * @return string */ private function purifyContents($contents) { // Decode all HTML entities to UTF-8 $contents = html_entity_decode($contents, ENT_QUOTES, 'UTF-8'); // Convert all UTF-8 unicode characters to symbols $contents = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/imu', function ($match) { return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE'); }, $contents); // Remove carriage returns $contents = preg_replace( "/\r|\n|\\\\n|src=\"\"/imu", "", $contents ); // Remove escaped slashes $contents = preg_replace('#\\\/#imu', '/', $contents ); // Rmove <noscript> tags $contents = preg_replace( "/<noscript>(.*)<\/noscript>/imuU", "", $contents ); // Remove all links referencing original contents, keep inner text or remove unclosed tags if($this->componentParams->get('aigenerator_remove_links', 1)) { $contents = preg_replace('#(<a.*?>)(.*?)(</a>)#imu', '$2', $contents); $contents = preg_replace('#(<a.*?>)#imu', '', $contents); $contents = preg_replace('#(<button.*?>)(.*?)(</button>)#imu', '', $contents); } // Images should be removed? if($this->getState('removeimgs')) { $contents = preg_replace('#(<img.*?\/?>)#i', '', $contents); } // Replace headers with plain paragraphs $contents = preg_replace('/<h\d.*>/imuU', '<p>', $contents); $contents = preg_replace('/<\/h\d>/imu', '</p>', $contents); // Reduce extra spaces and normalize them $contents = preg_replace('/\s{2,}/imu', ' ', $contents); $contents = preg_replace('/\t{2,}/imu', ' ', $contents); // Remove onevents $contents = preg_replace( "/oncontextmenu=\"|onmousedown=\"|onload=\"|onclick=\"|onerror=\"|onmouseover=\"|onmouseout=\"/im", "data-onevent=\"", $contents ); // Replace lazy loaded sources with standard ones if($this->componentParams->get('aigenerator_turn_datasrc', 1)) { $contents = preg_replace( '/src=\s*["\']([^"]*)(data:image)/imu', 'data-lazyoldsrc="$1$2', $contents ); $contents = preg_replace( "/data-src/imu", "src", $contents ); $contents = preg_replace( "/data-original/imu", "src", $contents ); $contents = preg_replace( "/data-lazyload/imu", "src", $contents ); $contents = preg_replace( "/data-dt-lazy-src/imu", "src", $contents ); $contents = preg_replace( "/data-lazy-src/imu", "src", $contents ); if($this->componentParams->get('aigenerator_remove_srcset', 1)) { $contents = preg_replace( '/srcset=\s*(["\'])/imu', 'data-noloadsrcset=$1', $contents ); } } return $contents; } /** * Get the state of the language filter plugin and Joomla multilanguage * * @access public * @return bool */ public function getLanguagePluginEnabled() { $languageFilterPluginEnabled = false; // Check if multilanguage dropdown is always active if($this->getComponentParams()->get('showalways_language_dropdown', false)) { $languageFilterPluginEnabled = true; } else { // Detect Joomla Language Filter plugin enabled $query = "SELECT " . $this->_db->quoteName('enabled') . "\n FROM #__extensions" . "\n WHERE " . $this->_db->quoteName('element') . " = " . $this->_db->quote('languagefilter') . "\n OR " . $this->_db->quoteName('element') . " = " . $this->_db->quote('jfdatabase'); $this->_db->setQuery($query); $languageFilterPluginEnabled = $this->_db->loadResult(); } return $languageFilterPluginEnabled; } /** * Return select lists used as filter for listEntities * * @access public * @return array */ public function getFilters() { $filters = []; $languageOptions = JMapHtmlLanguages::getAvailableLanguageOptions(true); $filters ['languages'] = JHtml::_ ( 'select.genericlist', $languageOptions, 'language', 'onchange="Joomla.submitform();" class="form-select hidden-phone"', 'value', 'text', $this->getState ( 'language' ) ); // Selection of the AI API $chosenGeneratorAPI = array(); $chosenGeneratorAPI[] = JHtml::_('select.option', '', JText::_('COM_JMAP_AIGENERATOR_ALL_API')); $chosenGeneratorAPI[] = JHtml::_('select.option', 'google', JText::_('COM_JMAP_AIGENERATOR_GOOGLE_API')); $chosenGeneratorAPI[] = JHtml::_('select.option', 'bing', JText::_('COM_JMAP_AIGENERATOR_BING_API')); $chosenGeneratorAPI[] = JHtml::_('select.option', 'openai', JText::_('COM_JMAP_AIGENERATOR_OPENAI_API')); $filters ['contentsapi'] = JHtml::_ ( 'select.genericlist', $chosenGeneratorAPI, 'contentsapi', 'onchange="Joomla.submitform();" class="form-select hidden-phone"', 'value', 'text', $this->getState ( 'contentsapi' ) ); return $filters; } /** * Return select lists used as filter for editEntity * * @access public * @param Object $record * @return array */ public function getLists($record = null) { $lists = []; // Selection of the AI API $chosenGeneratorAPI = array(); $chosenGeneratorAPI[] = JHtml::_('select.option', 'google', JText::_('COM_JMAP_AIGENERATOR_GOOGLE_API')); $chosenGeneratorAPI[] = JHtml::_('select.option', 'bing', JText::_('COM_JMAP_AIGENERATOR_BING_API')); $chosenGeneratorAPI[] = JHtml::_('select.option', 'openai', JText::_('COM_JMAP_AIGENERATOR_OPENAI_API')); $lists ['ai_generator_contents_api'] = JHtml::_( 'select.radiolist', $chosenGeneratorAPI, 'api', '', 'value', 'text', $record->api, 'api_'); // Priority select list $options = array (); $options [] = JHtml::_ ( 'select.option', null, JText::_ ( 'COM_JMAP_SELECT_MAX_AI_RESULTS' ) ); $arrayMaxResults = array ( '1' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_1_ITEMS'), '2' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_2_ITEMS'), '3' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_3_ITEMS'), '4' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_4_ITEMS'), '5' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_5_ITEMS'), '6' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_6_ITEMS'), '7' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_7_ITEMS'), '8' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_8_ITEMS'), '9' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_9_ITEMS'), '10' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_10_ITEMS'), '15' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_15_ITEMS'), '20' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_20_ITEMS'), '25' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_25_ITEMS'), '30' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_30_ITEMS'), '35' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_35_ITEMS'), '40' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_40_ITEMS'), '45' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_45_ITEMS'), '50' => JText::_('COM_JMAP_SELECT_MAX_AI_RESULTS_50_ITEMS') ); foreach ( $arrayMaxResults as $value => $text ) { $options [] = JHtml::_ ( 'select.option', $value, $text ); } $lists ['ai_generator_max_results'] = JHtml::_ ( 'select.genericlist', $options, 'maxresults', 'class="form-select"', 'value', 'text', $record->maxresults ); // Temperature list $options = array (); $options [] = JHtml::_ ( 'select.option', null, JText::_ ( 'COM_JMAP_AI_TEMPERATURE_SELECT_TEMPERATURE' ) ); $arrayTemperature = array( '0.1' => JText::_('COM_JMAP_AI_TEMPERATURE_01'), '0.2' => JText::_('COM_JMAP_AI_TEMPERATURE_02'), '0.4' => JText::_('COM_JMAP_AI_TEMPERATURE_04'), '0.5' => JText::_('COM_JMAP_AI_TEMPERATURE_05'), '0.6' => JText::_('COM_JMAP_AI_TEMPERATURE_06'), '0.8' => JText::_('COM_JMAP_AI_TEMPERATURE_08'), '1.0' => JText::_('COM_JMAP_AI_TEMPERATURE_10'), '1.2' => JText::_('COM_JMAP_AI_TEMPERATURE_12'), '1.4' => JText::_('COM_JMAP_AI_TEMPERATURE_14'), '1.6' => JText::_('COM_JMAP_AI_TEMPERATURE_16'), '1.8' => JText::_('COM_JMAP_AI_TEMPERATURE_18'), '2.0' => JText::_('COM_JMAP_AI_TEMPERATURE_20') ); foreach ( $arrayTemperature as $value => $text ) { $options [] = JHtml::_ ( 'select.option', $value, $text ); } $temperature = $record->temperature ? $record->temperature : '0.5'; $lists ['temperature'] = JHtml::_ ( 'select.genericlist', $options, 'temperature', 'class="form-select"', 'value', 'text', $temperature ); // Language dropdown $languageFilterPluginEnabled = $this->getLanguagePluginEnabled(); $languageOptions = JMapHtmlLanguages::getAvailableLanguageOptions(false, true); if(count($languageOptions) >= 2 && $languageFilterPluginEnabled) { $lists['languages'] = JMapHelpersHtml::genericlist( $languageOptions, 'language', 'class="form-select"', 'value', 'text', $record->language, 'aigenerator_language', 'languagecode' ); // Append a flag button image if the language is a specific one if($record->language && $record->language != '*') { $lists['languages'] .= '<img id="language_flag_image" src="' . JUri::root(false) . 'media/mod_languages/images/' . JString::str_ireplace('-', '_', $record->language) . '.gif" alt="language_flag" />'; } } return $lists; } /** * Main get data methods * * @access public * @return Object[] */ public function getData() { // Build query $query = $this->buildListQuery (); $this->_db->setQuery ( $query, $this->getState ( 'limitstart' ), $this->getState ( 'limit' ) ); try { $result = $this->_db->loadObjectList (); if($this->_db->getErrorNum()) { throw new JMapException(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA') . $this->_db->getErrorMsg(), 'error'); } } catch (JMapException $e) { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); $result = array(); } catch (Exception $e) { $jmapException = new JMapException($e->getMessage(), 'error'); $this->app->enqueueMessage($jmapException->getMessage(), $jmapException->getErrorLevel()); $result = array(); } return $result; } /** * Delete entity * * @param array $ids * @access public * @return boolean */ public function deleteEntity($ids) { $table = $this->getTable (); // Ciclo su ogni entity da cancellare if (is_array ( $ids ) && count ( $ids )) { foreach ( $ids as $id ) { try { $table->load($id); if($table->api == 'openai') { // If AI model is ChatGPT, delete also local images files $imagesFolder = md5($table->keywords_phrase); $imagesPath = JPATH_ROOT . '/administrator/components/com_jmap/cache/chatgpt/' . $imagesFolder; if(is_dir($imagesPath)) { JFolder::delete($imagesPath); } } if (! $table->delete ( $id )) { throw new JMapException ( $table->getError (), 'error' ); } } catch ( JMapException $e ) { $this->setError ( $e ); return false; } catch ( Exception $e ) { $jmapException = new JMapException ( $e->getMessage (), 'error' ); $this->setError ( $jmapException ); return false; } } } return true; } /** * Generate data method for the AI contents API * * @access public * @param string $keywordPhrase * @param string $selectedApi * @return mixed Contents on success, false on failure exceptions */ public function generateAIContentData($keywordPhrase, $selectedApi) { $cParams = $this->getComponentParams (); // Hold the final concatenated contents to be returned and stored in the DB $serviceAIContents = ''; // BING API endpoint if($selectedApi == 'bing') { $url = "https://www.bing.com/news/search?q=%s&setlang=%s&format=RSS"; } else { $url = ''; } // Format the API endpoint based on user's settings $keywordPhraseEncoded = urlencode($keywordPhrase); $apiUrl = sprintf($url, $keywordPhraseEncoded, $this->getState('contentlanguage')); try { // Fetch remote data to scrape $httpTransport = $cParams->get ( 'aigenerator_service_http_transport', 'curl' ) == 'socket' ? 'file_get_contents' : new JMapHttpTransportCurl(true); if (is_object ( $httpTransport )) { $connectionAdapter = new JMapHttp ( $httpTransport, $cParams ); } if($selectedApi == 'bing') { // CURL lib if (is_object ( $httpTransport )) { // Init headers $headers = array ( 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Language' => 'en,it;q=0.9,en-US;q=0.8,de;q=0.7,es;q=0.6,fr;q=0.5,ru;q=0.4,ja;q=0.3,el;q=0.2,sk;q=0.1,nl;q=0.1,ar;q=0.1,sv;q=0.1,da;q=0.1', 'Cache-Control' => 'no-cache', 'Connection' => 'keep-alive', 'Pragma' => 'no-cache', 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.4664.93 Safari/537.36' ); $httpResponse = $connectionAdapter->get ( $apiUrl, $headers ); } else { // file_get_contents case $opts = array ( 'http' => array ( 'method' => "GET", 'header' => "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n" . "Accept-Language: en,it;q=0.9,en-US;q=0.8,de;q=0.7,es;q=0.6,fr;q=0.5,ru;q=0.4,ja;q=0.3,el;q=0.2,sk;q=0.1,nl;q=0.1,ar;q=0.1,sv;q=0.1,da;q=0.1\r\n" . "Cache-Control: no-cache\r\n" . "Connection: keep-alive\r\n" . "Pragma: no-cache\r\n" . "User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.4664.93 Safari/537.36", 'timeout' => 5 ) ); $context = stream_context_create ( $opts ); $response = file_get_contents ( $apiUrl, false, $context ); if ($response) { $httpResponse = new JMapHttpResponse(); $httpResponse->code = 200; $httpResponse->body = $response; } else { throw new RuntimeException ( JText::sprintf ( 'COM_JMAP_AIGENERATOR_ERROR_GENERATING_CONTENT', 409 ) ); } } // Check if HTTP status code is 200 OK if ($httpResponse->code != 200 || !$httpResponse->body) { throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_GENERATING_CONTENT', $httpResponse->code) ); } // Process result as XML document. Extract all single feed URLs for further AI scraping analyzing libxml_use_internal_errors(true); $objXmlDocument = simplexml_load_string($httpResponse->body); if ($objXmlDocument === false) { $errors = []; foreach(libxml_get_errors() as $error) { $errors[] = $error->message; } throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_XML', implode('. ', $errors)) ); } $objJsonDocument = json_encode($objXmlDocument); $feedArrayStructure = json_decode($objJsonDocument, true); if(!is_array($feedArrayStructure)) { throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_DATA' )); } } else { // Do a Google SERP and build simulate an RSS feed from Google SERPs $customHeaders = array ( 'acceptlanguage' => $this->getState ( 'contentlanguage' ), 'cookie' => 'CGIC=InZ0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSxpbWFnZS93ZWJwLGltYWdlL2FwbmcsKi8qO3E9MC44LGFwcGxpY2F0aW9uL3NpZ25lZC1leGNoYW5nZTt2PWIz; CONSENT=YES+GB.en+20151207-13-0; SEARCH_SAMESITE=CgQI3o0B; SID=oQeF2oOrI8ct0mg68RmuhS9lq-rL5YDqzv_oWZFHyFm6SZYu_9MqGGFtgMqEco0A-5927g.; HSID=A6bVsYvjyB4aFQt1R; SSID=AMbs1MzN52UyDqZwm; APISID=iHy5G9KqldrHN2Nf/AQP6jZh1BhpuJLCqt; SAPISID=CkVydZgJs3KyBEJk/AEU5W6P4uiXHScqyS; ANID=AHWqTUmybJX0DetXtktJFaw06fqjq77B9CbX7QR6GkOKlYm1lB1MCUWoNbOE0Lu7; NID=188=FY6KW-ygeYgrkLl8FnyQBrChL9FP1UoS9WWs3IbJLqnuAmK6qATL-gwSNV6tSl4d7sgUU5By9tFM9zp1phivP9oykPRtPsqf4zH37OpRmjYxq6R0SSJr0Ez41qbw3HYW-uY0R_5sG-CE5jCEYWzEMU8Hb-emr51PGPeTKbeQQVOElFVjrVkJiPLQbNB8Sma6BEzzYwiFC6U-rXs1_Y42mcJEjTh31y40M00ffpGEXpTkmY1DJb4LKX6se0KnQk4YGBgzLoNhB5GyKv5YeL74yURM3linL_UeIqE3FskyQG1y; 1P_JAR=2019-9-20-15; DV=k4rz414DoMFIgAbC04tAEYubN-jz1JZw4P5MyRCtQwAAACD7P2SWOiEwcAAAAHC4M1I0Yx1kMQAAAA; SIDCC=AN0-TYvfXZ1gZPUm4szeckxeJXAciDzQvACQp6tDglk9LWV4SqY3nvNYozuIr2DLAn8IwgI8fvs' ); $feedArrayStructure = [ ]; $feedArrayStructure ['channel'] = [ ]; $feedArrayStructure ['channel'] ['item'] = [ ]; $maxSerpsResults = $this->getState ( 'maxresults' ); if ($maxSerpsResults >= 1 && $maxSerpsResults <= 10) { $maxPages = 2; } elseif ($maxSerpsResults >= 11 && $maxSerpsResults <= 20) { $maxPages = 3; } elseif ($maxSerpsResults >= 21 && $maxSerpsResults <= 30) { $maxPages = 4; } elseif ($maxSerpsResults >= 31 && $maxSerpsResults <= 40) { $maxPages = 5; } elseif ($maxSerpsResults >= 41 && $maxSerpsResults <= 50) { $maxPages = 6; } $startPageCounter = 1; for($p = 0; $p < $maxPages; $p ++) { $results = JMapSeostatsServicesGoogle::getSerps ( $keywordPhrase, $startPageCounter * 10, $customHeaders ); if ($results) { foreach ( $results as $page ) { foreach ( $page as $pageSerp ) { $feedArrayStructure ['channel'] ['item'] [] = $pageSerp ['url']; } } } $startPageCounter++; } } if(!isset($feedArrayStructure['channel']['item'])) { throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_DATA_ITEM' )); } if(count($feedArrayStructure['channel']['item']) == 0) { throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_DATA_EMPTY_ITEM' )); } // Start crawling and elaborating remote resources $counter = 0; $limitSnippets = $this->getState('maxresults'); foreach ($feedArrayStructure['channel']['item'] as $itemLinkToAnalyze) { // Hold the response for a given page $serviceAIResponse = ''; $queryVars = []; // CURL lib if (is_object ( $httpTransport )) { // Parse the full URL if($selectedApi == 'bing') { $parsedUrl = parse_url($itemLinkToAnalyze['link']); parse_str($parsedUrl['query'], $queryVars); } else { $queryVars['url'] = $itemLinkToAnalyze; } $httpResponse = $connectionAdapter->get ( $queryVars['url'] ); // Check if HTTP status code is 200 OK if ($httpResponse->code != 200 || !$httpResponse->body) { continue; } // Set the response contents $serviceAIResponse = $httpResponse->body; // Put the case to lower $httpResponse->headers = array_change_key_case($httpResponse->headers, CASE_LOWER); // Detect if contents are utf8 encoded otherwise convert them if(isset($httpResponse->headers['content-type']) && !preg_match('/utf-8/i', $httpResponse->headers['content-type'])) { /** * Note: PHP Readability expects UTF-8 encoded content. * If your content is not UTF-8 encoded, convert it * first before passing it to PHP Readability. */ if(preg_match('/ISO-8859-1/i', $httpResponse->headers['content-type'])) { $fromEncoding = 'ISO-8859-1'; } else { $fromEncoding = mb_detect_encoding($serviceAIResponse); } if($fromEncoding) { $serviceAIResponse = mb_convert_encoding($serviceAIResponse, 'UTF-8', $fromEncoding); } else { continue; } } } else { $queryVars['url'] = $itemLinkToAnalyze['link']; $serviceAIResponse = file_get_contents ( $itemLinkToAnalyze['link'], false, $context ); if (!$serviceAIResponse) { continue; } } /** * If we've got Tidy, let's clean up input. * This step is highly recommended - PHP's default HTML parser * often doesn't do a great job and results in strange output. */ if (function_exists('tidy_parse_string')) { $tidy = tidy_parse_string($serviceAIResponse, array(), 'UTF8'); $tidy->cleanRepair(); $serviceAIResponse = $tidy->value; } $readability = new JMapAigeneratorReadability($serviceAIResponse, $queryVars['url']); $result = $readability->init(); $readability->removeScripts($readability->getContent()); if ($result) { $readabilityTitle = JString::ucfirst($readability->getTitle()->textContent); $readabilityContents = $readability->getContent()->innerHTML; // If we've got Tidy, let's clean it up for output if (function_exists('tidy_parse_string')) { $tidy = tidy_parse_string($readabilityContents, array('indent'=>true, 'show-body-only' => true), 'UTF8'); $tidy->cleanRepair(); $serviceAIContents .= '{title}' . $readabilityTitle . '{/title}{content}' . $tidy->value . '{/content}{contentdivider}'; } else { $readabilityContents = JMapAigeneratorHtmlawed::executeHtmlLawed($readabilityContents); $serviceAIContents .= '{title}' . $readabilityTitle . '{/title}{content}' . $readabilityContents . '{/content}{contentdivider}'; } } // Respect pagination max snippets limit if($counter == ($limitSnippets - 1)) { break; } $counter++; } } catch ( RuntimeException $e ) { $jmapException = new JMapException ( $e->getMessage (), 'error' ); $this->setError ( $jmapException ); return false; } catch ( Exception $e ) { $jmapException = new JMapException ( $e->getMessage (), 'error' ); $this->setError ( $jmapException ); return false; } // Clean the content from common pitfalls $serviceAIContents = $this->purifyContents($serviceAIContents); return $serviceAIContents; } /** * Generate data method for the AI contents API * * @access public * @param string $keywordPhrase * @param string $onlyPredicted * @return mixed Contents on success, false on failure exceptions */ public function generateOpenAIContentData($keywordPhrase, $onlyPredicted = false) { $cParams = $this->getComponentParams (); // Hold the final concatenated contents to be returned and stored in the DB $serviceAIContents = ''; // ChatGPT API $chatgptApi = $cParams->get('chatgpt_api', 'completions'); $chatgptModel = $cParams->get('chatgpt_api_model', 'gpt-3.5-turbo'); if($chatgptApi == 'completions') { $apiUrl = "https://api.openai.com/v1/completions"; } else { $apiUrl = 'https://api.openai.com/v1/chat/completions'; } $apiImageUrl = "https://api.openai.com/v1/images/generations"; $removeImages = $this->getState('removeimgs'); $openAiApiKey = trim($cParams->get('chatgpt_apikey', '')); $numResults = (int)$this->getState('maxresults'); $temperature = (float)$this->getState('temperature'); $maxTokens = (int)$cParams->get('chatgpt_maxtokens', 2048); $imageSize = $cParams->get('chatgpt_images_size', '256x256'); try { // The ApiKey is required if(!$openAiApiKey) { throw new Exception ( JText::_( 'COM_JMAP_AIGENERATOR_CHATGPT_MISSING_APIKEY') ); } // Fetch remote data to scrape $httpTransport = $cParams->get ( 'aigenerator_service_http_transport', 'curl' ) == 'socket' ? 'file_get_contents' : new JMapHttpTransportCurl (true); // CURL lib if (is_object ( $httpTransport )) { $connectionAdapter = new JMapHttp ( $httpTransport, $cParams ); // Init headers $headers = array ( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $openAiApiKey ); // Open AI text post params if($chatgptApi == 'completions') { $postData = [ 'max_tokens' => $maxTokens, 'model' => 'gpt-3.5-turbo-instruct', 'n' => $numResults, 'temperature' => $temperature, 'prompt' => strip_tags ( $keywordPhrase ) ]; } else { $postData = [ 'max_tokens' => $maxTokens, 'model' => $chatgptModel, 'n' => $numResults, 'temperature' => $temperature, 'messages' => [ [ 'role' => 'user', 'content' => strip_tags ( $keywordPhrase ) ] ] ]; } $httpResponse = $connectionAdapter->post ( $apiUrl, json_encode($postData), $headers ); // Open AI images post params if(!$removeImages && $httpResponse->code == 200) { $postDataImages = [ 'n' => $numResults, 'size' => $imageSize, 'prompt' => strip_tags($keywordPhrase) ]; $httpResponseImages = $connectionAdapter->post ($apiImageUrl, json_encode($postDataImages), $headers); } } else { // file_get_contents case // Open AI post params if($chatgptApi == 'completions') { $postData = json_encode ( [ 'max_tokens' => $maxTokens, 'model' => 'gpt-3.5-turbo-instruct', 'n' => $numResults, 'temperature' => $temperature, 'prompt' => strip_tags ( $keywordPhrase ) ] ); } else { $postData = json_encode ( [ 'max_tokens' => $maxTokens, 'model' => $chatgptModel, 'n' => $numResults, 'temperature' => $temperature, 'messages' => [ [ 'role' => 'user', 'content' => strip_tags ( $keywordPhrase ) ] ] ] ); } $opts = array ( 'http' => array ( 'method' => "POST", 'header' => "Content-Type: application/json\r\n" . "Authorization: Bearer $openAiApiKey\r\n", 'content' => $postData, 'timeout' => 20 ) ); $context = stream_context_create ( $opts ); $response = file_get_contents ( $apiUrl, false, $context ); if ($response) { $httpResponse = new JMapHttpResponse (); $httpResponse->code = 200; $httpResponse->body = $response; if(!$removeImages) { // Open AI images post params $postDataImages = json_encode( [ 'n' => $numResults, 'size' => $imageSize, 'prompt' => strip_tags ( $keywordPhrase ) ] ); $opts = array ( 'http' => array ( 'method' => "POST", 'header' => "Content-Type: application/json\r\n" . "Authorization: Bearer $openAiApiKey\r\n", 'content' => $postDataImages, 'timeout' => 20 ) ); $context = stream_context_create ( $opts ); $responseImages = file_get_contents ( $apiImageUrl, false, $context ); if($responseImages) { $httpResponseImages = new JMapHttpResponse (); $httpResponseImages->code = 200; $httpResponseImages->body = $responseImages; } else { throw new RuntimeException ( JText::sprintf ( 'COM_JMAP_AIGENERATOR_ERROR_GENERATING_CONTENT', 409 ) ); } } } else { throw new RuntimeException ( JText::sprintf ( 'COM_JMAP_AIGENERATOR_ERROR_GENERATING_CONTENT', 409 ) ); } } // Check if HTTP status code is 200 OK if ($httpResponse->code != 200 || !$httpResponse->body) { $errorInfo = $httpResponse->code; if($httpResponse->body) { $responseError = json_decode($httpResponse->body)->error->message; $errorInfo = $errorInfo . ' - ' . $responseError; } throw new RuntimeException ( JText::sprintf( 'COM_JMAP_AIGENERATOR_ERROR_GENERATING_CONTENT', $errorInfo) ); } // Success response to parse $responseChatGPT = json_decode($httpResponse->body); // Check if the HTTP status code for images is 200 OK if(!$removeImages) { $imagesFolder = md5($keywordPhrase); $imagesPath = JPATH_ROOT . '/administrator/components/com_jmap/cache/chatgpt/' . $imagesFolder; if(!is_dir($imagesPath)) { JFolder::create($imagesPath); } $responseChatGPTImages = []; if ($httpResponseImages->code == 200 && $httpResponseImages->body) { $responseChatGPTImages = json_decode($httpResponseImages->body)->data; } } $choices = $responseChatGPT->choices; foreach ( $choices as $index => $chatChoice ) { if (! $removeImages && array_key_exists ( $index, $responseChatGPTImages )) { // Fetch of the remote image and local storing $imgTag = ''; $bin = file_get_contents ( $responseChatGPTImages [$index]->url ); $nameChunks = explode ( '?', $responseChatGPTImages [$index]->url ); $imgUrl = $nameChunks [0]; $urlChunks = explode ( '/', $imgUrl ); $fileName = array_pop ( $urlChunks ); file_put_contents ( JPATH_ROOT . '/administrator/components/com_jmap/cache/chatgpt/' . $imagesFolder . '/' . $fileName, $bin ); $imgTag = '<img src="' . JUri::root ( false ) . 'administrator/components/com_jmap/cache/chatgpt/' . $imagesFolder . '/' . $fileName . '"/>'; if($chatgptApi == 'completions') { $chatChoice->text = '<div class="chatgpt-snippet-image">' . $imgTag . '</div>' . $chatChoice->text; } else { $chatChoice->text = '<div class="chatgpt-snippet-image">' . $imgTag . '</div>' . $chatChoice->message->content; } } else { if($chatgptApi == 'completions') { $chatChoice->text = $chatChoice->text; } else { $chatChoice->text = $chatChoice->message->content; } } $serviceAIContents .= '{title}' . JString::ucfirst ( $keywordPhrase ) . ' #' . ($index + 1) . '{/title} {content}' . $chatChoice->text . '{/content}{contentdivider}'; } } catch ( RuntimeException $e ) { $jmapException = new JMapException ( $e->getMessage (), 'error' ); $this->setError ( $jmapException ); return false; } catch ( Exception $e ) { $jmapException = new JMapException ( $e->getMessage (), 'error' ); $this->setError ( $jmapException ); return false; } // Return only the simple ChatGPT response without any addition or alteration if($onlyPredicted) { return $chatChoice->text; } // Clean the content from common pitfalls $serviceAIContents = $this->purifyContents($serviceAIContents); return $serviceAIContents; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Генерация страницы: 2.32 |
proxy
|
phpinfo
|
Настройка