Your project uses non-strict array lookups

More information: https://insight.symfony.com/what-we-analyse/php.strict_array_lookup

  1. */
  2. public static function checkExecEnabled(): bool
  3. {
  4. $disabled = explode(', ', ini_get('disable_functions'));
  5. return !in_array('exec', $disabled);
    in_array() should be called with the third parameter set to true to enable strict comparison and avoid type juggling bugs.
    Time to fix: about 15 minutes
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. }
  7. /**
  8. * Checks if Composer is installed and accessible in the current environment.
  9. *
  • gyakutsuki

    not implemented
  • gyakutsuki

    not included
  • gyakutsuki

    no included
  • gyakutsuki

    no implemented

Your project should use dedicated PHP string functions 154

More information: https://insight.symfony.com/what-we-analyse/php.use_string_function

  1. {
  2. $query = strtolower($query);
  3. $detected = [];
  4. foreach (self::$temporalConnectors as $connector) {
  5. if (strpos($query, $connector) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $detected[] = $connector;
  7. }
  8. }
  9. return $detected;
  • gyakutsuki

    not included
  1. public static function hasFinancialMetric(string $query): bool
  2. {
  3. $query = strtolower($query);
  4. foreach (self::$financialMetrics as $metric) {
  5. if (strpos($query, $metric) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. public static function hasTemporalConnector(string $query): bool
  2. {
  3. $query = strtolower($query);
  4. foreach (self::$temporalConnectors as $connector) {
  5. if (strpos($query, $connector) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. if (strlen($word) < 2) {
  2. return $word;
  3. }
  4. // Words ending in "y" -> "ies" (e.g., "category" -> "categories")
  5. if (substr($word, -1) === 'y') {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return substr($word, 0, -1) . 'ies';
  7. }
  8. // Words ending in "s", "x", "z", "ch", "sh" -> add "es"
  9. if (preg_match('/(s|x|z|ch|sh)$/i', $word)) {
  • gyakutsuki

    not included
  1. if (strlen($word) < 2) {
  2. return $word;
  3. }
  4. // Words ending in "ies" -> "y" (e.g., "categories" -> "category")
  5. if (substr($word, -3) === 'ies') {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return substr($word, 0, -3) . 'y';
  7. }
  8. // Words ending in "es" -> remove "es" (e.g., "boxes" -> "box")
  9. if (substr($word, -2) === 'es') {
  • gyakutsuki

    not included
  1. if (isset($specialCases[$entityType])) {
  2. return $specialCases[$entityType];
  3. }
  4. // Handle compound words with underscores (e.g., "return_orders" -> "return_order")
  5. if (strpos($entityType, '_') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $parts = explode('_', $entityType);
  7. $lastPart = array_pop($parts);
  8. // Apply singularization to the last part only
  9. $singularLastPart = self::singularizeWord($lastPart);
  • gyakutsuki

    not included
  1. if (substr($word, -2) === 'es') {
  2. return substr($word, 0, -2);
  3. }
  4. // Words ending in "s" -> remove "s" (e.g., "products" -> "product")
  5. if (substr($word, -1) === 's') {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return substr($word, 0, -1);
  7. }
  8. // No change needed
  9. return $word;
  • gyakutsuki

    not included
  1. if (isset($specialCases[$entityType])) {
  2. return $specialCases[$entityType];
  3. }
  4. // Handle compound words with underscores
  5. if (strpos($entityType, '_') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $parts = explode('_', $entityType);
  7. $lastPart = array_pop($parts);
  8. // Apply pluralization to the last part only
  9. $pluralLastPart = self::pluralizeWord($lastPart);
  • gyakutsuki

    not included
  1. if (substr($word, -3) === 'ies') {
  2. return substr($word, 0, -3) . 'y';
  3. }
  4. // Words ending in "es" -> remove "es" (e.g., "boxes" -> "box")
  5. if (substr($word, -2) === 'es') {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return substr($word, 0, -2);
  7. }
  8. // Words ending in "s" -> remove "s" (e.g., "products" -> "product")
  9. if (substr($word, -1) === 's') {
  • gyakutsuki

    not included
  1. $errorMessage .= " (estimated tokens: {$estimatedTokens}, chunk size: {$token_length})";
  2. }
  3. error_log($errorMessage);
  4. if (strpos($e->getMessage(), 'maximum context length') !== false && $token_length > 200) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. error_log("Retrying with smaller chunk size...");
  6. return self::createEmbedding($path_file_upload, $text_description, (int)($token_length / 2));
  7. }
  8. return null;
  • gyakutsuki

    not included
  1. */
  2. private static function checkApiKeys(string $model): bool
  3. {
  4. if (strpos($model, 'gpt') === 0) {
  5. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY);
  6. } elseif (strpos($model, 'mistral') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL);
  8. } elseif (strpos($model, 'voyage') === 0) {
  9. return !empty(CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI);
  10. } elseif (strpos($model, 'ollama') === 0) {
  11. return true;
  • gyakutsuki

    not included
  1. private static function getModelProvider(string $model): string
  2. {
  3. if (strpos($model, 'gpt') === 0) return 'openai';
  4. if (strpos($model, 'mistral') === 0) return 'mistral';
  5. if (strpos($model, 'voyage') === 0) return 'voyageai';
  6. if (strpos($model, 'nomic') === 0) return 'ollama';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 'unknown';
  8. }
  9. //*********************
  • gyakutsuki

    not included
  1. return new OpenAI3LargeEmbeddingGenerator($config);
  2. } elseif (strpos($model, 'gpt-medium') === 0) {
  3. $config = new OpenAIConfig();
  4. $config->apiKey = $api_key;
  5. return new OpenAI3SmallEmbeddingGenerator($config);
  6. } elseif (strpos($model, 'mistral') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. $config = new OpenAIConfig();
  8. $config->apiKey = $api_key;
  9. return new MistralEmbeddingGenerator($config);
  10. } elseif (strpos($model, 'voyage3-large') === 0) {
  11. $config = new VoyageAIConfig();
  • gyakutsuki

    not included
  1. return null;
  2. }
  3. $api_key = self::getApiKey();
  4. if (strpos($model, 'gpt-large') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  5. $config = new OpenAIConfig();
  6. $config->apiKey = $api_key;
  7. return new OpenAI3LargeEmbeddingGenerator($config);
  8. } elseif (strpos($model, 'gpt-medium') === 0) {
  9. $config = new OpenAIConfig();
  • gyakutsuki

    not included
  1. return new Voyage3LargeEmbeddingGenerator($config);
  2. } elseif (strpos($model, 'voyage3-lite') === 0) {
  3. $config = new VoyageAIConfig();
  4. $config->apiKey = $api_key;
  5. return new Voyage3LiteEmbeddingGenerator($config);
  6. } elseif (strpos($model, 'voyage3') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. $config = new VoyageAIConfig();
  8. $config->apiKey = $api_key;
  9. return new Voyage3EmbeddingGenerator($config);
  10. } else {
  11. return new OllamaEmbeddingGenerator($model);
  • gyakutsuki

    not included
  1. return new OpenAI3SmallEmbeddingGenerator($config);
  2. } elseif (strpos($model, 'mistral') === 0) {
  3. $config = new OpenAIConfig();
  4. $config->apiKey = $api_key;
  5. return new MistralEmbeddingGenerator($config);
  6. } elseif (strpos($model, 'voyage3-large') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. $config = new VoyageAIConfig();
  8. $config->apiKey = $api_key;
  9. return new Voyage3LargeEmbeddingGenerator($config);
  10. } elseif (strpos($model, 'voyage3-lite') === 0) {
  11. $config = new VoyageAIConfig();
  • gyakutsuki

    not included
  1. {
  2. if (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-large') === 0) {
  3. return 3072;
  4. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-medium') === 0) {
  5. return 1536;
  6. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 1024;
  8. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-large') === 0) {
  9. return 4096;
  10. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-lite') === 0) {
  11. return 384;
  • gyakutsuki

    not included
  1. 'voyage3-lite' => 300,
  2. 'nomic-embed-text' => 800,
  3. ];
  4. foreach ($chunkSizes as $modelPrefix => $size) {
  5. if (strpos($model, $modelPrefix) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return $size;
  7. }
  8. }
  9. return 500;
  • gyakutsuki

    not included
  1. *
  2. * @return int The embedding length in dimensions for the selected model
  3. */
  4. public static function getEmbeddingLength(): int
  5. {
  6. if (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-large') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 3072;
  8. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-medium') === 0) {
  9. return 1536;
  10. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
  11. return 1024;
  • gyakutsuki

    not included
  1. return 1536;
  2. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
  3. return 1024;
  4. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-large') === 0) {
  5. return 4096;
  6. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-lite') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 384;
  8. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3') === 0) {
  9. return 1024;
  10. } else {
  11. return 1536;
  • gyakutsuki

    not included
  1. 'voyage3-lite' => 4000,
  2. 'nomic-embed-text' => 8192,
  3. ];
  4. foreach ($contextLengths as $modelPrefix => $length) {
  5. if (strpos($model, $modelPrefix) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return $length;
  7. }
  8. }
  9. return 4096;
  • gyakutsuki

    not included
  1. return new MistralEmbeddingGenerator($config);
  2. } elseif (strpos($model, 'voyage3-large') === 0) {
  3. $config = new VoyageAIConfig();
  4. $config->apiKey = $api_key;
  5. return new Voyage3LargeEmbeddingGenerator($config);
  6. } elseif (strpos($model, 'voyage3-lite') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. $config = new VoyageAIConfig();
  8. $config->apiKey = $api_key;
  9. return new Voyage3LiteEmbeddingGenerator($config);
  10. } elseif (strpos($model, 'voyage3') === 0) {
  11. $config = new VoyageAIConfig();
  • gyakutsuki

    not included
  1. */
  2. private static function getApiKey(): string
  3. {
  4. $api_key = CLICSHOPPING_APP_CHATGPT_CH_API_KEY;
  5. if (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $api_key = CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL;
  7. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage') === 0) {
  8. $api_key = CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI;
  9. }
  • gyakutsuki

    not included
  1. {
  2. if (strpos($model, 'gpt') === 0) {
  3. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY);
  4. } elseif (strpos($model, 'mistral') === 0) {
  5. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL);
  6. } elseif (strpos($model, 'voyage') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. return !empty(CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI);
  8. } elseif (strpos($model, 'ollama') === 0) {
  9. return true;
  10. }
  • gyakutsuki

    not included
  1. return 1024;
  2. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-large') === 0) {
  3. return 4096;
  4. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-lite') === 0) {
  5. return 384;
  6. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 1024;
  8. } else {
  9. return 1536;
  10. }
  11. }
  • gyakutsuki

    not included
  1. if (strpos($model, 'gpt-large') === 0) {
  2. $config = new OpenAIConfig();
  3. $config->apiKey = $api_key;
  4. return new OpenAI3LargeEmbeddingGenerator($config);
  5. } elseif (strpos($model, 'gpt-medium') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $config = new OpenAIConfig();
  7. $config->apiKey = $api_key;
  8. return new OpenAI3SmallEmbeddingGenerator($config);
  9. } elseif (strpos($model, 'mistral') === 0) {
  10. $config = new OpenAIConfig();
  • gyakutsuki

    not included
  1. */
  2. public static function getEmbeddingLength(): int
  3. {
  4. if (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-large') === 0) {
  5. return 3072;
  6. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-medium') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 1536;
  8. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
  9. return 1024;
  10. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-large') === 0) {
  11. return 4096;
  • gyakutsuki

    not included
  1. * @param string $model
  2. * @return string
  3. */
  4. private static function getModelProvider(string $model): string
  5. {
  6. if (strpos($model, 'gpt') === 0) return 'openai';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. if (strpos($model, 'mistral') === 0) return 'mistral';
  8. if (strpos($model, 'voyage') === 0) return 'voyageai';
  9. if (strpos($model, 'nomic') === 0) return 'ollama';
  10. return 'unknown';
  • gyakutsuki

    not included
  1. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY);
  2. } elseif (strpos($model, 'mistral') === 0) {
  3. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL);
  4. } elseif (strpos($model, 'voyage') === 0) {
  5. return !empty(CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI);
  6. } elseif (strpos($model, 'ollama') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. return true;
  8. }
  9. return false;
  10. }
  • gyakutsuki

    not included
  1. {
  2. $api_key = CLICSHOPPING_APP_CHATGPT_CH_API_KEY;
  3. if (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
  4. $api_key = CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL;
  5. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $api_key = CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI;
  7. }
  8. return $api_key;
  9. }
  • gyakutsuki

    not included
  1. * @return string
  2. */
  3. private static function getModelProvider(string $model): string
  4. {
  5. if (strpos($model, 'gpt') === 0) return 'openai';
  6. if (strpos($model, 'mistral') === 0) return 'mistral';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. if (strpos($model, 'voyage') === 0) return 'voyageai';
  8. if (strpos($model, 'nomic') === 0) return 'ollama';
  9. return 'unknown';
  10. }
  • gyakutsuki

    not included
  1. */
  2. private static function estimateTokenCount(string $text): int
  3. {
  4. $model = CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL;
  5. if (strpos($model, 'gpt') === 0 || strpos($model, 'voyage') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $avgCharsPerToken = 3.5;
  7. return (int)ceil(strlen($text) / $avgCharsPerToken);
  8. }
  9. return (int)ceil(strlen($text) / 4);
  • gyakutsuki

    not included
  1. */
  2. private static function getModelProvider(string $model): string
  3. {
  4. if (strpos($model, 'gpt') === 0) return 'openai';
  5. if (strpos($model, 'mistral') === 0) return 'mistral';
  6. if (strpos($model, 'voyage') === 0) return 'voyageai';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. if (strpos($model, 'nomic') === 0) return 'ollama';
  8. return 'unknown';
  9. }
  • gyakutsuki

    not included
  1. * @param string $model The embedding model to check
  2. * @return bool True if API keys are available, false otherwise
  3. */
  4. private static function checkApiKeys(string $model): bool
  5. {
  6. if (strpos($model, 'gpt') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY);
  8. } elseif (strpos($model, 'mistral') === 0) {
  9. return !empty(CLICSHOPPING_APP_CHATGPT_CH_API_KEY_MISTRAL);
  10. } elseif (strpos($model, 'voyage') === 0) {
  11. return !empty(CLICSHOPPING_APP_CHATGPT_RA_API_KEY_VOYAGE_AI);
  • gyakutsuki

    not included
  1. return 3072;
  2. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'gpt-medium') === 0) {
  3. return 1536;
  4. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'mistral') === 0) {
  5. return 1024;
  6. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-large') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return 4096;
  8. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3-lite') === 0) {
  9. return 384;
  10. } elseif (strpos(CLICSHOPPING_APP_CHATGPT_RA_EMBEDDING_MODEL, 'voyage3') === 0) {
  11. return 1024;
  • gyakutsuki

    not included
  1. $oldFiles = array_merge(
  2. glob($oldCacheDir . 'Rag_Embedding_*.cache'),
  3. glob($oldCacheDir . 'embedding_*.cache')
  4. );
  5. $oldFiles = array_filter($oldFiles, function($file) {
  6. return strpos(basename($file), 'embedding_search_') !== 0;
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. });
  8. $filesBefore += count($oldFiles);
  9. foreach ($oldFiles as $file) {
  10. @unlink($file);
  11. }
  • gyakutsuki

    not included
  1. $oldFilesAfter = array_merge(
  2. glob($oldCacheDir . 'Rag_Embedding_*.cache'),
  3. glob($oldCacheDir . 'embedding_*.cache')
  4. );
  5. $oldFilesAfter = array_filter($oldFilesAfter, function($file) {
  6. return strpos(basename($file), 'embedding_search_') !== 0;
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. });
  8. $filesAfter += count($oldFilesAfter);
  9. }
  10. $results['embeddings'] = $filesBefore - $filesAfter;
  • gyakutsuki

    not included
  1. $oldFiles = array_merge(
  2. glob($oldCacheDir . 'Rag_Embedding_*.cache'),
  3. glob($oldCacheDir . 'embedding_*.cache')
  4. );
  5. $oldFiles = array_filter($oldFiles, function($file) {
  6. return strpos(basename($file), 'embedding_search_') !== 0;
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. });
  8. $filesAfter += count($oldFiles);
  9. }
  10. $results['embedding'] = $filesBefore - $filesAfter;
  • gyakutsuki

    not included
  1. $supplierBonus = 0;
  2. $manufacturerBonus = 0;
  3. foreach ($supplierIndicators as $indicator) {
  4. if (strpos($query, $indicator) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $supplierBonus += 1.0;
  6. }
  7. }
  8. foreach ($manufacturerIndicators as $indicator) {
  • gyakutsuki

    not included
  1. if (abs($reviewScore - $sentimentScore) < 0.5) {
  2. $sentimentIndicators = ['sentiment', 'feeling', 'positive', 'negative', 'emotion', 'analysis'];
  3. $sentimentBonus = 0;
  4. foreach ($sentimentIndicators as $indicator) {
  5. if (strpos($query, $indicator) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $sentimentBonus += 0.5;
  7. }
  8. }
  9. if ($sentimentBonus > 0) {
  • gyakutsuki

    not included
  1. $supplierBonus += 1.0;
  2. }
  3. }
  4. foreach ($manufacturerIndicators as $indicator) {
  5. if (strpos($query, $indicator) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $manufacturerBonus += 1.0;
  7. }
  8. }
  9. $scores['suppliers']['score'] += $supplierBonus;
  • gyakutsuki

    not included
  1. foreach ($termGroups as $groupType => $terms) {
  2. $weight = $this->termWeights[$groupType] ?? 0.5;
  3. foreach ($terms as $term) {
  4. if (strpos($query, $term) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $domainScore += $weight;
  6. $matchedTerms[] = [
  7. 'term' => $term,
  8. 'type' => $groupType,
  9. 'weight' => $weight,
  • gyakutsuki

    not included
  1. return $pricing;
  2. }
  3. }
  4. // Détection par provider
  5. if (strpos($model, 'gpt') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return self::PRICING['gpt-3.5-turbo']; // Défaut OpenAI
  7. }
  8. if (strpos($model, 'claude') !== false) {
  9. return self::PRICING['claude-3-haiku']; // Défaut Anthropic (le moins cher)
  10. }
  • gyakutsuki

    not included
  1. return self::PRICING[$model];
  2. }
  3. // Match partiel (ex: "gpt-4-0613" match "gpt-4")
  4. foreach (self::PRICING as $knownModel => $pricing) {
  5. if (strpos($model, $knownModel) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return $pricing;
  7. }
  8. }
  9. // Détection par provider
  • gyakutsuki

    not included
  1. return self::PRICING['claude-3-haiku']; // Défaut Anthropic (le moins cher)
  2. }
  3. if (strpos($model, 'mistral') !== false) {
  4. return self::PRICING['mistral-small']; // Défaut Mistral
  5. }
  6. if (strpos($model, 'llama') !== false || strpos($model, 'ollama') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return [0.0, 0.0]; // Local, gratuit
  8. }
  9. return null;
  10. }
  • gyakutsuki

    not included
  1. // Détection par provider
  2. if (strpos($model, 'gpt') !== false) {
  3. return self::PRICING['gpt-3.5-turbo']; // Défaut OpenAI
  4. }
  5. if (strpos($model, 'claude') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return self::PRICING['claude-3-haiku']; // Défaut Anthropic (le moins cher)
  7. }
  8. if (strpos($model, 'mistral') !== false) {
  9. return self::PRICING['mistral-small']; // Défaut Mistral
  10. }
  • gyakutsuki

    not included
  1. return self::PRICING['gpt-3.5-turbo']; // Défaut OpenAI
  2. }
  3. if (strpos($model, 'claude') !== false) {
  4. return self::PRICING['claude-3-haiku']; // Défaut Anthropic (le moins cher)
  5. }
  6. if (strpos($model, 'mistral') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return self::PRICING['mistral-small']; // Défaut Mistral
  8. }
  9. if (strpos($model, 'llama') !== false || strpos($model, 'ollama') !== false) {
  10. return [0.0, 0.0]; // Local, gratuit
  11. }
  • gyakutsuki

    not included
  1. {
  2. $sql = trim(strtoupper($sql));
  3. if (strpos($sql, 'SELECT') === 0) return 'SELECT';
  4. if (strpos($sql, 'INSERT') === 0) return 'INSERT';
  5. if (strpos($sql, 'UPDATE') === 0) return 'UPDATE';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. if (strpos($sql, 'DELETE') === 0) return 'DELETE';
  7. return 'UNKNOWN';
  8. }
  • gyakutsuki

    not included
  1. $sql = trim(strtoupper($sql));
  2. if (strpos($sql, 'SELECT') === 0) return 'SELECT';
  3. if (strpos($sql, 'INSERT') === 0) return 'INSERT';
  4. if (strpos($sql, 'UPDATE') === 0) return 'UPDATE';
  5. if (strpos($sql, 'DELETE') === 0) return 'DELETE';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return 'UNKNOWN';
  7. }
  8. /**
  • gyakutsuki

    not included
  1. */
  2. private function detectQueryType(string $sql): string
  3. {
  4. $sql = trim(strtoupper($sql));
  5. if (strpos($sql, 'SELECT') === 0) return 'SELECT';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. if (strpos($sql, 'INSERT') === 0) return 'INSERT';
  7. if (strpos($sql, 'UPDATE') === 0) return 'UPDATE';
  8. if (strpos($sql, 'DELETE') === 0) return 'DELETE';
  9. return 'UNKNOWN';
  • gyakutsuki

    not included
  1. private function detectQueryType(string $sql): string
  2. {
  3. $sql = trim(strtoupper($sql));
  4. if (strpos($sql, 'SELECT') === 0) return 'SELECT';
  5. if (strpos($sql, 'INSERT') === 0) return 'INSERT';
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. if (strpos($sql, 'UPDATE') === 0) return 'UPDATE';
  7. if (strpos($sql, 'DELETE') === 0) return 'DELETE';
  8. return 'UNKNOWN';
  9. }
  • gyakutsuki

    not included
  1. $errorType = 'unknown';
  2. // Detect classification errors
  3. if (strpos($comment, 'wrong type') !== false ||
  4. strpos($comment, 'misclassified') !== false ||
  5. strpos($comment, 'should be analytics') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($comment, 'should be semantic') !== false) {
  7. $isClassificationError = true;
  8. $errorType = 'misclassification';
  9. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  10. $isClassificationError = true;
  • gyakutsuki

    not included
  1. 'wrong category',
  2. 'incorrect classification'
  3. ];
  4. foreach ($classificationKeywords as $keyword) {
  5. if (strpos($comment, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. if ($reason === 'irrelevant') {
  • gyakutsuki

    not included
  1. // Detect classification errors
  2. if (strpos($comment, 'wrong type') !== false ||
  3. strpos($comment, 'misclassified') !== false ||
  4. strpos($comment, 'should be analytics') !== false ||
  5. strpos($comment, 'should be semantic') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $isClassificationError = true;
  7. $errorType = 'misclassification';
  8. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  9. $isClassificationError = true;
  10. $errorType = 'irrelevant_result';
  • gyakutsuki

    not included
  1. $isClassificationError = false;
  2. $errorType = 'unknown';
  3. // Detect classification errors
  4. if (strpos($comment, 'wrong type') !== false ||
  5. strpos($comment, 'misclassified') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($comment, 'should be analytics') !== false ||
  7. strpos($comment, 'should be semantic') !== false) {
  8. $isClassificationError = true;
  9. $errorType = 'misclassification';
  10. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  • gyakutsuki

    not included
  1. $isClassificationError = false;
  2. $errorType = 'unknown';
  3. // Detect classification errors
  4. if (strpos($comment, 'wrong type') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. strpos($comment, 'misclassified') !== false ||
  6. strpos($comment, 'should be analytics') !== false ||
  7. strpos($comment, 'should be semantic') !== false) {
  8. $isClassificationError = true;
  9. $errorType = 'misclassification';
  • gyakutsuki

    not included
  1. strpos($comment, 'misclassified') !== false ||
  2. strpos($comment, 'should be analytics') !== false ||
  3. strpos($comment, 'should be semantic') !== false) {
  4. $isClassificationError = true;
  5. $errorType = 'misclassification';
  6. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $isClassificationError = true;
  8. $errorType = 'irrelevant_result';
  9. } elseif ($reason === 'incomplete' && strpos($comment, 'wrong') !== false) {
  10. $isClassificationError = true;
  11. $errorType = 'partial_misclassification';
  • gyakutsuki

    not included
  1. $isClassificationError = true;
  2. $errorType = 'misclassification';
  3. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  4. $isClassificationError = true;
  5. $errorType = 'irrelevant_result';
  6. } elseif ($reason === 'incomplete' && strpos($comment, 'wrong') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $isClassificationError = true;
  8. $errorType = 'partial_misclassification';
  9. }
  10. if ($isClassificationError) {
  • gyakutsuki

    not included
  1. public static function hasTimePeriod(string $query): bool
  2. {
  3. $query = strtolower($query);
  4. foreach (self::$timePeriods as $period) {
  5. if (strpos($query, $period) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. {
  2. $query = strtolower($query);
  3. $detected = [];
  4. foreach (self::$timePeriods as $period) {
  5. if (strpos($query, $period) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $detected[] = $period;
  7. }
  8. }
  9. return $detected;
  • gyakutsuki

    not included
  1. {
  2. $query = strtolower($query);
  3. $detected = [];
  4. foreach (self::$financialMetrics as $metric) {
  5. if (strpos($query, $metric) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $detected[] = $metric;
  7. }
  8. }
  9. return $detected;
  • gyakutsuki

    not included
  1. $errorType = 'unknown';
  2. // Detect classification errors
  3. if (strpos($comment, 'wrong type') !== false ||
  4. strpos($comment, 'misclassified') !== false ||
  5. strpos($comment, 'should be analytics') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($comment, 'should be semantic') !== false) {
  7. $isClassificationError = true;
  8. $errorType = 'misclassification';
  9. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  10. $isClassificationError = true;
  • gyakutsuki

    not included
  1. $isClassificationError = false;
  2. $errorType = 'unknown';
  3. // Detect classification errors
  4. if (strpos($comment, 'wrong type') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. strpos($comment, 'misclassified') !== false ||
  6. strpos($comment, 'should be analytics') !== false ||
  7. strpos($comment, 'should be semantic') !== false) {
  8. $isClassificationError = true;
  9. $errorType = 'misclassification';
  • gyakutsuki

    not included
  1. $isClassificationError = false;
  2. $errorType = 'unknown';
  3. // Detect classification errors
  4. if (strpos($comment, 'wrong type') !== false ||
  5. strpos($comment, 'misclassified') !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($comment, 'should be analytics') !== false ||
  7. strpos($comment, 'should be semantic') !== false) {
  8. $isClassificationError = true;
  9. $errorType = 'misclassification';
  10. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  • gyakutsuki

    not included
  1. // Detect classification errors
  2. if (strpos($comment, 'wrong type') !== false ||
  3. strpos($comment, 'misclassified') !== false ||
  4. strpos($comment, 'should be analytics') !== false ||
  5. strpos($comment, 'should be semantic') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $isClassificationError = true;
  7. $errorType = 'misclassification';
  8. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  9. $isClassificationError = true;
  10. $errorType = 'irrelevant_result';
  • gyakutsuki

    not included
  1. strpos($comment, 'misclassified') !== false ||
  2. strpos($comment, 'should be analytics') !== false ||
  3. strpos($comment, 'should be semantic') !== false) {
  4. $isClassificationError = true;
  5. $errorType = 'misclassification';
  6. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $isClassificationError = true;
  8. $errorType = 'irrelevant_result';
  9. } elseif ($reason === 'incomplete' && strpos($comment, 'wrong') !== false) {
  10. $isClassificationError = true;
  11. $errorType = 'partial_misclassification';
  • gyakutsuki

    not included
  1. $isClassificationError = true;
  2. $errorType = 'misclassification';
  3. } elseif ($reason === 'irrelevant' || strpos($comment, 'irrelevant') !== false) {
  4. $isClassificationError = true;
  5. $errorType = 'irrelevant_result';
  6. } elseif ($reason === 'incomplete' && strpos($comment, 'wrong') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $isClassificationError = true;
  8. $errorType = 'partial_misclassification';
  9. }
  10. if ($isClassificationError) {
  • gyakutsuki

    not included
  1. return false;
  2. }
  3. }
  4. // Model not found in list - check by prefix as fallback
  5. return strpos($model, 'gpt-5') === 0;
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. }
  7. /**
  8. * Get model context length limit
  9. *
  • gyakutsuki

    not included
  1. // Model-specific parameter mapping
  2. // GPT-4o-mini, GPT-4.1 series, GPT-5 series use max_completion_tokens
  3. if (strpos($model, 'gpt-4.1-mini') === 0 ||
  4. strpos($model, 'gpt-4.1') === 0 ||
  5. strpos($model, 'gpt-5') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $params['max_completion_tokens'] = $maxtoken;
  7. } else {
  8. // Default for GPT-4o, Anthropic, Mistral, LM Studio, and other models
  9. $params['max_tokens'] = $maxtoken;
  10. }
  • gyakutsuki

    not included
  1. {
  2. $params = [];
  3. // Model-specific parameter mapping
  4. // GPT-4o-mini, GPT-4.1 series, GPT-5 series use max_completion_tokens
  5. if (strpos($model, 'gpt-4.1-mini') === 0 ||
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($model, 'gpt-4.1') === 0 ||
  7. strpos($model, 'gpt-5') === 0) {
  8. $params['max_completion_tokens'] = $maxtoken;
  9. } else {
  10. // Default for GPT-4o, Anthropic, Mistral, LM Studio, and other models
  • gyakutsuki

    not included
  1. $params = [];
  2. // Model-specific parameter mapping
  3. // GPT-4o-mini, GPT-4.1 series, GPT-5 series use max_completion_tokens
  4. if (strpos($model, 'gpt-4.1-mini') === 0 ||
  5. strpos($model, 'gpt-4.1') === 0 ||
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($model, 'gpt-5') === 0) {
  7. $params['max_completion_tokens'] = $maxtoken;
  8. } else {
  9. // Default for GPT-4o, Anthropic, Mistral, LM Studio, and other models
  10. $params['max_tokens'] = $maxtoken;
  • gyakutsuki

    not included
  1. $models = self::getGptModel();
  2. foreach ($models as $modelInfo) {
  3. if ($modelInfo['id'] === $model) {
  4. // Check if this is a GPT-5 series model (uses reasoning API)
  5. if (strpos($modelInfo['id'], 'gpt-5') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. return false;
  9. }
  • gyakutsuki

    not included
  1. public static function hasEntityKeyword(string $query): bool
  2. {
  3. $query = strtolower($query);
  4. foreach (SuperlativePatterns::$entityKeywords as $entity) {
  5. if (strpos($query, $entity) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. {
  2. $query = strtolower($query);
  3. $detected = [];
  4. foreach (SuperlativePatterns::$entityKeywords as $entity) {
  5. if (strpos($query, $entity) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $detected[] = $entity;
  7. }
  8. }
  9. return $detected;
  • gyakutsuki

    not included
  1. // Register shutdown function to handle timeout gracefully
  2. register_shutdown_function(function() use ($seconds) {
  3. $error = error_get_last();
  4. if ($error && ($error['type'] === E_ERROR || $error['type'] === E_USER_ERROR)) {
  5. if (strpos($error['message'], 'Maximum execution time') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. error_log('[INFO : TIME] TIMEOUT ERROR: Query exceeded ' . $seconds . ' seconds');
  7. if (ob_get_length()) ob_clean();
  8. header('Content-Type: application/json; charset=UTF-8');
  • gyakutsuki

    not included
  1. $part = trim($part);
  2. $partIntent = null;
  3. // Check analytics
  4. foreach ($analyticsKeywords as $keyword) {
  5. if (strpos($part, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $partIntent = 'analytics';
  7. break;
  8. }
  9. }
  • gyakutsuki

    not included
  1. }
  2. // Check web_search
  3. if ($partIntent === null) {
  4. foreach ($webSearchKeywords as $keyword) {
  5. if (strpos($part, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $partIntent = 'web_search';
  7. break;
  8. }
  9. }
  10. }
  • gyakutsuki

    not included
  1. $hasConjunction = false;
  2. $conjunctionUsed = '';
  3. foreach ($conjunctions as $conj) {
  4. if (strpos($query, $conj) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $hasConjunction = true;
  6. $conjunctionUsed = trim($conj);
  7. break;
  8. }
  9. }
  • gyakutsuki

    not included
  1. }
  2. // Check semantic
  3. if ($partIntent === null) {
  4. foreach ($semanticKeywords as $keyword) {
  5. if (strpos($part, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $partIntent = 'semantic';
  7. break;
  8. }
  9. }
  10. }
  • gyakutsuki

    not included
  1. error_log("text_order_calculation length: " . strlen($orderCalculation) . " chars");
  2. error_log("text_query_examples length: " . strlen($queryExamples) . " chars");
  3. error_log("sqlFormatInstructions length: " . strlen($sqlFormatInstructions) . " chars");
  4. error_log("text_response_format length: " . strlen($responseFormat) . " chars");
  5. error_log("text_multi_token_rules length: " . strlen($multiTokenRules) . " chars");
  6. error_log("Contains 'MULTI-TOKEN' in multiTokenRules: " . (strpos($multiTokenRules, 'MULTI-TOKEN') !== false ? 'YES' : 'NO'));
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. error_log("Contains 'ABSOLUTE RULE' in aggregationRules: " . (strpos($aggregationRules, 'ABSOLUTE RULE') !== false ? 'YES' : 'NO'));
  8. error_log("First 200 chars of multiTokenRules: " . substr($multiTokenRules, 0, 200));
  9. error_log("================================================================================");
  10. }
  • gyakutsuki

    not included
  1. error_log("text_query_examples length: " . strlen($queryExamples) . " chars");
  2. error_log("sqlFormatInstructions length: " . strlen($sqlFormatInstructions) . " chars");
  3. error_log("text_response_format length: " . strlen($responseFormat) . " chars");
  4. error_log("text_multi_token_rules length: " . strlen($multiTokenRules) . " chars");
  5. error_log("Contains 'MULTI-TOKEN' in multiTokenRules: " . (strpos($multiTokenRules, 'MULTI-TOKEN') !== false ? 'YES' : 'NO'));
  6. error_log("Contains 'ABSOLUTE RULE' in aggregationRules: " . (strpos($aggregationRules, 'ABSOLUTE RULE') !== false ? 'YES' : 'NO'));
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. error_log("First 200 chars of multiTokenRules: " . substr($multiTokenRules, 0, 200));
  8. error_log("================================================================================");
  9. }
  10. // Construct complete message in the correct order
  • gyakutsuki

    not included
  1. error_log("DEBUG PromptBuilder::buildSystemMessage() - FINAL");
  2. error_log("================================================================================");
  3. error_log("Language ID: " . $this->languageId);
  4. error_log("Final message length: " . strlen($finalMessage));
  5. error_log("Contains 'CRITICAL RULES': " . (strpos($finalMessage, 'CRITICAL RULES') !== false ? 'YES' : 'NO'));
  6. error_log("Contains 'products_quantity': " . (strpos($finalMessage, 'products_quantity') !== false ? 'YES' : 'NO'));
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. error_log("First 500 chars: " . substr($finalMessage, 0, 500));
  8. error_log("================================================================================");
  9. }
  10. return $finalMessage;
  • gyakutsuki

    not included
  1. while ($tableRow = $tablesResult->fetch()) {
  2. $tableName = array_values($tableRow)[0];
  3. // Skip non-clic tables
  4. if (strpos($tableName, 'clic_') !== 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. continue;
  6. }
  7. $schema .= "Table: {$tableName}\n";
  • gyakutsuki

    not included
  1. error_log("================================================================================");
  2. error_log("DEBUG PromptBuilder::buildSystemMessage() - FINAL");
  3. error_log("================================================================================");
  4. error_log("Language ID: " . $this->languageId);
  5. error_log("Final message length: " . strlen($finalMessage));
  6. error_log("Contains 'CRITICAL RULES': " . (strpos($finalMessage, 'CRITICAL RULES') !== false ? 'YES' : 'NO'));
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. error_log("Contains 'products_quantity': " . (strpos($finalMessage, 'products_quantity') !== false ? 'YES' : 'NO'));
  8. error_log("First 500 chars: " . substr($finalMessage, 0, 500));
  9. error_log("================================================================================");
  10. }
  • gyakutsuki

    not included
  1. if ($hasPriceKeyword) {
  2. foreach (WebSearchPatterns::$comparisonKeywords as $keyword) {
  3. if (strpos($query, $keyword) !== false) {
  4. // Additional check: ensure it's not just internal comparison
  5. // If query contains "database" or "internal", it's likely hybrid, not pure web_search
  6. if (strpos($query, 'database') === false && strpos($query, 'internal') === false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $analysis['intent_type'] = 'web_search';
  8. $analysis['confidence'] = 0.90;
  9. $analysis['override_reason'] = "Price comparison detected: $keyword";
  10. $analysis['detection_method'] = 'pattern_post_filter';
  11. return $analysis;
  • gyakutsuki

    not included
  1. }
  2. // Only apply trends/news override if NO entity keywords AND NO financial keywords present
  3. if (!$hasEntityKeyword && !$hasFinancialKeyword) {
  4. foreach (WebSearchPatterns::$trendsNewsKeywords as $keyword) {
  5. if (strpos($query, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $analysis['intent_type'] = 'web_search';
  7. $analysis['confidence'] = 0.95;
  8. $analysis['override_reason'] = "Trends/news keyword detected: $keyword (no entity/financial keywords)";
  9. $analysis['detection_method'] = 'pattern_post_filter';
  10. return $analysis;
  • gyakutsuki

    not included
  1. // ========================================================================
  2. // STEP 2: Check for competitor keywords (ENGLISH ONLY)
  3. // ========================================================================
  4. foreach (WebSearchPatterns::$competitorKeywords as $keyword) {
  5. if (strpos($query, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $analysis['intent_type'] = 'web_search';
  7. $analysis['confidence'] = 0.95;
  8. $analysis['override_reason'] = "Competitor keyword detected: $keyword";
  9. $analysis['detection_method'] = 'pattern_post_filter';
  10. return $analysis;
  • gyakutsuki

    not included
  1. // Check if query has entity keywords (database query, not web search)
  2. // 🔧 MIGRATION: Use centralized EntityKeywordsPattern instead of WebSearchPatterns
  3. $hasEntityKeyword = false;
  4. foreach (WebSearchPatterns::getEntityKeywords() as $entity) {
  5. if (strpos($query, $entity) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $hasEntityKeyword = true;
  7. break;
  8. }
  9. }
  • gyakutsuki

    not included
  1. }
  2. // Check if query has financial metric keywords (analytics query, not web search)
  3. $hasFinancialKeyword = false;
  4. foreach ($financialMetricKeywords as $keyword) {
  5. if (strpos($query, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $hasFinancialKeyword = true;
  7. break;
  8. }
  9. }
  • gyakutsuki

    not included
  1. }
  2. }
  3. if ($hasPriceKeyword) {
  4. foreach (WebSearchPatterns::$comparisonKeywords as $keyword) {
  5. if (strpos($query, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. // Additional check: ensure it's not just internal comparison
  7. // If query contains "database" or "internal", it's likely hybrid, not pure web_search
  8. if (strpos($query, 'database') === false && strpos($query, 'internal') === false) {
  9. $analysis['intent_type'] = 'web_search';
  10. $analysis['confidence'] = 0.90;
  • gyakutsuki

    not included
  1. $externalSites[] = strtolower($row['site_domain']);
  2. }
  3. // Check if query mentions any configured external site
  4. foreach ($externalSites as $site) {
  5. if (strpos($query, $site) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $analysis['intent_type'] = 'web_search';
  7. $analysis['confidence'] = 0.95;
  8. $analysis['override_reason'] = "External site detected: $site (from database)";
  9. $analysis['detection_method'] = 'pattern_post_filter';
  10. return $analysis;
  • gyakutsuki

    not included
  1. // Only check comparison if query is price-related
  2. $hasPriceKeyword = false;
  3. foreach (WebSearchPatterns::$priceKeywords as $priceWord) {
  4. if (strpos($query, $priceWord) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $hasPriceKeyword = true;
  6. break;
  7. }
  8. }
  • gyakutsuki

    not included
  1. // Suggestions based on the type of error
  2. if (strpos($errorMessage, 'Unknown column') !== false) {
  3. return CLICSHOPPING::getDef('text_column_reference_does_not_exist');
  4. }
  5. if (strpos($errorMessage, 'syntax error') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return CLICSHOPPING::getDef('text_sql_query_generated_error');
  7. }
  8. if (strpos($errorMessage, 'Table') !== false && strpos($errorMessage, 'doesn\'t exist') !== false) {
  9. return CLICSHOPPING::getDef('text_table_referenced_does_not_exist');
  • gyakutsuki

    not included
  1. // Load language definitions
  2. $CLICSHOPPING_Language = Registry::get('Language');
  3. DomainConfig::loadLanguageFile('rag_error_handler');
  4. // Suggestions based on the type of error
  5. if (strpos($errorMessage, 'Unknown column') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return CLICSHOPPING::getDef('text_column_reference_does_not_exist');
  7. }
  8. if (strpos($errorMessage, 'syntax error') !== false) {
  9. return CLICSHOPPING::getDef('text_sql_query_generated_error');
  • gyakutsuki

    not included
  1. if (strpos($errorMessage, 'syntax error') !== false) {
  2. return CLICSHOPPING::getDef('text_sql_query_generated_error');
  3. }
  4. if (strpos($errorMessage, 'Table') !== false && strpos($errorMessage, 'doesn\'t exist') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. return CLICSHOPPING::getDef('text_table_referenced_does_not_exist');
  6. }
  7. // Generic suggestion
  8. return CLICSHOPPING::getDef('text_error_executing_query');
  • gyakutsuki

    not included
  1. foreach ($entityColumnMap as $columnName => $entityType) {
  2. $tableName = str_replace('_id', '', $columnName);
  3. // Check if table name appears in query
  4. if (strpos($sqlLower, "from {$tableName}") !== false ||
  5. strpos($sqlLower, "from clic_{$tableName}") !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($sqlLower, "join {$tableName}") !== false ||
  7. strpos($sqlLower, "join clic_{$tableName}") !== false) {
  8. return [
  9. 'entity_id' => null, // Can't extract ID from query alone
  • gyakutsuki

    not included
  1. // Check for table names in FROM clause
  2. foreach ($entityColumnMap as $columnName => $entityType) {
  3. $tableName = str_replace('_id', '', $columnName);
  4. // Check if table name appears in query
  5. if (strpos($sqlLower, "from {$tableName}") !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($sqlLower, "from clic_{$tableName}") !== false ||
  7. strpos($sqlLower, "join {$tableName}") !== false ||
  8. strpos($sqlLower, "join clic_{$tableName}") !== false) {
  9. return [
  • gyakutsuki

    not included
  1. // Check if table name appears in query
  2. if (strpos($sqlLower, "from {$tableName}") !== false ||
  3. strpos($sqlLower, "from clic_{$tableName}") !== false ||
  4. strpos($sqlLower, "join {$tableName}") !== false ||
  5. strpos($sqlLower, "join clic_{$tableName}") !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return [
  7. 'entity_id' => null, // Can't extract ID from query alone
  8. 'entity_type' => $entityType,
  9. ];
  • gyakutsuki

    not included
  1. $tableName = str_replace('_id', '', $columnName);
  2. // Check if table name appears in query
  3. if (strpos($sqlLower, "from {$tableName}") !== false ||
  4. strpos($sqlLower, "from clic_{$tableName}") !== false ||
  5. strpos($sqlLower, "join {$tableName}") !== false ||
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. strpos($sqlLower, "join clic_{$tableName}") !== false) {
  7. return [
  8. 'entity_id' => null, // Can't extract ID from query alone
  9. 'entity_type' => $entityType,
  • gyakutsuki

    not included
  1. $client = ProviderManager::getOpenAiGpt($parameters);
  2. } elseif (strpos($model, 'anth') === 0) {
  3. $client = ProviderManager::getAnthropicChat($model, $maxtoken);
  4. } elseif (strpos($model, 'mistral') === 0) {
  5. $client = ProviderManager::getMistralChat($model, $maxtoken);
  6. } elseif (strpos($model, 'ollama') === 0 || str_contains($model, ':latest')) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $client = ProviderManager::getOllamaChat($model);
  8. } elseif (strpos($model, 'openai/') === 0) {
  9. $client = ProviderManager::getLmStudioChat($model);
  10. } else {
  11. $client = ProviderManager::getLmStudioChat($model);
  • gyakutsuki

    not included
  1. $client = ProviderManager::getAnthropicChat($model, $maxtoken);
  2. } elseif (strpos($model, 'mistral') === 0) {
  3. $client = ProviderManager::getMistralChat($model, $maxtoken);
  4. } elseif (strpos($model, 'ollama') === 0 || str_contains($model, ':latest')) {
  5. $client = ProviderManager::getOllamaChat($model);
  6. } elseif (strpos($model, 'openai/') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. $client = ProviderManager::getLmStudioChat($model);
  8. } else {
  9. $client = ProviderManager::getLmStudioChat($model);
  10. }
  • gyakutsuki

    not included
  1. define('CLICSHOPPING_APP_CHATGPT_CH_MODEL', 'gpt-5-mini');
  2. }
  3. $model = $engine ?? CLICSHOPPING_APP_CHATGPT_CH_MODEL;
  4. if (strpos($model, 'gpt') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $maxtoken = self::getMaxTokens($maxtoken);
  6. $temperature = $temperature ?? (float)CLICSHOPPING_APP_CHATGPT_CH_TEMPERATURE;
  7. $tokenParams = ModelManager::getModelApiParameters($model, $maxtoken);
  • gyakutsuki

    not included
  1. if ($engine !== null) {
  2. $parameters['model'] = $engine;
  3. }
  4. $client = ProviderManager::getOpenAiGpt($parameters);
  5. } elseif (strpos($model, 'anth') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $client = ProviderManager::getAnthropicChat($model, $maxtoken);
  7. } elseif (strpos($model, 'mistral') === 0) {
  8. $client = ProviderManager::getMistralChat($model, $maxtoken);
  9. } elseif (strpos($model, 'ollama') === 0 || str_contains($model, ':latest')) {
  10. $client = ProviderManager::getOllamaChat($model);
  • gyakutsuki

    not included
  1. }
  2. $client = ProviderManager::getOpenAiGpt($parameters);
  3. } elseif (strpos($model, 'anth') === 0) {
  4. $client = ProviderManager::getAnthropicChat($model, $maxtoken);
  5. } elseif (strpos($model, 'mistral') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $client = ProviderManager::getMistralChat($model, $maxtoken);
  7. } elseif (strpos($model, 'ollama') === 0 || str_contains($model, ':latest')) {
  8. $client = ProviderManager::getOllamaChat($model);
  9. } elseif (strpos($model, 'openai/') === 0) {
  10. $client = ProviderManager::getLmStudioChat($model);
  • gyakutsuki

    not included
  1. {
  2. $keywords = self::getModificationKeywords();
  3. $queryLower = mb_strtolower($query);
  4. foreach ($keywords as $keyword) {
  5. if (strpos($queryLower, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return $keyword;
  7. }
  8. }
  9. return null;
  • gyakutsuki

    not included
  1. {
  2. $keywords = self::getModificationKeywords();
  3. $queryLower = mb_strtolower($query);
  4. foreach ($keywords as $keyword) {
  5. if (strpos($queryLower, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. // Process special vector fields
  2. $vector_fields = [];
  3. foreach ($data as $field => $value) {
  4. // Check if the field is meant to be a vector and starts with 'vec_'
  5. if (substr($field, 0, 4) === 'vec_') {
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $actual_field = substr($field, 4); // Get the actual field name without 'vec_' prefix
  7. $vector_fields[$actual_field] = $value; // Store the vector value
  8. unset($data[$field]); // Remove the special prefixed field
  9. }
  10. }
  • gyakutsuki

    not included
  1. if (!preg_match('/^[a-zA-Z0-9_]*$/', $prefix)) {
  2. throw new \InvalidArgumentException('Invalid table prefix');
  3. }
  4. // Ajout d'un underscore terminal si le préfixe est non vide et ne se termine pas déjà par un underscore
  5. if ($prefix !== '' && substr($prefix, -1) !== '_') {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $prefix .= '_';
  7. }
  8. // Substitution sûre des tokens
  9. return preg_replace_callback('/:table_([a-zA-Z0-9_]+)/', function ($matches) use ($prefix) {
  • gyakutsuki

    not included
  1. if (is_null($temperature)) {
  2. $temperature = 0.5;
  3. }
  4. if (strpos(CLICSHOPPING_APP_CHATGPT_CH_MODEL, 'gpt') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  5. $engine = CLICSHOPPING_APP_CHATGPT_CH_MODEL;
  6. $response = Gpt::getGptResponse($question, $maxtoken, $temperature, $engine);
  7. } else {
  8. //ollama
  9. $response = Gpt::getGptResponse($question, $maxtoken, $temperature);
  • gyakutsuki

    not included
  1. */
  2. private static function containsMaliciousPatterns(string $text): bool
  3. {
  4. $lowerText = strtolower($text);
  5. foreach (ObfuscationPatterns::$maliciousKeywords as $keyword) {
  6. if (strpos($lowerText, $keyword) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return true;
  8. }
  9. }
  10. return false;
  • gyakutsuki

    not included
  1. // Extract type from column info (now returns array with 'type' and 'comment')
  2. $type = is_array($columnInfo) ? $columnInfo['type'] : $columnInfo;
  3. // Detect ID columns that could be foreign keys
  4. if (preg_match('/_id$/', $column) && strpos($type, 'int') !== false) {
    Consider replacing preg_match() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $relatedTable = str_replace('_id', '', $column);
  6. // Validate related table name
  7. $safeRelatedTable = InputValidator::sanitizeIdentifier($relatedTable);
  • gyakutsuki

    not included
  1. // Extract type from column info (now returns array with 'type' and 'comment')
  2. $type = is_array($columnInfo) ? $columnInfo['type'] : $columnInfo;
  3. // Detect ID columns that could be foreign keys
  4. if (preg_match('/_id$/', $column) && strpos($type, 'int') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. $relatedTable = str_replace('_id', '', $column);
  6. // Validate related table name
  7. $safeRelatedTable = InputValidator::sanitizeIdentifier($relatedTable);
  • gyakutsuki

    not included
  1. $metrics['total_interactions'] = $memStats['total_interactions'] ?? 0;
  2. $metrics['memory_size'] = $memStats['total_size'] ?? 0;
  3. }
  4. break;
  5. case strpos($name, 'Correction') !== false:
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $metrics['type'] = 'correction';
  7. if (method_exists($component, 'getLearningStats')) {
  8. $learnStats = $component->getLearningStats();
  9. $metrics['correction_accuracy'] = $learnStats['correction_accuracy'] ?? 0;
  10. $metrics['learned_patterns'] = $learnStats['learned_patterns'] ?? 0;
  • gyakutsuki

    not included
  1. $metrics['correction_accuracy'] = $learnStats['correction_accuracy'] ?? 0;
  2. $metrics['learned_patterns'] = $learnStats['learned_patterns'] ?? 0;
  3. }
  4. break;
  5. case strpos($name, 'WebSearch') !== false:
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $metrics['type'] = 'web_search';
  7. $metrics['cache_hit_rate'] = $this->extractCacheHitRate($componentStats);
  8. break;
  9. }
  • gyakutsuki

    not included
  1. $metrics['type'] = 'planner';
  2. $metrics['total_plans'] = $componentStats['total_plans_created'] ?? 0;
  3. $metrics['avg_steps'] = $componentStats['avg_steps_per_plan'] ?? 0;
  4. break;
  5. case strpos($name, 'Memory') !== false:
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $metrics['type'] = 'memory';
  7. if (method_exists($component, 'getStats')) {
  8. $memStats = $component->getStats();
  9. $metrics['total_interactions'] = $memStats['total_interactions'] ?? 0;
  10. $metrics['memory_size'] = $memStats['total_size'] ?? 0;
  • gyakutsuki

    not included
  1. $metrics = array_merge($metrics, $componentStats);
  2. }
  3. // Méthodes spécifiques par type de composant
  4. switch (true) {
  5. case strpos($name, 'Planner') !== false:
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $metrics['type'] = 'planner';
  7. $metrics['total_plans'] = $componentStats['total_plans_created'] ?? 0;
  8. $metrics['avg_steps'] = $componentStats['avg_steps_per_plan'] ?? 0;
  9. break;
  • gyakutsuki

    not included
  1. $schema .= 'NULL, ';
  2. } elseif (!\is_null($Qrows->value($i))) {
  3. $row = $Qrows->value($i);
  4. // Check if this is a VECTOR column
  5. if (isset($columnTypes[$i]) && strpos(strtolower($columnTypes[$i]), 'vector') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. // VECTOR data is already in the correct format from MariaDB
  7. // Just escape it properly
  8. $row = addslashes($row);
  9. } else {
  10. $row = addslashes($row);
  • gyakutsuki

    not included
  1. $is_vector_type = preg_match('/^vector/i', $columnType);
  2. // Check if default value is already quoted (starts and ends with single quote)
  3. $is_already_quoted = (strlen($default_value) >= 2 &&
  4. substr($default_value, 0, 1) === "'" &&
  5. substr($default_value, -1) === "'");
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. // Skip empty string defaults for numeric types (invalid SQL)
  7. if ($is_numeric_type && $default_value === '') {
  8. // Don't add default clause - let MySQL use its default behavior
  9. } elseif ($is_datetime_type && $default_value === '') {
  • gyakutsuki

    not included
  1. // Check if column type is VECTOR (cannot have empty string default)
  2. $is_vector_type = preg_match('/^vector/i', $columnType);
  3. // Check if default value is already quoted (starts and ends with single quote)
  4. $is_already_quoted = (strlen($default_value) >= 2 &&
  5. substr($default_value, 0, 1) === "'" &&
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. substr($default_value, -1) === "'");
  7. // Skip empty string defaults for numeric types (invalid SQL)
  8. if ($is_numeric_type && $default_value === '') {
  9. // Don't add default clause - let MySQL use its default behavior
  • gyakutsuki

    not included
  1. {
  2. $markers = self::getResetMarkers();
  3. $queryLower = mb_strtolower($query);
  4. foreach ($markers as $marker) {
  5. if (strpos($queryLower, $marker) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. return false;
  • gyakutsuki

    not included
  1. $markers = self::getResetMarkers();
  2. $queryLower = mb_strtolower($query);
  3. $foundMarkers = [];
  4. foreach ($markers as $marker) {
  5. if (strpos($queryLower, $marker) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $foundMarkers[] = $marker;
  7. }
  8. }
  9. $hasReset = !empty($foundMarkers);
  • gyakutsuki

    not included
  1. }
  2. }
  3. foreach ($tablesList as $tableName) {
  4. // Skip technical tables
  5. if (strpos($tableName, '_embedding') !== false || strpos($tableName, $prefix . 'rag_') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. continue;
  7. }
  8. $this->totalTables++;
  • gyakutsuki

    not included
  1. }
  2. }
  3. foreach ($tablesList as $tableName) {
  4. // Skip technical tables
  5. if (strpos($tableName, '_embedding') !== false || strpos($tableName, $prefix . 'rag_') === 0) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. continue;
  7. }
  8. $this->totalTables++;
  • gyakutsuki

    not included
  1. $headers = ['status_code' => $statusCode];
  2. while (($line = fgets($socket)) !== false) {
  3. $line = trim($line);
  4. if ($line === '') break;
  5. if (strpos($line, ':') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. [$name, $value] = explode(':', $line, 2);
  7. $headers[strtolower(trim($name))] = trim($value);
  8. }
  9. }
  • gyakutsuki

    not included
  1. 'Connection' => 'close'
  2. ];
  3. if (!empty($parameters['header'])) {
  4. foreach ($parameters['header'] as $header) {
  5. if (strpos($header, ':') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. [$name, $value] = explode(':', $header, 2);
  7. $headers[trim($name)] = trim($value);
  8. }
  9. }
  10. }
  • gyakutsuki

    not included
  1. while ($Qembeddings->fetch()) {
  2. $tableName = $Qembeddings->value('table_name');
  3. // Skip technical tables (should not be in embeddings, but filter just in case)
  4. if (strpos($tableName, '_embedding') !== false || strpos($tableName, 'clic_rag_') === 0) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. continue;
  6. }
  7. $embeddingText = $Qembeddings->value('embedding_text');
  • gyakutsuki

    not included
  1. while ($Qembeddings->fetch()) {
  2. $tableName = $Qembeddings->value('table_name');
  3. // Skip technical tables (should not be in embeddings, but filter just in case)
  4. if (strpos($tableName, '_embedding') !== false || strpos($tableName, 'clic_rag_') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. continue;
  6. }
  7. $embeddingText = $Qembeddings->value('embedding_text');
  • gyakutsuki

    not included
  1. if (self::$prefixDb === null) {
  2. self::$prefixDb = CLICSHOPPING::getConfig('db_table_prefix');
  3. }
  4. // Add prefix if not already present
  5. if (strpos($tableName, self::$prefixDb) !== 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $tableName = self::$prefixDb . $tableName;
  7. }
  8. $connection = self::getEntityManager()->getConnection();
  9. $affectedRows = $connection->insert($tableName, $data);
  • gyakutsuki

    not included
  1. if (self::$prefixDb === null) {
  2. self::$prefixDb = CLICSHOPPING::getConfig('db_table_prefix');
  3. }
  4. // Add prefix if not already present
  5. if (strpos($tableName, self::$prefixDb) !== 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $tableName = self::$prefixDb . $tableName;
  7. }
  8. $connection = self::getEntityManager()->getConnection();
  9. return $connection->delete($tableName, $criteria);
  • gyakutsuki

    not included
  1. return true;
  2. }
  3. // Fuzzy match
  4. foreach ($allFields as $field) {
  5. if (strpos($field, $word) !== false || strpos($word, $field) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. return true;
  7. }
  8. }
  9. // Check against non-database words
  • gyakutsuki

    not included
  1. if (self::$prefixDb === null) {
  2. self::$prefixDb = CLICSHOPPING::getConfig('db_table_prefix');
  3. }
  4. // Add prefix if not already present
  5. if (strpos($tableName, self::$prefixDb) !== 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $tableName = self::$prefixDb . $tableName;
  7. }
  8. $connection = self::getEntityManager()->getConnection();
  9. return $connection->update($tableName, $data, $criteria);
  • gyakutsuki

    not included
  1. if ($serverVersion) {
  2. $serverVersionLower = strtolower($serverVersion);
  3. // Extract and properly format the version
  4. if (strpos($serverVersionLower, 'mariadb') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  5. // Typical format: "10.11.8-MariaDB" or "11.7.0-mariadb"
  6. preg_match('/(\d+\.\d+\.\d+)/', $serverVersion, $matches);
  7. if (!empty($matches[1])) {
  8. $versionNumber = $matches[1];
  • gyakutsuki

    not included
  1. // 🔧 FIX: If interpretations array is empty, use defaults based on ambiguity type
  2. if (empty($availableInterpretations)) {
  3. $ambiguityType = $ambiguityAnalysis['ambiguity_type'] ?? '';
  4. // For quantification queries, default to count and sum
  5. if (strpos($ambiguityType, 'quantification') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $availableInterpretations = ['count', 'sum'];
  7. if ($this->debug) {
  8. $this->logger->logSecurityEvent(
  9. "AmbiguityOptimizer: Empty interpretations array, using defaults for quantification: count, sum",
  • gyakutsuki

    not included
  1. // Clear from Memcached (note: Memcached doesn't support key pattern matching easily)
  2. // We'll rely on TTL expiration for Memcached
  3. // Clear from file cache
  4. foreach ($this->promptCache as $key => $data) {
  5. if (strpos($key, $prefix) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. unset($this->promptCache[$key]);
  7. $cleared++;
  8. }
  9. }
  • gyakutsuki

    not included
  1. // iterate through all keys. We'll rely on TTL expiration for Memcached.
  2. // For production use, consider using Redis for better invalidation support.
  3. // Invalidate from file cache
  4. foreach ($this->promptCache as $key => $data) {
  5. if (strpos($key, self::CACHE_TYPE_SQL) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. if (isset($data['tables_used']) && in_array($cleanTableName, $data['tables_used'], true)) {
  7. unset($this->promptCache[$key]);
  8. $invalidated++;
  9. }
  10. }
  • gyakutsuki

    not included
  1. }
  2. }
  3. // Invalidate from file cache
  4. foreach ($this->promptCache as $key => $data) {
  5. if (strpos($key, self::CACHE_TYPE_SQL) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. if (isset($data['tables_used'])) {
  7. $intersection = array_intersect($cleanTableNames, $data['tables_used']);
  8. if (!empty($intersection)) {
  9. unset($this->promptCache[$key]);
  10. $invalidated++;
  • gyakutsuki

    not included
  1. $cleaned = $matches[1];
  2. }
  3. // STEP 4: Remove leading/trailing quotes if they wrap the entire string
  4. if ((substr($cleaned, 0, 1) === '"' && substr($cleaned, -1) === '"') ||
  5. (substr($cleaned, 0, 1) === "'" && substr($cleaned, -1) === "'")) {
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $cleaned = substr($cleaned, 1, -1);
  7. }
  8. return trim($cleaned);
  9. }
  • gyakutsuki

    not included
  1. if (preg_match('/is:\s*["\'](.+?)["\']$/i', $cleaned, $matches)) {
  2. $cleaned = $matches[1];
  3. }
  4. // STEP 4: Remove leading/trailing quotes if they wrap the entire string
  5. if ((substr($cleaned, 0, 1) === '"' && substr($cleaned, -1) === '"') ||
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. (substr($cleaned, 0, 1) === "'" && substr($cleaned, -1) === "'")) {
  7. $cleaned = substr($cleaned, 1, -1);
  8. }
  9. return trim($cleaned);
  • gyakutsuki

    not included
  1. $cleaned = $matches[1];
  2. }
  3. // STEP 4: Remove leading/trailing quotes if they wrap the entire string
  4. if ((substr($cleaned, 0, 1) === '"' && substr($cleaned, -1) === '"') ||
  5. (substr($cleaned, 0, 1) === "'" && substr($cleaned, -1) === "'")) {
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $cleaned = substr($cleaned, 1, -1);
  7. }
  8. return trim($cleaned);
  9. }
  • gyakutsuki

    not included
  1. if (preg_match('/is:\s*["\'](.+?)["\']$/i', $cleaned, $matches)) {
  2. $cleaned = $matches[1];
  3. }
  4. // STEP 4: Remove leading/trailing quotes if they wrap the entire string
  5. if ((substr($cleaned, 0, 1) === '"' && substr($cleaned, -1) === '"') ||
    Consider replacing substr() with str_ends_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. (substr($cleaned, 0, 1) === "'" && substr($cleaned, -1) === "'")) {
  7. $cleaned = substr($cleaned, 1, -1);
  8. }
  9. return trim($cleaned);
  • gyakutsuki

    not included
  1. if ($value === null) {
  2. return null;
  3. }
  4. // Si la valeur est déjà une chaîne formatée correctement, la retourner telle quelle
  5. if (is_string($value) && strpos($value, '[') === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. return $value;
  7. }
  8. // Convertir le tableau en chaîne formatée pour MariaDB
  9. if (is_array($value)) {
  • gyakutsuki

    not included
  1. * @return bool True if it contains a comparison operator, false otherwise.
  2. */
  3. private function isComparisonClause(string $clause): bool
  4. {
  5. foreach (self::ALLOWED_OPERATORS as $operator) {
  6. if (strpos($clause, $operator) !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return true;
  8. }
  9. }
  10. return false;
  11. }
  • gyakutsuki

    not included
  1. {
  2. // Remove backticks and quotes
  3. $tableName = str_replace(['`', '"', "'"], '', $tableName);
  4. // Remove database prefix (e.g., database.table -> table)
  5. if (strpos($tableName, '.') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. $parts = explode('.', $tableName);
  7. $tableName = end($parts);
  8. }
  9. // Remove alias (take only the first word)
  • gyakutsuki

    not included
  1. $isHtmlContent = false;
  2. if (isset($results['text_response']) && !empty($results['text_response'])) {
  3. $interpretationText = $results['text_response'];
  4. // Check if text_response contains HTML
  5. $isHtmlContent = (strpos($interpretationText, '<div') !== false || strpos($interpretationText, '<p>') !== false);
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. } elseif (isset($results['interpretation']) && $results['interpretation'] !== 'Array') {
  7. $interpretationText = $results['interpretation'];
  8. }
  9. if (!empty($interpretationText)) {
  • gyakutsuki

    not included
  1. if ($path === '' || $path === '.' . $separator) {
  2. return $systemroot;
  3. }
  4. if (substr($path, 0, 3) === '..' . $separator) {
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  5. $path = $systemroot . $path;
  6. }
  7. // Normalize path
  8. $path = rtrim($path, $separator) . $separator;
  • gyakutsuki

    not included
  1. if ($path[0] === $separator || strpos($path, $systemroot) === 0) {
  2. return $path;
  3. }
  4. // Relative path from 'Here'
  5. if (substr($path, 0, 2) === '.' . $separator || $path[0] !== '.') {
    Consider replacing substr() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $arrn = preg_split('/\\' . $separator . '/', $path, -1, PREG_SPLIT_NO_EMPTY);
  7. if ($arrn[0] !== '.') {
  8. array_unshift($arrn, '.');
  9. }
  10. $arrn[0] = rtrim($base, $separator);
  • gyakutsuki

    not included
  1. // Normalize path
  2. $path = rtrim($path, $separator) . $separator;
  3. // Absolute path
  4. if ($path[0] === $separator || strpos($path, $systemroot) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  5. return $path;
  6. }
  7. // Relative path from 'Here'
  8. if (substr($path, 0, 2) === '.' . $separator || $path[0] !== '.') {
  • gyakutsuki

    not included
  1. // Check if the path is within allowed directories
  2. $isAllowed = false;
  3. foreach ($allowedDirs as $allowedDir) {
  4. $normalizedAllowedDir = str_replace('\\', '/', realpath($allowedDir));
  5. if ($normalizedAllowedDir && strpos($realPath, $normalizedAllowedDir) === 0) {
    Consider replacing strpos() with str_starts_with() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $isAllowed = true;
  7. break;
  8. }
  9. }
  • gyakutsuki

    not included
  1. foreach ($files as $sm) {
  2. $result['file'][] = ['files_name' => $sm];
  3. }
  4. foreach ($result['file'] as &$module) {
  5. if (strpos($module['files_name'], '.') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  6. $class = substr($module['files_name'], 0, strrpos($module['files_name'], '.'));
  7. $this->startService($class);
  8. }
  9. }
  10. }
  • gyakutsuki

    not included
  1. * @param string $ip The IP address to check
  2. * @param string $range The CIDR range (e.g., '
  3. */
  4. public static function ipInRange(string $ip, string $range): bool
  5. {
  6. if (strpos($range, '/') === false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by ClicShopping
  7. return $ip === $range;
  8. }
  9. list($subnet, $bits) = explode('/', $range);
  10. $ip = ip2long($ip);
  • gyakutsuki

    not included
  1. if ($this->debug) {
  2. error_log("AmbiguousQueryDetector: LLM returned empty interpretations for ambiguous query, generating defaults");
  3. }
  4. // Generate default interpretations based on ambiguity type
  5. if (strpos($ambiguityType, 'quantification') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. // For quantification queries: count vs sum
  7. $interpretations = [
  8. [
  9. 'type' => 'count',
  10. 'label' => 'Count of items',
  • gyakutsuki

    not included
  1. 'label' => 'Sum of quantities',
  2. 'description' => 'Sum the total quantity',
  3. 'sql_hint' => 'Use SUM(quantity_field)'
  4. ]
  5. ];
  6. } else if (strpos($ambiguityType, 'scope') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. // For scope queries: all vs recent
  8. $interpretations = [
  9. [
  10. 'type' => 'all',
  11. 'label' => 'All items',
  • gyakutsuki

    not included
  1. * @return bool True if the text contains valid JSON, false otherwise.
  2. */
  3. private static function validateJsonStructure(string $text): bool
  4. {
  5. // If the text contains JSON, check its validity
  6. if (strpos($text, '{') !== false || strpos($text, '[') !== false) {
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  7. return json_last_error() === JSON_ERROR_NONE;
  8. }
  9. return true; // No JSON detected
  10. }
  • gyakutsuki

    not included
  1. $isHtmlContent = false;
  2. if (isset($results['text_response']) && !empty($results['text_response'])) {
  3. $interpretationText = $results['text_response'];
  4. // Check if text_response contains HTML
  5. $isHtmlContent = (strpos($interpretationText, '<div') !== false || strpos($interpretationText, '<p>') !== false);
    Consider replacing strpos() with str_contains() for improved readability.
    Time to fix: about 1 hour
    Read doc Permalink Copy Prompt
    Last edited by clicshopping
  6. } elseif (isset($results['response']) && !empty($results['response'])) {
  7. $interpretationText = $results['response'];
  8. } elseif (isset($results['interpretation']) && $results['interpretation'] !== 'Array') {
  9. $interpretationText = $results['interpretation'];
  10. }
  • gyakutsuki

    not included