I'm fairly new to OpenCart but I know PHP and MVC platforms. I want to make an importer for OpenCart to import some products from a CSV and the photos for them.
However, I've been struggling for the last 2 hours trying to see my module in the admin. I created an admin/controller/module/custom_importer.php:
<?php
class ControllerModuleCustomImporter extends Controller {
}
and a language file admin/language/en-gb/module/custom_importer.php:
$_['heading_title'] = 'Custom Importer';
However, in my admin I can't seem to find the module at all. It's the simplest, emptiest module. What am I doing wrong?
Opencart: Version 3.0.2.0
The path you are using is wrong. Put your file in admin/controller/extension/module/custom_importer.php. Note the class name changes in a corresponding way.
<?php
class ControllerExtensionModuleCustomImporter extends Controller {
}
The language file goes in admin/language/en-gb/extension/module/custom_importer.php.
<?php
$_['heading_title'] = 'Custom Importer';
Now go to Extensions->Extensions and choose Modules. You will see Custom Importer.
Related
I recently tried to use Generic Markers to put out some Database content via TypoScript, but I need to be more flexible, so I'm looking for a solution to make use of hooks to tt_news. I want to parse my own Template of data into the MarkerArray of tt_news.
My own extension comes with /Classes/Controller/FahrzeugController.php and I added the function extraItemMarkerProcessor(..), according to the codehook provided by tt_news.
<?
class FahrzeugController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
function extraItemMarkerProcessor($markerArray, $row, $lConf, $obj) {
$markerArray['###FAHRZEUGE###'] = 'exItMaPro';
return $markerArray;
}
}?>
Then I added some Config-Parameters in my ext_localconf.php .
if (TYPO3_MODE!='BE') {
require_once(t3lib_extMgm::extPath('y7_fahrzeugdatenbank').'/Classes/Controller/FahrzeugController.php');
}
// y7_fahrzeugdatenbank = Path to my Extension , followed by relative path to my .php .
$TYPO3_CONF_VARS['EXTCONF']['tt_news']['extraItemMarkerHook'][] = 'EXT:y7_fahrzeugdatenbank/Classes/Controller/FahrzeugController.php:tx_y7fahrzeugdatenbank'; // tx_y7fahrzeugdatenbank is my SQL prefix
The template part works, as I tested it with generic Markers and the same file. According to many internet guides, it should work out of the box like this. But I don't see anything in any view.
I don't even know, where to start looking.
Your Hook registration in your ext_localconf is wrong. tx_y7fahrzeugdatenbank does not belong there. You have to tell tt_news in which php class your code is found. That would be Vendor\Extension\Controller\FahrzeugController if you followed the extbase Folder structure your class shoukd be autoloaded.
But I strongly suggest not to use an extbase controller for a tt_news Hook. Use a class that only contains your code that should be executed by the hook and nothing more. Put in In your_extenion/Classes/Hooks. Use a proper namespace and TYPO3 will autoload your class for you.
In your ext_localconf.php it will be
$TYPO3_CONF_VARS['EXTCONF']['tt_news']['extraItemMarkerHook'][] = 'Vendor\Extension\Hooks\ClassContainingMyHook';
I'm new to ATK4.
I'm trying to implement an Autocomplete field, but I had only an error when I try to define the field.
I'm running all on a MAC with the last version (4.2.4) of ATK4. All other functions (field types) seems to work well, but when I define a field of type autocomplete I get the same error I saw on the example: http://codepad.agiletoolkit.org/autocomplete
The case is I defined a model:
class Model_Agenda extends Model_Table {
public $entity_code='Agenda';
function init(){
parent::init();
$this->addField('DATE');
$this->addField('TIME');
$this->addField('DRIVERID');
$this->addField('STUDENTID');
$this->hasOne('STUDENTID')->display(array('form'=>'autocomplete/Basic'));
}
}
and then on my Page:
$form = $this->add('Form');
$form->addField('ReadOnly','Date')->Set($_GET['date']);
$form->addField('ReadOnly','Time')->Set($_GET['time']);
$form->addField('ReadOnly','Driver')->Set($_GET['driverid']);
$client=$form->addField('autocomplete','studentid');
something simple, but nothing, I cannot get the autocomplete field, I ever get an error that say that "autocomplete.php" doesn't exist (actually the file doesn't exist and I try to download the github module, but either that module includes this file), anyway the error I get is:
Exception_PathFinder, code: 0
Additional information:
file: Form/Field/Autocomplete.php
type: php
attempted_locations:
0: /Library/WebServer/Documents/rutas/lib/Form/Field/Autocomplete.php
1: /Library/WebServer/Documents/rutas/atk4/lib/Form/Field/Autocomplete.php
2: /Library/WebServer/Documents/rutas/atk4-addons/mvc/Form/Field/Autocomplete.php
3: /Library/WebServer/Documents/rutas/atk4-addons/misc/lib/Form/Field/Autocomplete.php
class: Form_Field_Autocomplete
namespace:
orig_class: Form_Field_Autocomplete
/Library/WebServer/Documents/rutas/atk4/lib/PathFinder.php:207
Someone could help me please?
You're talking about this add-on, right: https://github.com/atk4/autocomplete?
Looks like issue with PathFinder unable to find appropriate location of namespaced addons.
Please post here part of your API_Frontend class where you add additional locations to pathfinder and also tell me something more about your folder structure (in which folder you have put autocomplete add-on files).
ATK 4.2.4 version is not last. Can you try to upgrade ATK to version 4.2.5? It's not officially released, but is available in GitHub master branch here: https://github.com/atk4/atk4?
I hope everything will work with 4.2.5 version but if not, then I'll help you solve this issue.
And one more thing - if you're creating form fields manually, then you need to set Model for that $client field. I guess it can be done with $client->setModel('Agenda');
EDIT: correct answer
In line
$client=$form->addField('autocomplete','studentid');
you should write full autocomplete field class name with namespace like this:
$client=$form->addField('autocomplete/Basic', 'studentid');
One more thing to note is to use lowercase function name. So instead of Set() use set().
I'm working on my own module. I realize I constantly need to manually type my module name in different places. Most popular usage is with drupal_get_path($type, $name) function (I have more then 10 of these in my code). Where $name is theme or module name. During that time I need to already change my module name 3 times. As you can surmise I also need change all module names hard-coded in my project. So I thought it would be nice to have some convenient function to grab this name automatically.
How can I get machine module name programmatically?
For example if you have your module in following directory..
sites/all/modules/my_module/
..then you can grab it in this way
drupal_get_current_module_name(); // return my_module
Generally, you should know by convention - if you have: sites/all/modules/my_module/ then the machine name of the module should match the folder name - my_module.
Virtually all contributed modules follow this convention, and you should too.
It is possible to have your .info and .module file not match the name of the folder, but this isn't correct.
If you are already executing code inside your module, you should already know the machine name of the module by virtue of the name of the file you're editing - unless you're trying to do something that I'm not understanding.
Edit: Since we've determined you're just trying to call your module's theme function, you don't actually need to know the name.
If you have:
/** Implements theme_table **/
function my_really_long_module_name_table() {}
Your function might get called like this:
theme('table');
There is a little more to it than that, but the theme engine will make a determination about which theme functions get called based on what is implementing them.
It sounds like you may want to read up on some of the basics of the Drupal theme system.
Here's a good start for learning the Drupal 6 theme layer: http://drupal.org/node/165706
I figure out something like this:
function get_current_module_name() {
return array_shift(explode('.', end(explode(DIRECTORY_SEPARATOR, __FILE__))));
}
but don't know is't the best way to do it..
UPDATE:
I see now it's better to use basename
$name = basename(__FILE__, '.module');
UPDATE 2:
I think if this is needed across whole module then it could be accessible via constant defined in the very beginning of the module e.g.:
define('MODULE_NAME', basename(__FILE__, '.module'));
Then you could use all the time in all your function like this:
drupal_get_path('module', MODULE_NAME);
Im currently trying to simply add a block to a custom Adminhtml module. i am able to display the content of the block but it renders right at the top of the page with a grey background, and then the standard magento layout with the design and menu renders directly underneath it.
im trying to do things in the correct fashion as to learn best practises and am following books and tutorials as well as the magento core but so far have been unable to add content correctly.
so far i have :
public function indexAction()
{
$this->loadLayout();
$this->_setTitle();
$main_block = new Invent_General_Block_Info();
echo $main_block->toHtml();
//$this->_addContent($main_block);
$this->renderLayout();
i can see the general way to do so in the Mage Core would be something like
/**
* Append customers block to content
*/
$this->_addContent(
$this->getLayout()->createBlock('adminhtml/customer', 'customer')
);
since i have already created the block $main_block it doesnt make sense to me to ->createBlock and so im not sure what to do from here.
any assistance is appreciated as usual. thanks!
I have found an answer that solved this problem.
of course it would come from Alan Storm. Thanks Alan. the thread is found here!
so to solve this, all i did was :
create a folder in app/design/adminhtml/mythemename/info.phtml
and then in my controller action i simply did :
$this->loadLayout();
$this->_setTitle();
$this->_addContent($this->getLayout()->createBlock('adminhtml/template')->setTemplate('shipment/info.phtml'));
$this->renderLayout();
and it works great.
Use this if its a static block you created through your CMS
/**
* Append customers block to content
*/
$this->_addContent(
$this->getLayout()
->createBlock('cms/block')
->setBlockId('{block_name}')
->toHtml()
);
I'm trying to create a widget within the module and then load that widget from 'outside' of the module. More particularly I'm using user module written by someone else. I don't want to have a separate page for displaying a login form, therefore I tried to make a CPortlet/widget (confusion) displaying the login form. Basically, I've moved the code from LoginController into that widget. Then I try to display the widget on some random page by
<?php $this->widget('user.components.LoginForm'); ?>
However, I get an error
CWebApplication does not have a method named "encrypting".
in UserIdentity class in this line:
else if(Yii::app()->controller->module->encrypting($this->password)!==$user->password)
This happens, because I'm basically trying to execute this code within context of the app and not the module. Thus the "Yii::app()->controller->module" trick doesn't really work as expected.
What am I doing wrong:-\
Is there a better way to achieve this. I.e. display that login form in some other page, which is normally displayed by accessing login controller within user module (user/login) or is a widget the right way of doing it?
Thanks.
The quick solution
Ok, so I simply ended up doing
Yii::app()->getModule('user')->encrypting($this->password)
instead of
Yii::app()->controller->module->encrypting($this->password)
Notice that now the module must be called 'user' in the main config, but I think this allows for more flexibility. I.e. we're not bound to only use module functionality within the module.
Additional insight on displaying widget outside of the module scope
After playing more with it that's what I did. In the UserModule.php I've created a method
public static function id() {
return 'user';
}
Then everywhere where I need the module I use
Yii::app()->getModule(UserModule::id())->encrypting($this->password)
I don't like having many imports related to the module like:
'application.modules.user.models.*',
'application.modules.user.components.*',
Because we already have those imports in the UserModule.php:
public function init()
{
// this method is called when the module is being created
// you may place code here to customize the module or the application
// import the module-level models and components
$this->setImport(array(
'user.models.*',
'user.components.*',
));
}
Therefore whenever you know that some piece of functionality will be used outside of the module it's important to make sure the module is loaded. For example, in the LoginForm widget that I am trying to display NOT in one of the module controllers, I have this line of code:
$model = new UserLogin;
However, UserLogin is a model inside of the User module, and in order to be able to autoload this model we first have to make sure the module was initialised:
$module = Yii::app()->getModule(UserModule::id());
$model = new UserLogin;
I hope this will be helpful if you were stuck with the whole modules concept the way I was.
http://www.yiiframework.com/forum/index.php?/topic/6449-access-another-modules-model/ was useful but hard to find =)
You better move that encrypting() into a MyUserIdentiy class which extends CUserIdentity. Whatever the code you take to use, they putting the method in controller is a bad idea and as a result you cannot reuse that code.
The login form should still post to User/Login controller but I guess they use Yii's standard login code and you might want to modify it to use the MyUserIdentity.