Loading and using models in opencart - codeigniter

Open cart is based on CodeIgniter as I understand but in CodeIgniter to load and use the model you do something like this
$this->load->model('Model_name');
$this->Model_name->function();
In OpenCart you do something like this
$this->load->model('catalog/product');
$this->model_catalog_product->getTotalProducts()
How does this work and where does the "model_catalog_product" come from?
It seems like they have 0 developer documentation besides their forums.

OpenCart's loader class seems to be inspired by CodeIgniter, but it's not based on it. You can look into the source of OpenCart, see file system/engine/loader.php (Line 39).
public function model($model) {
$file = DIR_APPLICATION . 'model/' . $model . '.php';
$class = 'Model' . preg_replace('/[^a-zA-Z0-9]/', '', $model);
if (file_exists($file)) {
include_once($file);
// Right here. Replaces slash by underscore.
$this->registry->set('model_' . str_replace('/', '_', $model), new $class($this->registry));
} else {
trigger_error('Error: Could not load model ' . $model . '!');
exit();
}
}
You can clearly see that it replaces slashes with underscores and append 'model_' before the model's name. That's why you end up with model_catalog_product.

The model_catalog_product comes from the path folder structure and file name within the model folder, so model_catalog_product is the model/catalog/product.php file, with the extension removed and the slashes changed to underscores. Also, notice that the model class name also refers to a similar structure, which is ModelCatalogProduct. As for the documentation, there was some documentation for developers, but just checked briefly and it appears that it's been removed for whatever reason. I learn't from lots of trial and error unfortunately, as have most developers using it

Related

I can't find the implementation for Storage Facade in laravel

I'm new with laravel and I'm working in fileststem on laravel
(I want to do usual fileststem process like -make dir - copy - put -delete -ect)
I'm using laravel "Storage" Facade
but when i type
i referenced the class above like this in my code
use Illuminate\Support\Facades\Storage;
for example below :
if (file_exists(public_path($oldImage))) {
Storage::delete($oldImage);
}
nothing happens ,and when i refer to the class code i found this :
namespace Illuminate\Support\Facades;
/**
* #see \Illuminate\Filesystem\FilesystemManager
*/
class Storage extends Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'filesystem';
}
}
so where is the implementation and if you have alternative way to deal with
filesystem process rather than "Storage" facade ??
Storage is a facade and accesses the class Filesystem located here: vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php
As you can see in the official filesystem documentation the code snippets use Storage.
UPDATE:
You should add use Storage; to be able to use the Storage facade.
I recommend reading the Laravel 8.X docs to get an initial heads up: https://laravel.com/docs/8.x/filesystem
NOTE: Before you get too carried away, make sure you understand the difference between local and public.
For starters, you should make your first goal to upload a file and acquire the UploadedFile type.
You can access a single file via something like $request->file('name'), or an array of images via something like:
// $request->input('images')
foreach ($images as $image) {
\Log::debug($image->getClientOriginalName());
}
If your file upload can be single and/or multiple, I recommend going with the array approach because a single file wrapped in an array allows you to use the same syntax for single and multi uploads (ie: that foreach loop works fine with one image, no extra code).
Here's an example:
use Illuminate\Support\Facades\Storage;
$slug = 'davids-sandwich-photos';
foreach ($images as $image) {
Storage::putFileAs(
'images' .'/'. $slug,
$image,
$image->getClientOriginalName()
);
}
Storage::putFileAs() can take 3 parameters: directory, content, filename. You can see above in the code that I interpolated a mix of static and derived directory name. You could do something like 'images' .'/'. $slug .'/'. Auth::user()->id to save the file in /images/davids-sandwich-photos/11.
Then, check in your repo directory: /storage/app/ and look for the images directory.
You can manually delete the folders while testing to get your bearings straight.
That should be enough to get most people started.
To avoid using the Storage facade, you can use:
foreach ($images as $image) {
$image->storeAs(
'examples' .'/'. $slug,
$image->getClientOriginalName(),
'public'
);
}
--
Check out config/filesystems.php under the disks section if you want to start manipulating the drivers, but I'm not a DB admin expert here.
I also saved this along my journey: https://medium.com/#shafiya.ariff23/how-to-store-uploaded-images-in-public-folder-in-laravel-5-8-and-display-them-on-shared-hosting-e31c7f37a737. You might need that if you get stuck with something like symlinking.
<img
v-for="image in example.images"
:key="image.filename"
:src="`/storage/examples/${example.slug}/${image.filename}`"
>
NOTE: The important part with Vue JS is to use <img src="/storage/examples/slug/filename.jpg"> if your file is located in your repository as /storage/app/public/examples/slug/filename.jpg Pay close attention to every character.
The public_path function returns the fully qualified path to the public directory ie public directory inside the laravel application. When using Storage, the path is set to the storage/app directory.
if (file_exists(public_path($oldImage))) {
//public_path($oldImage) will check for file in public directory
Storage::delete($oldImage); //Will delete file in storage/app directory
}
The modified code should be
if(Storage::has($oldImage)){
Storage::delete($oldImage);
}

