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.
Related
I'm trying to write my own Jekyll plugin to construct an api query from a custom tag. I've gotten as far as creating the basic plugin and tag, but I've run into the limits of my programming skills so looking to you for help.
Here's my custom tag for reference:
{% card "Arbor Elf | M13" %}
Here's the progress on my plugin:
module Jekyll
class Scryfall < Liquid::Tag
def initialize(tag_name, text, tokens)
super
#text = text
end
def render(context)
# Store the name of the card, ie "Arbor Elf"
#card_name =
# Store the name of the set, ie "M13"
#card_set =
# Build the query
#query = "https://api.scryfall.com/cards/named?exact=#{#card_name}&set=#{#card_set}"
# Store a specific JSON property
#card_art =
# Finally we render out the result
"<img src='#{#card_art}' title='#{#card_name}' />"
end
end
end
Liquid::Template.register_tag('cards', Jekyll::Scryfall)
For reference, here's an example query using the above details (paste it into your browser to see the response you get back)
https://api.scryfall.com/cards/named?exact=arbor+elf&set=m13
My initial attempts after Googling around was to use regex to split the #text at the |, like so:
#card_name = "#{#text}".split(/| */)
This didn't quite work, instead it output this:
[“A”, “r”, “b”, “o”, “r”, “ “, “E”, “l”, “f”, “ “, “|”, “ “, “M”, “1”, “3”, “ “]
I'm also then not sure how to access and store specific properties within the JSON response. Ideally, I can do something like this:
#card_art = JSONRESPONSE.image_uri.large
I'm well aware I'm asking a lot here, but I'd love to try and get this working and learn from it.
Thanks for reading.
Actually, your split should work – you just need to give it the correct regex (and you can call that on #text directly). You also need to escape the pipe character in the regex, because pipes can have special meaning. You can use rubular.com to experiment with regexes.
parts = #text.split(/\|/)
# => => ["Arbor Elf ", " M13"]
Note that they also contain some extra whitespace, which you can remove with strip.
#card_name = parts.first.strip
#card_set = parts.last.strip
This might also be a good time to answer questions like: what happens if the user inserts multiple pipes? What if they insert none? Will your code give them a helpful error message for this?
You'll also need to escape these values in your URL. What if one of your users adds a card containing a & character? Your URL will break:
https://api.scryfall.com/cards/named?exact=Sword of Dungeons & Dragons&set=und
That looks like a URL with three parameters, exact, set and Dragons. You need to encode the user input to be included in a URL:
require 'cgi'
query = "https://api.scryfall.com/cards/named?exact=#{CGI.escape(#card_name)}&set=#{CGI.escape(#card_set)}"
# => "https://api.scryfall.com/cards/named?exact=Sword+of+Dungeons+%26+Dragons&set=und"
What comes after that is a little less clear, because you haven't written the code yet. Try making the call with the Net::HTTP module and then parsing the response with the JSON module. If you have trouble, come back here and ask a new question.
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.
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($articleId);
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
data = form.cleaned_data
rad1=form.cleaned_data['point']
I want to display both the data and rad1 , so as to know what is my form capturing . One way to do it send it as a value to the template to be displayed on the page . But I think there would be an easier way out . If I give a print 'data' . It doesn't print the data anywhere .
Text sent to stderr will appear in the web server's error log; it is best to use either logging or a logger supplied by the WSGI container for this.
If you want the text to appear in the browser then you will need to send it in the response, either as raw text or via a template.
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.