2

I've got a Magento CE store that sits behind a proxy and doesn't have outgoing internet access. Obviously this causes problems with Connect Manager and trying to grab updates. To get round this, I have access to a web proxy but there's no way of setting Connect Manager to use a proxy unless I directly edit downloader/lib/Mage/HTTP/Client/Curl.php. This causes problems as each update replaces the file and removes my proxy edits.

What I want to know is if it's possible to extend/override Magento Connect classes like you can for Magento itself.

  • Using Magento Downloader to maintain a live store is a bletcherous process, oft fraught with failure. Establish a staging/dev server that is version managed with git, do the changes there and push them to the live server. – Fiasco Labs Jul 8 '16 at 17:26
1

Absolutely, via autoload preference set in app/Mage.php:

//...
$paths = array();
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local';
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community';
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';
$paths[] = BP . DS . 'lib';

$appPath = implode(PS, $paths);
set_include_path($appPath . PS . Mage::registry('original_include_path'));
//...

Place your edited Mage_HTTP_Client_Curl definition at ./app/code/local/Mage/HTTP/Client/Curl.php and it will be matched by the autoloader before the definition in ./lib/

NB: you are responsible for merging in core changes for this class in the future.

  • You've just described the override method for Magento itself which I'm already taking advantage of but Downloader doesn't appear to allow overrides like this from what I can tell. Certainly doing what you suggest makes no difference to Magento Downloader checking for updates or installing extensions. – Geoffrey Dec 17 '14 at 19:28
  • Ah, I missed the "downloader" in your path. I'll look again. – benmarks Dec 18 '14 at 13:11
  • Any updates on this? I'm looking to override the downloader/lib/Mage/Connect/Packager.php and lib/Mage/Connect/Packager.php files to make them PHP7 compliant. The lib one I can manage with the notes above, but the downloader one still eludes me. – Benjam Mar 3 '16 at 1:50
  • @benjam, since you're recently interested in this, I've posted an answer that I hope will help. – TylersSN May 14 '16 at 14:28
1

Since there still seems to be interest in this post, I'll provide my solution for this.

This assumes that you'll be installing from the command line. This fix will prevent you from touching any core files. If you adhere to Magento's recommended file/folder permissions this shouldn't open up any vulnerabilities - I'd love an extra set of eyes on this to confirm that statement though since this is my first foray into extending an autoloader.

Once implemented, just replace ./mage with ./mageX when installing from the commandline.

i.e. $ ./mageX install community Community_Package

How to extend Magento's downloader autoload classes

All file paths in the steps below reference the Magento root.

  1. Copy ./mage file to ./mageX
  2. In ./mageX, replace MAGE_PHP_SCRIPT="mage.php" with MAGE_PHP_SCRIPT="mageX.php"
  3. Create this directory: ./downloader/lib/local
  4. Create a file called ./downloader/mageX.php and place the following contents in that file:

    <?php
    /** Store and unset $argv so that mage.php will not execute */
    $storedArgv = $argv;
    unset($argv);
    
    /**
     * Include mage.php and suppress output and php notices to the console
     * The goal is to pull in the __cli_Mage_Connect class while virtually
     * disabling mage.php
     */
    $storedErrorReportingSetting = ini_get('error_reporting');
    error_reporting(E_ERROR);
    ob_start();
    include 'mage.php';
    ob_end_clean();
    
    /** Restore Error Reporting to default settings */
    error_reporting($storedErrorReportingSetting);
    
    /** Restore $argv values */
    $argv = $storedArgv;
    
    class __cli_Mage_ConnectX extends __cli_Mage_Connect
    {
        /**
         * This is a private method set in the parent class
         * It must be declared here as well
         * */
        private static $_instance;
    
        /**
         * I could not get parent::instance() to work, possibly
         * because of self::$_instance, so it is redeclared.
         * */
        public static function instance()
        {
            if(!self::$_instance) {
                self::$_instance = new self();
            }
            return self::$_instance;
        }
    
    
        public function setIncludes()
        {
            parent::setIncludes();
            $this->setExtendedIncludes();
        }
    
        public function setExtendedIncludes()
        {
            if(defined('DEVELOPMENT_MODE')) {
                $libPath = PS . dirname(BP) . DS . 'lib';
            } else {
                $libPath = PS . BP . DS . 'downloader' . DS . 'lib';
            }
            $includePath = BP . DS . 'app' . $libPath . DS . 'local' . PS . get_include_path();
            set_include_path($includePath);
        }
    
        /*public function run()
        {
            $testClass = new My_Class_Name_Is_Here();
            $testClass->killAndOutput("This");
            parent::run(); 
        }*/
    
    }
    
    if(defined('STDIN') && defined('STDOUT') && (defined('STDERR'))) {
        __cli_Mage_ConnectX::instance()->init($argv)->run();
    }
    

We're all set! ./downloader/lib/local is now a referenced include directory. So, when you call new My_Class_Name_Is_Here() it will check

  1. ./app/My/Class/Name/Is/Here.php
  2. ./downloader/lib/My/Class/Name/Is/Here.php
  3. ./downloader/lib/local/My/Class/Name/Is/Here.php

If you want to override the core file ./downloader/lib/Mage/HTTP/Client/Curl.php just copy the file to ./downloader/lib/local/Mage/HTTP/Client/Curl.php

A little more insight into ./mageX

The run() method does not need to be included as shown above. It can be removed. It is included as proof of concept. If you want to test it yourself go ahead and uncomment the run() method, create ./downloader/lib/local/My/Class/Name/Is/Here.php and fill it with the contents below.

    <?php

    class My_Class_Name_Is_Here extends Mage_HTTP_Client_Curl
    {
        public function killAndOutput($text = "")
        {
            die($text);
        }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.