CodeIgniter - Dynamic URL segments

I was wondering if someone could help me out.
Im building a forum into my codeigniter application and im having a little trouble figuring out how i build the segments.
As per the CI userguide the uri is built as follows
www.application.com/CLASS/METHOD/ARGUMENTS
This is fine except i need to structure that part a bit different.
In my forum i have categories and posts, so to view a category the following url is used
www.application.com/forums
This is fine as its the class name, but i want to have the next segment dynamic, for instance if i have a category called 'mycategory' and a post by the name of 'this-is-my-first-post', then the structure SHOULD be
www.application.com/forums/mycategory/this-is-my-first-post
I cant seem to achieve that because as per the documentation the 'mycategory' needs to be a method, even if i was to do something like /forums/category/mycategory/this-is-my-first-post it still gets confusing.
If anyone has ever done something like this before, could they shed a little light on it for me please, im quite stuck on this.
Cheers,
Nothing is confusing in the document but you are a little bit confused. Let me give you some suggestions.
You create a view where you create hyperlinks to be clicked and in the hyperlink you provide this instruction
First Post
In the controller you can easily get this
$category = $this->uri->segment(3);
$post = $this->uri->segment(4);
And now you can proceed.
If you think your requirements are something else you can use a hack i have created a method for this which dynamically assign segments.
Go to system/core/uri.php and add this method
function assing_segment($n,$num)
{
$this->segments[$n] = $num;
return $this->segments[$n];
}
How to use
$this->uri->assign_segment(3,'mycategory');
$this->uri->assign_segment(4,'this-is-my-first-post');
And if you have error 'The uri you submitted has disallowed characters' then go to application/config/config.php and add - to this
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
You could make a route that forwards to a lookup function.
For example in your routes.php add a line something like;
$route['product/(:any)/(:any)'] = "forums/cat_lookup/$1/$2";
This function would then do a database lookup to find the category.
...
public function cat_lookup($cat, $post) {
$catid = $this->forum_model->get_by_name($cat);
if ($catid == FALSE) {
redirect('/home');
}
$post_id = $this->post_model->get_by_name($post);
/* whatever else you want */
// then call the function you want or load the view
$this->load->view('show_post');
}
...
This method will keep the url looking as you want and handle any problems if the category does not exist.Don't forget you can store the category/posts in your database using underscores and use the uri_title() function to make them pretty,
Set in within config/routes.php
$route['song-album/(:any)/:num'] = 'Home/song_album/$id';
fetch in function with help of uri segment.
$this->uri->segment(1);

Beginners Tutorial for Zend Framework implementing model and call it from Controller

