7

Is there a better way then using VQMOD/OCMOD to change OpenCart's core files?

Is there some "overrides" folder exists so that I can simply create any PHP file corresponding to the file structure and simply override a core file? (Like it is possible in PrestaShop and Magento).

VQMOD/OCMOD is highly inconvenient. Does someone use any hacks & tricks to achieve the result?

I don't want to touch any core files to keep the system clean and manageable.

Thanks a lot!

Serhii Matrunchyk
  • 9,083
  • 6
  • 34
  • 47

5 Answers5

6

If you want to call your function within the system which follows the OC structure, avoid the search/replace mods, try using the new Opencart Events (a.k.a. hooks) instead:

https://github.com/opencart/opencart/wiki/Events-System

Or, you can still use the Opencart override engine (by a 3rd-party developer) though.

Nikhil Chaudhary
  • 478
  • 4
  • 16
  • 1
    Years down the line, it's still an issue. Documentation is poor and rarely updated. On oc 3x now - what if a simple change is needed to a tpl/twig file using the events system... How to replace/insert a line of code? There is no documentation that makes sense, or a working example of this. OC are constantly updating their core code but failing to update docs alongside it and help the community. vQmod was my method and it was easy but is being pushed out due to loss of control by OC, @jaygilford did a great job on this, it's a shame. OCmod is buggy and convoluted, events are poorly documented. – mackwizard Aug 20 '17 at 12:17
6

My solution was to modify 1 function (modification()) in the system/startup.php which then allows you to copy any existing PHP file into an 'override' folder and modify it without making changes to the original file.
I'd like to find a way of just replacing the functions changed/added, but the OOP approach in OpenCart doesn't easily allow this.
I've adapted a few OCMOD modules to fit my override method (by applying the module, copying the changed files into my override structure and then removing the module), as I think it's easier to maintain and easier to develop with, and when I create my own modules, I create dummy files in the main structure and the actual files in the 'override' directory, which means all my modifications/additions are in one folder that maintains the structure of the original layout.
It would be possible to generate file diffs that create an OCMOD, but I haven't had time to do that yet. I do mark all my changes, so I can upgrade to newer versions by re-applying my changes manually (which is usually a "good thing" (c), and there is potential to have conflict with other extensions, so manually marking changes means I can apply changes to OCMOD patched files too. My modification function looks like this:

function modification($filename) {
    $mod_dirs = array(
        DIR_MODIFICATION,
        dirname(DIR_SYSTEM).'/override/'    // do this second in case there are other over-rides needed for modules
    );

    foreach($mod_dirs as $mod) {
        if (!defined('DIR_CATALOG')) {
            $file = $mod . 'catalog/' . substr($filename, strlen(DIR_APPLICATION));
        } else {
            $file = $mod . 'admin/' .  substr($filename, strlen(DIR_APPLICATION));
        }

        if (substr($filename, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
            $file = $mod . 'system/' . substr($filename, strlen(DIR_SYSTEM));
        }

        if (is_file($file)) {
            return $file;
        }
    }

    return $filename;
}

and my directory structure looks like this

/override
/override/admin
/override/catalog
/override/system
kevstev01
  • 330
  • 5
  • 13
  • 1
    Nice approach! Thanks for sharing – Serhii Matrunchyk Jun 20 '17 at 12:20
  • 1
    It is a nice approach in a way but it will probably prevent all extensions from working? – Paul Feakins Apr 02 '19 at 10:05
  • @PaulFeakins My modification() function also checks the existing DIR_MODIFICATION folder, which is where extensions store modified files, so this method works alongside VQMOD/OCMOD extension modules. – kevstev01 Apr 10 '19 at 09:17
  • But what does it do if it finds a modified file in there? Just use yours instead? In which case it would break any extensions? – Paul Feakins Apr 11 '19 at 10:01
  • @Paul Feakins - it's the other way round actually, as my customised modification function uses the DIR_MODIFICATION folder first, so if a module has customised an OpenCart default file, that one gets used, even if one exists in the 'override' folder. This was done so that modules can be applied and then any changed files can be merged into the 'override' folder, As noted in the answer, I have successfully done this myself. It's a solution that worked for me, YMMV ;) – kevstev01 Apr 12 '19 at 18:16
  • So to be clear, it tries to apply vQmods and OCMODS to the custom-created files in the override folder? If so I can see it would work in most cases as long as the custom files still contain the 'hooks' vQ and OC mods are looking for. – Paul Feakins Apr 15 '19 at 14:46
  • no mods are applied to files in this code, it just uses existing files. OpenCart provides a method that 'prefers' retrieving a file from a folder first (DIR_MODIFICATION) rather than the default file structure, and if it exists, returns that file, otherwise the default file. OCMOD modules are used to create new files from specially crafted DIFF instructions usually using regular expressions to perform search/replace operations on default files to store the resulting file in the DIR_MODIFICATION folder. All I've done is to add in an 'override' folder, so that it checks there too. – kevstev01 Apr 15 '19 at 16:25
0

You can use Vqmod or Ocmod in OpenCart. both are working in OpenCart for overrides code.

For vqmod:

Read this Official OpenCart documentation. http://docs.opencart.com/administration/vqmod/

For ocmod:

OCMOD works independently. You have to create ocmod xml file with ".ocmod.xml" extension, then you can upload that file using "Extension Installer" from admin panel of opencart.

You have to clear and refresh the modification cache to update the system and make the extension work. You can clear and refresh by top right buttons on Extension > Modification page in admin panel.

HDP
  • 4,005
  • 2
  • 36
  • 58
  • Thank you, but I'm trying to avoid `Vqmod` and `Ocmod`. They are unusable for me. There is a lot of RegExp rules needed using `install.xml`/`.ocmod.xml` files. And AFAIK unfortunately these system doesn't support multiline search. And what if someday after update it will start matching wrong strings... More questions, then actual programming :) – Serhii Matrunchyk Oct 05 '15 at 18:06
0

wouldn't it be possible to identify a controller file dependent if an alternative exists somewhere else? You could use vq/ocmod one time to write a script that says "if alternative core file exists in xyz location, use it, otherwise, use core file out of base folder" then add new core files to the mods directory that you created.. just a thought..

lexguru
  • 121
  • 6
0

You can try the following solution. The advantage is you can use it with any files moved into system/override folder

function modification($filename) {

    if (defined('DIR_CATALOG')) {
        $file = DIR_MODIFICATION . 'admin/' .  substr($filename, strlen(DIR_APPLICATION));
    } elseif (defined('DIR_OPENCART')) {
        $file = DIR_MODIFICATION . 'install/' .  substr($filename, strlen(DIR_APPLICATION));
    } else {
        $file = DIR_MODIFICATION . 'catalog/' . substr($filename, strlen(DIR_APPLICATION));
    }

    if (substr($filename, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
        $file = DIR_MODIFICATION . 'system/' . substr($filename, strlen(DIR_SYSTEM));
    }

    if (is_file($file)) {

        $new_file = str_replace("/storage/modification/" , "/override/",$file ); 

         if (is_file($new_file))   $__file =  $new_file;
            else $__file =  $file;

        return $__file; 
    }

    if( preg_match("/\/catalog\/model\//",  $filename) ) 
       $new_file      = str_replace("catalog/model", "system/override/catalog/model", $filename );  
    else if( preg_match("/\/catalog\/controller\//",  $filename) ) 
      $new_file = str_replace("catalog/controller", "system/override/catalog/controller",$filename );  
    else   $new_file = '';

    if (file_exists($new_file )) $__file = $new_file; 
    else $__file = $filename;

    return $__file;
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103