Whoops \ Exception \ ErrorException (E_WARNING)
Undefined array key 0 Whoops\Exception\ErrorException thrown with message "Undefined array key 0" Stacktrace: #13 Whoops\Exception\ErrorException in /data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php:50 #12 Whoops\Run:handleError in /data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php:50 #11 THEME\AffiliateMarketing\Contents\Components\ProductSearchLinks:getData in /data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php:172 #10 THEME\AffiliateMarketing\Contents\AffiliateContents:THEME\AffiliateMarketing\Contents\{closure} in [internal]:0 #9 array_reduce in /data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php:167 #8 THEME\AffiliateMarketing\Contents\AffiliateContents:getData in /data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:87 #7 THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons:getDirectData in /data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:55 #6 THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons:getButtons in /data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:38 #5 THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons:getData in /data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Single.php:86 #4 THEME\ViewModel\Single:setComponents in /data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Single.php:35 #3 THEME\ViewModel\Single:__construct in /data/websites/telefonino/web/app/themes/telefonino/single-prodotti.php:6 #2 include in /data/websites/telefonino/web/wp/wp-includes/template-loader.php:106 #1 require_once in /data/websites/telefonino/web/wp/wp-blog-header.php:19 #0 require in /data/websites/telefonino/web/index.php:6
Stack frames (14)
13
Whoops\Exception\ErrorException
/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php:50
12
Whoops\Run handleError
/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php:50
11
THEME\AffiliateMarketing\Contents\Components\ProductSearchLinks getData
/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php:172
10
THEME\AffiliateMarketing\Contents\AffiliateContents THEME\AffiliateMarketing\Contents\{closure}
[internal]:0
9
array_reduce
/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php:167
8
THEME\AffiliateMarketing\Contents\AffiliateContents getData
/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:87
7
THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons getDirectData
/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:55
6
THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons getButtons
/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php:38
5
THEME\ViewModel\Post\Components\AffiliateMarketing\ProductButtons getData
/web/app/themes/telefonino/src/ViewModel/Single.php:86
4
THEME\ViewModel\Single setComponents
/web/app/themes/telefonino/src/ViewModel/Single.php:35
3
THEME\ViewModel\Single __construct
/web/app/themes/telefonino/single-prodotti.php:6
2
include
/web/wp/wp-includes/template-loader.php:106
1
require_once
/web/wp/wp-blog-header.php:19
0
require
/web/index.php:6
/data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php
        ]
    ];

    
    private $special_categories = [ 'home', 'videogames', 'elettronica' ];
    
    private $post_id;
    private $keyword;
    private $categories;
    protected $category;
    
        

    function getData( $product, $offers, $post_id ) {

        $this->post_id = $post_id;

        $this->categories = $this->getCategories();

        $this->category   = $this->categories[0]; // non mettere array_shift perché elimineresti il contenuto

        $this->keyword = $this->getKeyword();

        return (object) [ 'name' => 'product_search_links', 'data' => $this->getSearchLinks() ];
    }

    /**
     * Ritorna un array con gli slug delle categorie
     *
     * @return array
     */
    private function getCategories() {

        $categories = wp_get_post_terms( $this->post_id, 'category' );
        
        return array_map( function( $category ) { return $category->slug; }, $categories );
    }


    /**
/data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/Components/ProductSearchLinks.php
        ]
    ];

    
    private $special_categories = [ 'home', 'videogames', 'elettronica' ];
    
    private $post_id;
    private $keyword;
    private $categories;
    protected $category;
    
        

    function getData( $product, $offers, $post_id ) {

        $this->post_id = $post_id;

        $this->categories = $this->getCategories();

        $this->category   = $this->categories[0]; // non mettere array_shift perché elimineresti il contenuto

        $this->keyword = $this->getKeyword();

        return (object) [ 'name' => 'product_search_links', 'data' => $this->getSearchLinks() ];
    }

    /**
     * Ritorna un array con gli slug delle categorie
     *
     * @return array
     */
    private function getCategories() {

        $categories = wp_get_post_terms( $this->post_id, 'category' );
        
        return array_map( function( $category ) { return $category->slug; }, $categories );
    }


    /**
/data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php
     *
     * @return void
     */
    protected function getQuery() {
        
        return Utils\StringHelper::slugify( $this->keyword );
    }


    /**
     * Ritorna i dati delle offerte per tutti i content types   
     */ 
    function getData () {

        return array_reduce ( $this->contentTypes,  function( $data, $content ) {

            // get the task class
            $content = __NAMESPACE__ .'\\Components\\'. $content; 
            
            $content_data = ( new $content() )->getData( $this->keyword, $this->offers, $this->product_post_id );            
            if (!empty($content_data)) {
                if (is_array($content_data->data) && array_key_exists(1, $content_data->data)) {
                    $data[$content_data->name] = array_values($content_data->data);
                } else {
                    $data[$content_data->name] = $content_data->data;
                }
            }

            return $data;
        });  
    }
 

}
[internal]
/data/websites/telefonino/web/app/themes/telefonino/src/AffiliateMarketing/Contents/AffiliateContents.php
    }


    /**
     * Serve a comporre la query da inviare all'offerRetriever
     *
     * @return void
     */
    protected function getQuery() {
        
        return Utils\StringHelper::slugify( $this->keyword );
    }


    /**
     * Ritorna i dati delle offerte per tutti i content types   
     */ 
    function getData () {

        return array_reduce ( $this->contentTypes,  function( $data, $content ) {

            // get the task class
            $content = __NAMESPACE__ .'\\Components\\'. $content; 
            
            $content_data = ( new $content() )->getData( $this->keyword, $this->offers, $this->product_post_id );            
            if (!empty($content_data)) {
                if (is_array($content_data->data) && array_key_exists(1, $content_data->data)) {
                    $data[$content_data->name] = array_values($content_data->data);
                } else {
                    $data[$content_data->name] = $content_data->data;
                }
            }

            return $data;
        });  
    }
 

}
/data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php
        $buttons = array_merge( $search_buttons, $deep_buttons );

        return $buttons;
    }


    /**
     * Solo per testare la chiamata diretta alla factory
     *
     * @return void
     */
    private function getDirectData() {

        $product = get_post( $this->post_id );

        $productButtons = \THEME\AffiliateMarketing\ButtonsFactory::get( $product );
        
        //echo get_class( $productButtons); die;

        $data =  $productButtons->getData();

        return $data;
    }



    /**
     * Ritorna una mappa basata sui marketplace
     *
     * @param array $offers
     * @return array
     */
    private function formatDeepButtons( $offers ) {
       
        return array_reduce( $offers, function( $buttons, $offer )  {

            if( in_array( strtolower($offer['marketplace']), $this->marketplaces ) ) {
                /// ad ogni marketplace associa un link e le sue proprietà
                $buttons[ strtolower($offer[ 'marketplace' ]) ] = [

/data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php
    public function getData() {

        $data = $this->getButtons();

        //var_dump( $data ); die;
        
        return (object) [ 'name' => 'product_affiliate_buttons', 'data' => $data ];
    }

    /**
     * Return the links for the buttons
     *     
     * @return array 
     */
    private function getButtons() {

        //$data = $this->getTaskData();
        
        /// SOLO PER TEST -->  
        $data = $this->getDirectData();
        
        /// ottiene una mappa di deep link basata su marketplace
        $deep_buttons = $this->formatDeepButtons( $data['offers'] );

        if (isset($data['offers'][0]) && isset($data['offers'][0]["domination"])){
            /// tornare creatività domination
            return $deep_buttons;
        }
        /// ottiene una mappa di search link basata su marketplace
        $search_buttons = $this->formatSearchButtons( $data );
        
        /// prende i search_link come fallback
        $buttons = array_merge( $search_buttons, $deep_buttons );

        return $buttons;
    }


    /**
     * Solo per testare la chiamata diretta alla factory
/data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Post/Components/AffiliateMarketing/ProductButtons.php
        'amazon',
        'google',

    ];

    /**
     *
     * @param int $post_id - si riferisce ad un post di post_type = 'prodotti'
     */
    public function __construct( $post_id , $versus_post_id = null ) {

        $this->post_id = $post_id;
        
        $this->versus_post_id = (is_int($versus_post_id)) ? $versus_post_id : $post_id;

    } 

    public function getData() {

        $data = $this->getButtons();

        //var_dump( $data ); die;
        
        return (object) [ 'name' => 'product_affiliate_buttons', 'data' => $data ];
    }

    /**
     * Return the links for the buttons
     *     
     * @return array 
     */
    private function getButtons() {

        //$data = $this->getTaskData();
        
        /// SOLO PER TEST -->  
        $data = $this->getDirectData();
        
        /// ottiene una mappa di deep link basata su marketplace
        $deep_buttons = $this->formatDeepButtons( $data['offers'] );
/data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Single.php
            'Taxonomies',
            'Credits',
            'Canonical',
            'StructuredDataFaq',
            'AnalysisTracking',
            'Meta'
        ];
    }
    
    /**
     * Get data from all the components in the 
     * $components list
     */
    private function setComponents() {

        foreach($this->components as $component) {

            $component = __NAMESPACE__ .'\\Post\Components\\'. $component; 

            $component_instance = (new $component( $this->post->ID, $this->data ))->getData();
            
            $this->data[$component_instance->name] = $component_instance->data;
        }
    }




    /**
     * questa parte deve essere applicata al content
     * 
     * filter the embeds and removes width attributes
     * 
     * va aggiunto ? comunque in content
     *//*
    protected function removeWidthAttributes(){
    
        $content = $this->data['post']['content'];
        $patterns = [
            '/width\s*=\s*".*?"/i',
/data/websites/telefonino/web/app/themes/telefonino/src/ViewModel/Single.php
    
    function __construct($post, $postTemplate = 'Single') {     
        
        parent::__construct();

        $this->post = $post;

        // assign the post template (default is 'Single')        
        $this->postTemplate = $this->postTemplateFactory($postTemplate);
        
        // init the post template 
        // (includes content details as well)
        $this->setPost(); 

        // set the components list into property
        // $components 
        $this->initComponents();

        // add all the default components 
        $this->setComponents();

    }

        
    /**
     * Writes the basic page info
     */
    protected function setPageData(){       
        
        $this->data = [
            'type' => 'single_post',
            'infinite' => 'true'
        ];        
    }

    /**
     * Add the post info to data
     */
    protected function setPost() {        
        $this->data['post'] = $this->postTemplate->getPostData($this->post);
/data/websites/telefonino/web/app/themes/telefonino/single-prodotti.php
<?php
use THEME\ViewModel\SingleProduct;
use THEME\Utils\Timber;

// load data
$data = ( new SingleProduct($posts[0], 'SingleProdotti') )->getData();

$template = 'single-product.twig';

Timber::render( $template, $data );
 
/data/websites/telefonino/web/wp/wp-includes/template-loader.php
            }
 
            break;
        }
    }
 
    if ( ! $template ) {
        $template = get_index_template();
    }
 
    /**
     * Filters the path of the current template before including it.
     *
     * @since 3.0.0
     *
     * @param string $template The path of the template to include.
     */
    $template = apply_filters( 'template_include', $template );
    if ( $template ) {
        include $template;
    } elseif ( current_user_can( 'switch_themes' ) ) {
        $theme = wp_get_theme();
        if ( $theme->errors() ) {
            wp_die( $theme->errors() );
        }
    }
    return;
}
 
/data/websites/telefonino/web/wp/wp-blog-header.php
<?php
/**
 * Loads the WordPress environment and template.
 *
 * @package WordPress
 */
 
if ( ! isset( $wp_did_header ) ) {
 
    $wp_did_header = true;
 
    // Load the WordPress library.
    require_once __DIR__ . '/wp-load.php';
 
    // Set up the WordPress query.
    wp();
 
    // Load the theme template.
    require_once ABSPATH . WPINC . '/template-loader.php';
 
}
 
/data/websites/telefonino/web/index.php
<?php
/**
 * WordPress View Bootstrapper
 */
define('WP_USE_THEMES', true);
require __DIR__ . '/wp/wp-blog-header.php';
 

Environment & details:

empty
empty
empty
empty
empty
Key Value
SERVER_SOFTWARE nginx/1.26.2
REQUEST_URI /prodotti/onda-felice-2/
USER nginx
HOME /var/lib/nginx
HTTP_REFERER https://staging.telefonino.net/prodotti/onda-felice-2
HTTP_ACCEPT_ENCODING gzip, br, zstd, deflate
HTTP_USER_AGENT Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
HTTP_ACCEPT */*
HTTP_CONNECTION close
HTTP_X_FORWARDED_FOR 216.73.216.51
HTTP_HOST staging.telefonino.net
HTTP_X_FORWARDED_PORT 443
HTTP_X_FORWARDED_PROTO https
REDIRECT_STATUS 200
SERVER_NAME staging.telefonino.net
SERVER_PORT 443
SERVER_ADDR 10.50.50.197
REMOTE_PORT 45544
REMOTE_ADDR 10.50.50.12
GATEWAY_INTERFACE CGI/1.1
HTTPS on
REQUEST_SCHEME https
SERVER_PROTOCOL HTTP/1.0
DOCUMENT_ROOT /data/websites/telefonino/web
DOCUMENT_URI /index.php
SCRIPT_NAME /index.php
CONTENT_LENGTH
CONTENT_TYPE
REQUEST_METHOD GET
QUERY_STRING
SCRIPT_FILENAME /data/websites/telefonino/web/index.php
FCGI_ROLE RESPONDER
PHP_SELF /index.php
REQUEST_TIME_FLOAT 1774897030.9912
REQUEST_TIME 1774897030
DB_NAME telefonino
DB_USER telefoninoUSR
DB_PASSWORD .T3lefon!n0.
DB_HOST localhost
DB_PREFIX wp_
GTM_ID GTM-PV4S3R4X
ASSETS_DIR /app/themes/telefonino/assets
FORMINATOR_NEWSLETTER_FORM_ID 404256
WP_ENV staging
WP_HOME https://staging.telefonino.net
WP_SITEURL https://staging.telefonino.net/wp
WP_THEMEPATH https://staging.telefonino.net/app/themes/telefonino/
WP_EMAIL no-reply@telefonino.net
WP_DEBUG true
WP_CACHE false
DISABLE_WP_CRON true
WP_MEMORY_LIMIT 512M
WP_POST_REVISIONS false
AUTH_KEY &uq&p$ypr;Yr7DiuR3ECXHD14o0M562d|MYpdP>;X.fm9q@pOvJ^D-/w9uC+`q1z
SECURE_AUTH_KEY *kkFy7N_9]uNEIk%lG{zxv|aT/_BSV:-|l+C{NU|2/|-HJqP82K[e7mg=>qX!Mef
LOGGED_IN_KEY RJ%0[1(1^$bKjvj^IXV!e[%+yD;d1_fl/)Q4/SdSO>>np:+=`+Es9UbS]dOg89J=
NONCE_KEY 1RTq(</}tixMOUC^n44?.,xA!,n-ms-6J@,LS@/aVJAk8<Ofvjaeu[1iPzU,oG{q
AUTH_SALT ,ptA@)1JrYHO3CjZxYcqX_v<7@X1>2*v7K<Ul2?ofl2qP<>!qzjkf)$Zu&iovz-k
SECURE_AUTH_SALT GA/axYdH9ls=wCH#1XwF9P&E<jOP^d4VKlFF?>vb4Czz3v$jz0dl@DES]&A3D_`^
LOGGED_IN_SALT tWjy]Qb,XQ9%th/9Oi1D;E/L@z-Oo5<TfTSVD-obR;MTyal!SWCcez=fnAGNFlFL
NONCE_SALT aMNhCOYLU+(1URHOor&2^Ux0}9%5eQ1B;MRZ({=XMcw!+42NI3Gx?;,L&Y;yYni]
ACF_PRO_KEY b3JkZXJfaWQ9NzQ2MTV8dHlwZT1kZXZlbG9wZXJ8ZGF0ZT0yMDE2LTAyLTA5IDExOjQ5OjE5
Key Value
DB_NAME telefonino
DB_USER telefoninoUSR
DB_PASSWORD .T3lefon!n0.
DB_HOST localhost
DB_PREFIX wp_
GTM_ID GTM-PV4S3R4X
ASSETS_DIR /app/themes/telefonino/assets
FORMINATOR_NEWSLETTER_FORM_ID 404256
WP_ENV staging
WP_HOME https://staging.telefonino.net
WP_SITEURL https://staging.telefonino.net/wp
WP_THEMEPATH https://staging.telefonino.net/app/themes/telefonino/
WP_EMAIL no-reply@telefonino.net
WP_DEBUG true
WP_CACHE false
DISABLE_WP_CRON true
WP_MEMORY_LIMIT 512M
WP_POST_REVISIONS false
AUTH_KEY &uq&p$ypr;Yr7DiuR3ECXHD14o0M562d|MYpdP>;X.fm9q@pOvJ^D-/w9uC+`q1z
SECURE_AUTH_KEY *kkFy7N_9]uNEIk%lG{zxv|aT/_BSV:-|l+C{NU|2/|-HJqP82K[e7mg=>qX!Mef
LOGGED_IN_KEY RJ%0[1(1^$bKjvj^IXV!e[%+yD;d1_fl/)Q4/SdSO>>np:+=`+Es9UbS]dOg89J=
NONCE_KEY 1RTq(</}tixMOUC^n44?.,xA!,n-ms-6J@,LS@/aVJAk8<Ofvjaeu[1iPzU,oG{q
AUTH_SALT ,ptA@)1JrYHO3CjZxYcqX_v<7@X1>2*v7K<Ul2?ofl2qP<>!qzjkf)$Zu&iovz-k
SECURE_AUTH_SALT GA/axYdH9ls=wCH#1XwF9P&E<jOP^d4VKlFF?>vb4Czz3v$jz0dl@DES]&A3D_`^
LOGGED_IN_SALT tWjy]Qb,XQ9%th/9Oi1D;E/L@z-Oo5<TfTSVD-obR;MTyal!SWCcez=fnAGNFlFL
NONCE_SALT aMNhCOYLU+(1URHOor&2^Ux0}9%5eQ1B;MRZ({=XMcw!+42NI3Gx?;,L&Y;yYni]
ACF_PRO_KEY b3JkZXJfaWQ9NzQ2MTV8dHlwZT1kZXZlbG9wZXJ8ZGF0ZT0yMDE2LTAyLTA5IDExOjQ5OjE5
0. Whoops\Handler\PrettyPageHandler