I'm quite new to ZF, and right now, i try to write a tiny app, based on ZF. It works more or less fine until now. I wanna access my db- data. For starters, i just want to use query-string, before I start messing araound with zend_db. So to keep a nice mvc-structure, I created application/models/IndexMapper.php
class Application_Models_IndexMapper{...}
it just contains one function by now to see if it works
public function test(){
return ('yay');
}
In my IndexController, which is working, i try to access my model by
$indexMapper = new Application_Models_IndexMapper();
$x = $indexMapper->test();
but the first line throws an
Fatal error: Class 'Application_Models_IndexMapper' not found in /path/to/application/controllers/IndexController.php on line 31
As I'm new, I don't understand the more complex tutorials and they don't help me fix my problem. What am I doing wrong? Do I have to include it somehow?
Thanks
edit: my application/bootstrap.php
<?php
defined('APPLICATION_PATH')
or define('APPLICATION_PATH' , dirname(__FILE__));
defined('APPLICATION_ENVIRONMENT')
or define('APPLICATION_ENVIRONMENT' , 'development');
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory(APPLICATION_PATH . '/controllers');
$frontController->setParam('env', APPLICATION_ENVIRONMENT);
Zend_Layout::startMvc(APPLICATION_PATH . '/layouts/scripts');
//Doctype
$view = Zend_Layout::getMvcInstance()->getView();
$view->doctype('HTML5');
$view->addHelperPath('App/View/Helper', 'App_View_Helper');
unset($frontController);
The structure for a model would be found under ./application/models/IndexMapper.php. In that file you would have the class As you named it and then the autoloading will work.
A great beginner tutorial would be found on www.akrabat.com
You have your class in the wrong place and have named it incorrectly.
Your class should be in application/models/Indexmapper.php and should look like this:-
class Application_Model_Indexmapper
{
public function test(){
return ('yay');
}
}
Then you call it thus:-
$indexMapper = new Application_Model_Indexmapper();
$x = $indexMapper->test();
Notice I dropped the 's' from the end of Models, it is not required and will cause an error as you found. Also the class is in the models folder, not modules. If you want to use modules then you need to read this and this from the manual.
Your bootstrap.php should look like this for a first, basic project:-
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
//Yes, it's empty!
}
Well, I guess my tutorial wasn't very helpful. I'll do as recommended, and start over from scratch. Thanks though

Joomla problem with MVC component

I have problem with Joomla layouts in my component..There must be something bad with file/class name convention..
I was trying to ask on Joomla developer forum, but noone answered..
So I am getting this error.. 500 - View not found [name, type, prefix]: PostToBank,,postToBankView
The view is in views/postTobank/view.php and name is postToBankViewPostToBank
In my controllers/controller.php file I have class named PaymentController which contains this part of code.
$view = $this->getView('PostToBank','','postToBankView');
$this->getModel("Payment")->savePaymentData($data);
foreach ($data as $key => $value) {
$view->assignRef($key, $value);
}
$view->setLayout('postTobank');
$view->display();
my view.php file looks like this
class postToBankViewPostToBank extends JView{
function display($tpl=null){
//display set template
parent::display($tpl);
}
}
on attached image is full folder structure of my component..
Please whats wrong with this?Thanks
Joomla uses a naming conventions and you are not following them. Refer to http://docs.joomla.org/File_Structure_and_Naming_Conventions
Also, your views should be view.html.php and then you do not need to call setView.
FYI: this is where the error is coming from. Refer to this: http://docs.joomla.org/API16:JController/getView, even though it is 1.6 doc it is same in 1.5
Look though this tutorial and adopt regular conventions: http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1

yii debug rendering branch

How can i see all view file names which was rendered for current page ?
in debug console there is no any info about which view files were loaded during page generation.
There is no native solution for this but it can be accomplished in a couple ways.
I think the easiest is to override the CViewRenderer class and keep a list of files that renderFile is called with. Overriding the class is a matter of adding
'viewRenderer'=>array
(
'class'=>'MyViewRenderer',
),
In the components part in your config.
It could look like this in its simplest form:
class MyViewRenderer extends CViewRenderer
{
public function renderFile($context, $sourceFile, $data, $return)
{
echo "Rendering " . $sourceFile . PHP_EOL;
return parent::renderFile($context, $sourceFile, $data, $return)
}
}

Resources