I want to override class MySQL of PrestaShop module ps_facetedsearch that is located in file: mystore/modules/ps_facetedsearch/src/Adapter/MySQL.php
How do I achieve this?
EDIT:
Class MySQL that I want to override is defined in file mystore/modules/ps_facetedsearch/src/Adapter/MySQL.php.
This class is used by class Search of same module and is defined in file mystore/modules/ps_facetedsearch/src/Product/Search.php. Class Search is used by another module class and so on, so there is a long 'chain' of classes.
Do I need to extend all chained classes or can I somehow override only the MySQL class that really requires modification?
Override Module Classes
To modify behavior of a module’s class you have to put your modified class at
ROOT/override/modules/MODULENAME/OVERRIDECLASS.php
You have to create a PHP file on the location below and call it ps_facetedsearch.php
ROOT/override/modules/ps_facetedsearch/ps_facetedsearch.php
Inside the overriding class you can add the code below.
<?php
class Ps_FacetedsearchOverride extends Ps_Facetedsearch
{
public function getContent()
{
return "Hello store owner! this code is brought to you by crezzur.com";
}
}
?>
After saving your ps_facetedsearch.php override and clearing the Prestashop cache you will see the message "Hello store owner! this code is brought to you by crezzur.com" when you open the module ps_facetedsearch.
Related
I have project structure like
app :
InstantApp :
library:
dynamic-feature1 :
dynamic-feature2 :
dynamic-feature3 :
Now there is some dependency between dynamic-feature1 and dynamic-feature2. Now if i add it as dependency in dynamic-feature2 build.gradle then it will cause cyclic dependency.
Above is just one example there are many other cases too. How to handle such dependency conflicts properly or any suggestion ?
Communicate from the main app module to a dynamic feature module
You can do this by reflection in Java. Make sure your class and method names are not obfuscated in the dynamic modules.
Get a Fragment/Activity or other class from module:
Class class = Class.forName("your.dynamic.module.package.name.classname");
Get a method from your class:
Method method = class.getMethod("GenerateQuestion");
Invoke the method:
method.invoke(objectYouWantToInvokeTheMethodOn);
Communicate from dynamic feature module to main module
To get a parent activity of a dynamic feature module's fragment you can do:
#Override
public void onAttach(Context context) {
super.onAttach(context);
activity = (Activity) context;
}
Then you can call a method on that activity.
How can I override the default functionality of Prestashop 1.7 using the override feature
To override the Prestashop controller class you have to create a separate file with the same name as the class name and extend it to the core class and put that file in to override folder.
For example: if you want to override the Product class located at
root/classess/Product.php
Create a file with the name Product.php in root/override/classes/ folder.
Now create the Product class and extend it to ProductCore class
class Product extends ProductCore
{
// put the functions and variables that need to be override
}
This is not compulsory to put all the content of ProductCore class into the override class. Just put the required functions that you want to override.
Note: Don't forget to clear the cache.
(I am a new ByteBuddy user. I'm using ByteBuddy version 1.10.8 and JDK 11 without the module path or any other part of the module system.)
I have a nested class declared like this:
public static class Frob {
protected Frob() {
super();
}
public String sayHello() {
return "Hello!";
}
}
(Its containing class is foo.bar.TestExplorations.)
When I create a dynamic subclass of Frob named foo.bar.Crap like the following, everything works OK as I would expect:
final String className = "foo.bar.Crap";
final DynamicType.Unloaded<?> dynamicTypeUnloaded = new ByteBuddy()
.subclass(Frob.class)
.name(className)
.make();
final Class<?> mySubclass = dynamicTypeUnloaded
.load(this.getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertNotNull(mySubclass);
assertEquals(className, mySubclass.getName());
final Object frobSubclass = mySubclass.newInstance();
assertTrue(frobSubclass instanceof Frob);
But if I change Frob's constructor so that it is package private, I get the following error from the final assertion:
java.lang.IllegalAccessError: class foo.bar.Crap tried to access method 'void foo.bar.TestExplorations$Frob.<init>()' (foo.bar.Crap is in unnamed module of loader net.bytebuddy.dynamic.loading.ByteArrayClassLoader #5e3d57c7; foo.bar.TestExplorations$Frob is in unnamed module of loader 'app')
For some reason, Crap's constructor cannot call super(), even though Crap and Frob are in the same package, and Frob() is defined as package-private.
I have a sense the JDK module system is to blame here, even though I am deliberately (very, very deliberately) not using it. I know the module system does not like split packages, which is what it looks like to me is going on here. Is there a constructor strategy or other mechanism to work around this problem?
In Java, a package is only equal to another package if it has the same name and is loaded by the same class loader (the same as it is with classes). If you are using the WRAPPER strategy, you cannot access package-private members of any super class. Byte Buddy does not forbid the generation as it would be legal to do in javac but you would need to use the INJECTION strategy to do what you want to make sure that classes are loaded by the same class loader. Mind that it uses internal API, therefore, from Java 9, you'd rather use a ForLookup class loading strategy.
How to override ModuleCore class located in /classes/module/Module.php?
If I put class ModuleOverride extends ModuleCore (...) in /override/classes/module/Module.php, the file is ignored.
The override of built in class is the same name without the "Core". In ModuleCore the override class would be just class Module extends ModuleCore (...) and the location is correct, the same, but inside the folder override. The Override suffix is for modules classes.
Dont' forget to delete de cache/class_index.php file.
I have built a cloud project for a month. My problem is that:
I have 2 classes to connect with Ibm web service. First class is the main class and the second one is test class. I put a key-value to appSetting in Config File.
If value in configFile is "TEST", the project will use test class and if value is the "PROD", the project will use main class. When I change the value in config, I will not change everywhere.
My Manager gave me advice to use "interface" but I didn't understand.
How can I solve this problem basiclly?
Both your test class and prod class could implement the said interface. If you need to use the approach where you do the selection in the config file of which class to use you are probably better off creating a data factory class that returns the correct implementation of the interface. The data factory reads the config file and depending on the value in app settings returns the correct class that implements the interface.
Example of doing this in C# (the concept is the same in other oo languages as well):
From the calling class:
SomethingFactory factory = new SomethingFactory();
ISomething testOrProdObj = factory.GetCorrectImplementation();
var result = testOrProdObj.MyMethod();
And in the factory class:
public class SomethingFactory
{
public ISomething GetCorrectImplementation()
{
//Do a check in appsettings to decide which class (TESTSomething or PRODSomething) to instantiate and return
}
}
Implementation of the interface
public class TESTSomething : ISomething
or
public class PRODSomething : ISomething