How to load catalog model in admin controller - opencart

I am using Opencart Version 2.1.0.1, how to load frontend model in admin controller,
i have a model function which tells external booking id
class ModelShippingParcelled extends Model {
public function getParcelledBooking($order_id) {
$query = $this->db->query("SELECT booking_id FROM " . DB_PREFIX . "parcelled WHERE order_id = '" . (int)$order_id . "'");
return $query->row;
}
I want to load this model in admin controller. What is the best way to do this?
Should I rewrite this model in admin too? But I don't want to rewrite the same function. If there is a good way please suggest!

Well, there is one ugly trick to achieve what you want. Example if you want to use the frontend's catalog/product model from your admin controller, then you can:
require_once DIR_CATALOG . "model/catalog/product.php";
$product = new ModelCatalogProduct($this->registry);
This will work also when you want to use the admin model from the frontend controller, just change the require statement.

I also needed to call a function from catalog/model inside admin/model (without copying). Requiring a function occured to be imposible in php.
But I figured out that I can move the function into system/library, for example in /system/library/cart/cart.php.
Albeit cart functions is never called in admin it occured to be possible. So I called it like
$this->cart->functionName($params)
To make sure function is still working in catalog I made replacement via shell like
find catalog -type f -print0 | xargs -0 sed -i '' -e 's/this->model_catalog_filter->functionName/this->cart->functionName/g'

I suggest that you make a copy of the model in the admin folder.
And if you are sure which functions you are gonna use copy only them.

Related

Save data created in OpenCart 2.3 event for later display

I see how to use an event to generate a controller call in OpenCart 2.3.
What I don't see is how to save the data created by the controller call for later use in a view.
How have other people handled this?
Not sure exactly what you want to do here but couldn't you just do something like:
file_put_contents(DIR_CACHE . __CLASS__ . __FUNCTION__ . md5(serialize($this->request->get)) . '.ser', serialize($data));
That would store everything in $data (which is everything that gets passed to the view) in a flat file named after the class and method and query parameters.
Then, for example, to recall later on a product page, just do:
if (file_exists(DIR_CACHE . __CLASS__ . __FUNCTION__ . md5(serialize($this->request->get)) . '.ser') {
$data = unserialize(file_get_contents(DIR_CACHE . __CLASS__ . __FUNCTION__ . md5(serialize($this->request->get)) . '.ser'));
$this->response->setOutput($this->load->view('product/product', $data));
}
Not sure if that answers your question but could could also just use Opencart's built in cache methods if you wanted it to expire at regular intervals.

How to get full url of a article by it's ID in joomla?

I have article id, How can I get valid full url of this article? This article already associated with menu but I might not know, is there any easy way in php to get url? I am using joomla 3.2
I tried following already.
$article = ControllerLegacy::getInstance('Content')->getModel('Article')->getItem($article‌​Id);
JRoute::_(ContentHelperRoute::getArticleRoute($articleId,$article->catid))
You can use like this
$article = JControllerLegacy::getInstance('Content')
->getModel('Article')->getItem($articleId);
$url = JRoute::_(ContentHelperRoute::getArticleRoute($articleId,
$article->catid,
$article->language))
I am writing this because I think this information is useful to all other users who want full current URL anywhere in Joomla not only in articles.
In Joomla use JURIclass to get URLs.
Functions like root(), current() & base() will be used according to the need.
echo 'Joomla root URI is ' . JURI::root();
output:-Joomla root URI is http://localhost/joomla/
echo 'Joomla current URI is ' . JURI::current();
output:-Joomla current URI is http://localhost/joomla3/index.php/somealias
Note:- current() will give the whole URI except the query string part, for example,
IF your full URL is http://localhost/joomla3/index.php/somealias?id=1 then current() will only return this-> http://localhost/joomla3/index.php/somealias
While, if you use JURI::getInstance()->toString() then it will return this->
http://localhost/joomla3/index.php/somealias?id=1
For more information see these links->
https://docs.joomla.org/JURI/root
https://docs.joomla.org/JURI/current
https://docs.joomla.org/JURI/getInstance
Maybe the JURI (from Joomla! API) help you:
exemple:
echo 'Joomla current URI is ' . JURI::current() . "\n";
might output
Joomla base URI is http://localhost/joomla/
JURI class

Joomla: calling function from models with parameter

Since Joomla 2.5 I can call functions from the default model now with this code:
$result = $this->get('Data');
Where get and Data together are leading to the function name "getData".
But I cannot do this:
$myModel = $this->getModel('special_model');
$result = $myModel->getData();
and I can also not do:
$myModel = $this->getModel('special_model');
$result = $myModel->getData('myId');
So, I can't call a method directly and also not with a parameter? Is it correct? Why is it like this? In J!1.5 this was possible.
Best Regards
Björn
What you have actually will work in J2.5, but you have to add one more piece. That should work as is if you are in the 'special_model' view. Based on the naming though, you are trying to add a second model to the view. This model has to be added to the view from the controller:
$view = $this->getView('myview', 'html') ;
$view->setModel( $this->getModel( 'special_model' )) ;
Again, add that to the controller, and the code you have will work in the model.

Django: How to access the model id's within an AJAX script?

I was wondering what is the correct approach,
Do I create HiddenInput fields in my ModelForm and from the
View I pass in the primaryKey for the models I am about to edit into
the hiddenInput fields and then grab those hiddenInput fields from
the AJAX script to use it like this?
item.load(
"/bookmark/save/" + hidden_input_field_1,
null,
function () {
$("#save-form").submit(bookmark_save);
}
);
Or is there is some more clever way of doing it and I have no idea?
Thanks
It depends upon how you want to implement.
The basic idea is to edit 1. you need to get the existing instance, 2. Save provided information into this object.
For #1 you can do it multiple ways, like passing ID or any other primary key like attribute in url like http://myserver/edit_object/1 , Or pass ID as hidden input then you have to do it through templates.
For #2, I think you would already know this. Do something like
inst = MyModel.objects.get(id=input_id) # input_id taken as per #1
myform = MyForm(request.POST, instance=inst)
if myform.is_valid():
saved_inst = myform.save()
I just asked in the django IRC room and it says:
since js isn't processed by the django template engine, this is not
possible.
Hence the id or the object passed in from django view can't be accessed within AJAX script.

is it possible to create a custom admin view without a model behind it

I have an object which I want to use under admin instead of a model which inherits models.Model. If I make it inherit models.Model, this object will create a table in the database which i don't want. I only want this object to stay in memory.
One solution I have come with help from the nice people at stack overflow is I create admin views, register these custom views via a modelAdmin ( admin.site.register() ) under admin.py and use this model-like object as dynamic data storage (in memory).
Since this model like object doesn't inherit from models.Model, admin.site.register() (under admin.py) doesnt accept it and shows a 'type' object is not iterable" error when I try to access it in the browser.
hmmm. Thanks for your help everyone. The solution I have come up ( with your help ofcourse :) is as follows:
I have two custom templates:
my_model_list.html
my_model_detail.html
Under views.py:
class MyModel(object):
# ... Access other models
# ... process / normalise data
# ... store data
#staff_member_required
def my_model_list_view(request) #show list of all objects
#. . . create objects of MyModel . . .
#. . . call their processing methods . . .
#. . . store in context variable . . .
r = render_to_response('admin/myapp/my_model_list.html', context, RequestContext(request))
return HttpResponse(r)
#staff_member_required
def my_model_detail_view(request, row_id) # Shows one row (all values in the object) in detail
#. . . create object of MyModel . . .
#. . . call it's methods . . .
#. . . store in context variable . . .
r = render_to_response('admin/myapp/my_model_detail.html', context, RequestContext(request))
return HttpResponse(r)
Under the main django urls.py:
urlpatterns = patterns(
'',
(r'^admin/myapp/mymodel/$', my_model_list_view),
(r'^admin/myapp/mymodel/(\d+)/$', my_model_detail_view),
( r'^admin/', include( admin.site.urls ) )
)
You can add your views directly to the AdminSite object, rather than to any particular ModelAdmin subclass which you then register.
The default AdminSite is accessed via django.contrib.admin.site, which is what you call register and autodiscover on. Instead of using this, you could create your own subclass and add your own views to it, and then register your models against that rather than the default one.
The most straightforward answer is "no". As the Django Book says, the admin is for "Trusted users editing structured content," in this case the structured content being models arranged in hierarchies and configured through settings.py. More importantly, if your object doesn't completely duck-type to a models.Model complete with expected relationships, the admin will probably toss exceptions all over the place.
However, as the mantra goes, "It's just python." You can override any of the pages in admin. Just create your own templates in your project, and have them come first in the template search. Also, by inheriting admin/base.html, you maintain the look & feel of the administration project.
Write your administrative view and templates for this object, just like any others, but making sure to wrap the views in the is_staff decorator to ensure that the views are protected from access by unauthorized users. Put those in the application, perhaps in admin/views.py, with templates/admin/object_list.html and object_form.html.
Once you have appropriate administrative tools for these non-database objects, you can then provide access to them through the administration index page: You want to override admin/index.html, and provide additional project-specific items to the page as needed.
I have done exactly this to provide administrative access to third-party APIs that store our data, such as the ConstantContact email service, and it works pretty well.