2.0.x-2.2.x/upload/catalog/controller/module/facebook_business.php [218:327]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    private function sendFileResponse($filename) {
        if (!headers_sent()) {
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename="'.basename($filename.'"'));
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length:'.filesize($filename));
      
            if (ob_get_level()) {
                ob_end_clean();
            }
      
            readfile($filename, 'rb');
      
            exit();
        }
    }

    private function getProductFeedPath() {
        $product_feed_dir = $this->getWritableProductFeedDir();

        if (!$product_feed_dir) {
            return false;
        }

        return $product_feed_dir . $this->facebook_feed_filename;
    }

    private function getWritableProductFeedDir() {
        // Checks on 3 folders if they are writable and return a folder if so
        if (is_writable(DIR_DOWNLOAD)) {
            return DIR_DOWNLOAD;
        }

        if (is_writable(DIR_MODIFICATION)) {
            return DIR_MODIFICATION;
        }

        if (is_writable(DIR_LOGS)) {
            return DIR_LOGS;
        }

        return false;
    }

    private function isFeedFileStale($filepath) {
        $time_file_modified = file_exists($filepath) ? filemtime($filepath) : 0;

        /**
         * If no file last modified time is available, or the last modified time
         * is 1 hour ago, we count it as 'stale'
         */
        if (!$time_file_modified) {
            return true;
        } else {
            return time() - $time_file_modified > 3600;
        }
    }

    private function generateProductFeedFile($product_feed_path) {
        try {
            $feed_file = fopen($product_feed_path, "ab");
      
            if (!$this->writeProductFeedFileHeader($feed_file)) {
                fclose($feed_file);
                return false;
            }

            // Process products in batches to handle large product catalogs
            $filter_data = array(
                'filter_status' => 1
            );

            $product_total = $this->model_catalog_product->getTotalProducts($filter_data);
      
            return $this->writeProductFeedFileInBatch($product_total, $feed_file);
        } catch (Exception $e) {
            // Handle any exceptions during the feed file generation
            if (isset($feed_file) && !!($feed_file)) {
                fclose($feed_file);
            }

            return false;
        }
    }

    private function writeProductFeedFileHeader($feed_file) {
        $product_feed_header_row = 'id,title,description,rich_text_description,image_link,link,google_product_category,brand,price,' . 
            'availability,item_group_id,additional_image_link,sale_price,sale_price_effective_date,condition,' . 
            'age_group,color,gender,material,pattern' . PHP_EOL;

        try {
            fputs($feed_file, "\xEF\xBB\xBF");
            fwrite($feed_file, $product_feed_header_row);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    private function writeProductFeedFileInBatch($product_total, $feed_file) {
        $total_batches = ceil($product_total / 100);

        for ($batch_number = 0; $batch_number < $total_batches; $batch_number++) {
            $filter_data = array(
                'start' => $batch_number * 100,
                'limit' => 100,
                'filter_status' => 1
            );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



2.3.x-and-above/upload/catalog/controller/extension/module/facebook_business.php [218:327]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    private function sendFileResponse($filename) {
        if (!headers_sent()) {
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename="'.basename($filename.'"'));
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length:'.filesize($filename));
      
            if (ob_get_level()) {
                ob_end_clean();
            }
      
            readfile($filename, 'rb');
      
            exit();
        }
    }

    private function getProductFeedPath() {
        $product_feed_dir = $this->getWritableProductFeedDir();

        if (!$product_feed_dir) {
            return false;
        }

        return $product_feed_dir . $this->facebook_feed_filename;
    }

    private function getWritableProductFeedDir() {
        // Checks on 3 folders if they are writable and return a folder if so
        if (is_writable(DIR_DOWNLOAD)) {
            return DIR_DOWNLOAD;
        }

        if (is_writable(DIR_MODIFICATION)) {
            return DIR_MODIFICATION;
        }

        if (is_writable(DIR_LOGS)) {
            return DIR_LOGS;
        }

        return false;
    }

    private function isFeedFileStale($filepath) {
        $time_file_modified = file_exists($filepath) ? filemtime($filepath) : 0;

        /**
         * If no file last modified time is available, or the last modified time
         * is 1 hour ago, we count it as 'stale'
         */
        if (!$time_file_modified) {
            return true;
        } else {
            return time() - $time_file_modified > 3600;
        }
    }

    private function generateProductFeedFile($product_feed_path) {
        try {
            $feed_file = fopen($product_feed_path, "ab");

            if (!$this->writeProductFeedFileHeader($feed_file)) {
                fclose($feed_file);
                return false;
            }

            // Process products in batches to handle large product catalogs
            $filter_data = array(
                'filter_status' => 1
            );

            $product_total = $this->model_catalog_product->getTotalProducts($filter_data);
      
            return $this->writeProductFeedFileInBatch($product_total, $feed_file);
        } catch (Exception $e) {
            // Handle any exceptions during the feed file generation
            if (isset($feed_file) && !!($feed_file)) {
                fclose($feed_file);
            }

            return false;
        }
    }

    private function writeProductFeedFileHeader($feed_file) {
        $product_feed_header_row = 'id,title,description,rich_text_description,image_link,link,google_product_category,brand,price,' . 
            'availability,item_group_id,additional_image_link,sale_price,sale_price_effective_date,condition,' . 
            'age_group,color,gender,material,pattern' . PHP_EOL;

        try {
            fputs($feed_file, "\xEF\xBB\xBF");
            fwrite($feed_file, $product_feed_header_row);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    private function writeProductFeedFileInBatch($product_total, $feed_file) {
        $total_batches = ceil($product_total / 100);

        for ($batch_number = 0; $batch_number < $total_batches; $batch_number++) {
            $filter_data = array(
                'start' => $batch_number * 100,
                'limit' => 100,
                'filter_status' => 1
            );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



