How to load a controller class from admin to controller class in catalog - opencart

How to load a controller class from admin to controller class in catalog
/admin/controller/tool/getip.php
load function ip() from getip.php in: /catalog/controller/account/account.php
getip.php
class ControllerGetIp extends Controller {
public function ip() {
return ...;
}
...
}
account.php
class ControllerAccount extends Controller {
public function index() {
load ip();
..
}

Try to write the code below in your account controller
$ip = $this->load->controller('tool/getip');
$getip = $ip->ip();

Related

How to inject a service into a constructor when creating a new instance of an object?

The Setup: I've registered a configuration service that pulls data from appsettings.json and it works fine. I also have a controller that uses that service to get settings from that file, again this works like it's supposed to:
public class ApiController : Controller
{
private readonly string _apiUri;
public ApiController(IOptions<Configurator> config)
{
_apiUri = config.Value.ApiSettings.ApiBaseUrl +
config.Value.ApiSettings.ApiVersion;
}
//...
}
Now note, I'm new to automated unit testing and to asp.net core. What I'd like to do is to decouple the ApiController's reliance on the injected service so that I can use a separate XUnit test project to test functions inside the controller, similar to the example in this tutorial.
To do this I created a model and interface representing the ApiSettings section of my appsettings.json file:
"ApiSettings": {
"ApiBaseUrl": "https://example.com/api/",
"ApiVersion": "v1/"
}
The Model:
public class ApiSettings : IApiSettings
{
public string ApiBaseUri { get; set; }
public string ApiVersion { get; set; }
}
The Interface:
public interface IApiSettings
{
string ApiBaseUri { get; set; }
string ApiVersion { get; set; }
}
I then created a class that would be dependent on the service to inject the settings:
public class ApiSettingsBuilder
{
private readonly string _apiUri;
public ApiSettingsBuilder(IOptions<Configurator> config)
{
_apiUri = config.Value.ApiSettings.ApiBaseUrl +
config.Value.ApiSettings.ApiVersion;
}
public string ApiUri { get { return _apiUri; } }
}
The Problem: How do I create an new instance of this class?
public class ApiController : Controller
{
private readonly string _apiUri;
public ApiController()
{
ApiSettingsBuilder builder = new ApiSettingsBuilder(/*What do I do here*/);
_apiUri = builder.ApiUri;
}
public ApiController(IApiSettings settings)
{
//For testing
_apiUri = settings.ApiBaseUrl + settings.ApiVersion;
}
//...
}
Also, I know this is all a bit overkill, but I would still like an answer because It would possibly be useful in other scenarios.
You don't have to create new classes for unit testing purposes, you can mock the interface of your IOptions using appropriate framework, e.g. Moq:
var configurator = new Configurator() { ApiBaseUrl = "abc" };
var mock = new Mock<IOptions<Configurator>>();
mock.Setup(ap => ap.Value).Returns(configurator);
Then you can pass mocked object to your constructor for unit testing:
var controller = new ApiController(mock.Object);

C# Entity Framework Core & Repository

Having some issues getting my repository to retrieve information - keeps coming back null. Any Thoughts would be appreciated - new to this and teaching myself.
Repository:
public class CustomerRepository : ICustomerRepository
{
private masterContext context;
public CustomerRepository(masterContext context)
{
this.context = context;
}
public IEnumerable<Customer> GetCustomers()
{
return context.Customer.ToList();
}
public Customer GetCustomerById(int customerId)
{
var result = (from c in context.Customer where c.CustomerId == customerId select c).FirstOrDefault();
return result;
}
public void Save()
{
context.SaveChanges();
}
Controller:
public class CustomerController : Controller
{
private readonly ICustomerRepository _repository = null;
public ActionResult Index()
{
var model = (List<Customer>)_repository.GetCustomers();
return View(model);
}
public ActionResult New()
{
return View();
}
}
MasterContext which i had efc make:
public partial class masterContext : DbContext
{
public masterContext(DbContextOptions<masterContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>(entity =>
{
entity.Property(e => e.CustomerName).IsRequired();
});
}
public virtual DbSet<Customer> Customer { get; set; }
public virtual DbSet<Order> Order { get; set; }
}
I think you need to create instances of you Context and your Repository. So in your Controller you need to something like this:
private masterContext context = new masterContext();
private ICustomerRepository repository = new CustomerRepository(context);
I assume that you're not using Dependency injection ... if so you just need to create a Constructor for your Controller that takes CustomerRepository as argument:
public CustomerController(ICustomerRepository _repository) {
repository = _repository;
}
If you did not configure your database context, look here: https://docs.efproject.net/en/latest/platforms/aspnetcore/new-db.html
This will than enable you the dependency injection. Everything you than need to do for the Repository is to use
services.AddScoped<ICustomerRepository,
CustomerRepository>();
And I think it could be good to remove the ToList() in the Repository class and remove the Cast List<Customer> in your Controller and use ToList() instead, if it's really needed. Because if you're using it in the View the ienumerable could also work.

Jukito: How to instantiate Widget while testing view

I have Jukito test like this:
#RunWith(JukitoRunner.class)
public class HomeViewTest extends ViewTestBase {
#Inject
private HomeView homeView;
public static class Module extends ViewTestModule {
#Override
protected void configureViewTest() {
bind(HomeView.Binder.class).to(HomeTestBinder.class);
}
static class HomeTestBinder extends MockingBinder<Widget, HomeView> implements HomeView.Binder {
#Inject
public HomeTestBinder(final MockFactory mockitoMockFactory) {
super(Widget.class, mockitoMockFactory);
}
}
}
}
In home view I'm creating new instance of widget HTML. Like this
final HTML connectToServer = new HTML();
But test fails with follow exception:
Caused by: java.lang.UnsatisfiedLinkError: com.google.gwt.dom.client.Document.nativeGet()Lcom/google/gwt/dom/client/Document;
at com.google.gwt.dom.client.Document.nativeGet(Native Method)
at com.google.gwt.dom.client.Document.get(Document.java:46)
at com.google.gwt.user.client.ui.HTML.<init>(HTML.java:84)
I tried a forceMock() but it didn't help. Among this I tried to inject HTML in constructor through com.google.inject.Provider. It works but I don't like this workaround.
So, any suggestions is appriciated.

CXF In interceptor get reference to service object

I am extending AbstractPhaseInterceptor, and I want to get hold of the JAXWS web service object, in INVOKE or PRE_INVOKE phase. How do I do this?
To be clear, I need to get a reference to the object that implements the web service methods, so:
#WebService(...)
public class ExampleWebService
{
#WebMethod(...)
public void doSomething(...)
{
}
}
public class MyInterceptor
extends AbstractPhaseInterceptor<Message>
{
public MyInterceptor()
{
super(Phase.INVOKE);
}
#Override
public void handleMessage(Message message)
throws Fault
{
ExampleWebService serviceObject = getServiceObject(message);
}
private static ExampleWebService getServiceObject(Message messsage)
{
// how do I implement this?
}
}
I do not test the code but something like that probably works.
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
...
Server server = serverFactoryBean.create();
MyInterceptor myInterceptor = new MyInterceptor(server.getEndpoint());
server.getEndpoint().getInInterceptor().add(myInterceptor);

Extends Form Data in scout eclipse

I have some abstract form :
#FormData(value = AbstractMyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public abstract class AbstractMyForm extends AbstractForm {
...
#Order(10.0)
#ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
This form data has some table (MyTable class as template) inside :
public abstract class AbstractMyFormData extends AbstractFormData {
private static final long serialVersionUID = 1L;
public AbstractMyFormData() {}
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
}
My real form extends AbstractMyForm :
#FormData(value = MyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public class MyForm extends AbstractMyForm {
...
#Order(10.0)
#ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
form data for this is :
public class MyFormData extends AbstractMyFormData {
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
.....
.....
}
The problem is that both form datas (AbstractMyFormData and MyFormData) has implemented
public static class MyTable extends AbstractMyTableData
and than scout complains that has duplicate method getMyTable().
But I don't understand this. If MyFormData is extend from AbstractMyFormData than MyFormData must not have this method inside because it already has it his parent.
How to do this? I see FormData.SdkCommand.USE that by description might be it, but I don't now how to use it.
Second question witch might be related is how to inject table in AbstractMyForm like normal AbstractForm inject Cancel button?
EDIT :
Code for classes :
ABSTRACT FORM
#FormData(value = AbstractPurchasePriceFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
#ClassId("41f0f405-b257-47e7-accf-270f5be158ce")
public abstract class AbstractMyForm extends AbstractForm {
/**
* #throws org.eclipse.scout.commons.exception.ProcessingException
*/
public AbstractMyForm() throws ProcessingException {
super();
}
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
#Override
protected String getConfiguredTitle() {
return TEXTS.get("AbstractMyForm");
}
}
AbstractMyTableField template :
import org.eclipse.scout.commons.annotations.FormData;
import org.eclipse.scout.commons.annotations.Order;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractIntegerColumn;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
import org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField;
import org.eclipse.scout.rt.extension.client.ui.basic.table.AbstractExtensibleTable;
#FormData(value = AbstractMyTableFieldData.class, sdkCommand = FormData.SdkCommand.CREATE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE)
public abstract class AbstractMyTableField extends AbstractTableField<AbstractMyTableField.Table> {
#Order(10.0)
public class Table extends AbstractExtensibleTable {
#Order(10.0)
public class NameColumn extends AbstractStringColumn {
}
#Order(20.0)
public class AgeColumn extends AbstractIntegerColumn {
}
}
}
FOR REAL FORM you just create form from template :
and in main box add MyTable like :
insted :
#Order(10.0)
public class MainBox extends AbstractGroupBox {
}
do :
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
I hope I was more explicit this time.
EDIT 2
I admit that creating main box inside abstract form is maybe not the right approach, but what I want to achive is to have AbstractMyTableField in AbstractMyFormData, so I can rely on server side that all forms that extend from AbstractMyForm has this in form data so I can write only one server method for all forms (returning AbstractMyFormData).
FormData and Form hierarchy
The formData hierarchy reflects the form hierarchy. If you form hierarchy looks like this:
MyForm
|-- PersonForm
| \-- VipForm.
\-- CompanyForm
Your formData hierarchy looks like this:
MyFormData
|-- PersonFormData
| \-- VipFormData
\-- CompanyFormData
Do not define the MainBox twice
With you example, You have absolutely right the code generated by the SDK contains compilation errors.
I have tried to explain it in your question about form template, but it doesn’t make any sense to have a main box in the form template and in one in the concrete form.
Each form contains:
0..n variables
0..n Key Strokes (inner classes implementing IKeyStroke)
exactly 1 Main Box (inner class implementing IGroupBox)
0..n ToolButtons (inner classes implementing IToolButton)
1..n Form Handler (usually defined as inner classes implementing IFormHandler, but since the handler is set as parameter of AbstractForm.startInternal(IFormHandler) the handler can be defined everywhere)
In your case, when you consider how the concrete form (MyForm) looks like, you notice that it have two MainBox:
one corresponding to ConcreteForm.MainBox
one contributed by the abstract class and corresponding to AbstractMyForm.MainBox
I would have expected a compile error (from a pure jave point of view) but it seems to work.
At runtime scout pick one of the two MainBox classes and use it as root of the field tree. I am not even sure if the selected MainBox is well defined by scout or if you just randomly get one of the two (depending on what the java introspection Class.getClasses() will return).
I do not see what is ensured with the pattern you have used. You can define something else in the main box of the concrete form:
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class NameField extends AbstractStringField {
#Override
protected String getConfiguredLabel() {
return TEXTS.get("Name");
}
}
#Order(20.0)
public class OkButton extends AbstractOkButton {
}
#Order(30.0)
public class CancelButton extends AbstractCancelButton {
}
}
In this case I do not have any table extending AbstractMyTableField in the concrete form, even if one table is defined in the abstract class used as form template.
#FormData configuration
You can influence the generation of the formData with the formData annotation. Here two examples:
1/ If you work with group boxes defined as templates you can decide if the GroupBoxData should be an external class or not. You can try it by ourself:
Check or uncheck the checkbox "Create external FormData". You can compare the output (generated classes) and the #FormData annotation.
2/ For TableData you can decided how the structure in the formData will look like (bean based or array based). See TableData on the eclipse wiki
Usage of the different options is described in the JavaDoc of the #FormData annotation.
If you have moved some field from one class to another, I recommend you to regenerate all the FormDatas with the SDK. (“Update all formData classes” in the scout explorer). This might solve your compilations problem.