How can you safely add a dependency to a Drupal module? - drupal-6

I have a new version of a Drupal 6 module. In the new version, I have added a new dependency in the .info file to a views utility module I've created called lib_views.
However, lib_views may not be enabled when my module is upgraded. If it's not, then upgrading my module causes an irretrievable crash, because views fires a hook that invokes a function in my un-enabled lib_views module.
Is there any safe way to add a new dependency to an existing Drupal module that can prevent this?

You can force drupal to load the module (it's common practice for CCK modules for example).
Example:
function example_install() {
drupal_load('module', 'content');
content_notify('install', 'example');
}
In the example, drupal_load loads the "content" module first, then content_notify is an example of function that can only be used when the content module is available.
So if the drupal_load call returns FALSE, you can detect that the module is missing and notify the user.

Drupal 7 handles this automatically when going to update.php (which you are suppose to visit after updating a module). I suppose another alternative would be to display a warning message via an update function.

Related

How to insert module into product page in prestashop

I am creating a new module in Prestashop 1.6 which displays some data on the products page in the info box. I have created a new hook in the install method of the module like this: $this->registerHook('combinationDescription') and created the hookDisplayCombinationDescription function for assigning some smarty variables and displaying them with a tpl file.
After installing my module the hook is registered into the database so its usable.
Manually I can insert code into the product.tpl file just like: {hook h="hookDisplayCombinationDescription"} and I think it's working, but I would like to make this step automatically when the module gets installed. How can I do that?
My guess would be that to edit the product.tpl file from the install method of the module but it's a bit dirty method for me. Is there some other nice way to do that?
If you made a custom hook you need to insert its execution somewhere manually: into .tpl or into overrided ProductController.php (if it is an action hook). Prestashop can't execute it automatically for it doesn't know where do you want to execute it.
But you can use the default Prestashop 1.6 hooks to make your part of the code hooked and ready after the module installation. For the product page are these:
displayLeftColumnProduct
displayRightColumnProduct
displayProductTab
displayProductTabContent
displayFooterProduct
displayProductButtons
displayProductPriceBlock
actionProductOutOfStock
You can use one of these hooks and position your content with css (or javascript - to any part of the page).
If you make any custom hook then you have to make it executable first.Prestashop can't execute custom hooks automatically.But for displaying some data on product page you can use predefined prestashop hooks.Some are following
displayProductButtons
displayProductTab
To use these hooks, first you have to register hooks in install function like
public function install()
{
if (!parent::install() || !$this->registerHook('displayProductButtons')){
}
}
and in the same file you have to make a function like
public function hookDisplayProductButtons($params)
{
}
Now in that function you can assign some smarty variables which you want to access or show in your tpl file like
public function hookDisplayProductButtons($params)
{
$this->smarty->assign(array(
'product_name' => 'abc'
));
}
Now in your tpl file you can access that
If you want to add new custom hook and execute them when your particular module is active or installed.
Please follow the following steps:
Add you new custom hook code any where you want to perform your action.
Then, you can insert entry for that new custom hook into database at the time of installing module.
Now, your hook will execute as per your need.
Delete the same entry of hook from database at the time of uninstalling module so that hook could not be executed after uninstalling module.
I am not sure for, Is any other solution available to fulfill your need in prestashop?

What is the best way to configure an AMD/Require.js module before it is loaded into other modules?

Currently I am using Marionette which registers itself as an AMD module called "marionette". Before it gets loaded into other modules, I want to set some configurations on it. My only thought as of now is to do this:
// configuredMarionette.js
define(["marionette"], function(Marionette) {
// modify Marionette here
return Marionette;
});
Then, in each of my modules that need marionette, I set "configuredMarionette" as the dependency instead of "marionette" so that I get the configured version. Is there any other way around this that is cleaner?
It may be more useful if you rename 'configuredMarionette' to 'marionette' and use 'orignalMarionette' for original one.
It will be easy to use any other module which has a dependency to 'marionette' to use configured one.

RequireJS Multi Injecting

I am building a modular single page application which consumes multiple require config files from different sources. I would like a way in my application to be able to consume a list of all modules of a specific type. something like this:
define('module-type/an-implementation',...)
define('module-type/another-implementation',...)
require('module-type/*', function(modules){
$.each(modules,function(m){ m.doStuff(); });
})
This is similar patterns dependency injectors use with multiple dependency injection (eg. https://github.com/ninject/ninject/wiki/Multi-injection)
Is there a way to do this (or something similar) with require?
RequireJS doesn't know which modules exist until something requires them. Once a module is required / depended upon RequireJS will figure out where to request the module from based on module's name and RequireJS's configuration. Once the module is loaded it can be examined / executed to find out its dependencies and handle them in turn, until all dependencies are loaded and all module bodies are executed.
In order to be able to "consume a list of all modules of a specific type" something would need to be able to find all such modules. RequireJS doesn't have any means to know which modules exist, so it alone wouldn't be enough to implement "Multi Injection".
Speculation
Some kind of module registry could be created and populated with help of the build system: e.g. a file (say module-registry.js) could be generated each time a file in the source directory is added / removed or renamed, then multi inject could be possible like:
multiRequire('module-type/*', function(modules){
$.each(modules,function(m){ m.doStuff(); });
})
which in turn would call
require(findModules(pattern), function() {
callback(Array.prototype.slice.call(arguments, 0));
});
(where multiRequire and findModules are provided by the module registry).

What is the use of module.parent in node.js? How can I refer to the require()ing module?

I was looking in the node.js module documentation, and noticed that each module has a property- module.parent. I tried to use it, but got burnt by the module caching- module.parent only ever seems to the module that first require()'d it, irrespective of current context.
So what is the usage of it? Is there any other way for me to get a reference to the current require()ing module? Right now I'm wrapping the module in a function, so that it is called like:
require("mylibrary")(module)
but that seems sub-optimal.
The "parent" is the module that caused the script to be interpreted (and cached), if any:
// $ node foo.js
console.log(module.parent); // `null`
// require('./foo')
console.log(module.parent); // `{ ... }`
What you're expecting is the "caller," which Node doesn't retain for you. For that, you'll need the exported function you're currently using to be a closure for the value.
There is a workaround for this. Node adds a module to the module cache before it finishes loading it. This means that a module can delete itself from the module cache while it's loading! Then every time the module is require'd a new instance of the module is loaded.
Magic.js
console.log('Required by ' + module.parent.filename);
delete require.cache[__filename];
Module1.js
//prints "Required by Module1.js"
require('./Magic');
Module2.js
//prints "Required by Module2.js"
require('./Magic');
Of course the side-effect of this is that your module is no longer a singleton, so you have to code Magic.js with that in mind. If you need to store global data you can always keep it in a require()'ed module that doesn't delete itself from the cache.
Update for 2022
Note the technique described above doesn't work for ES Modules included with import. As far as I know there is no good way to detect the importing ES Module.

Declaring function in Blocks in Drupal 6

I am facing an issue in declaring a fucation in block which I have added . I am calling a function by including an file which ia placed in the theme. I have also tried it by placing out of the theme folder. The function is alredy being user in front page. But when I am using the same function in that block. The screen gets blank and nothing displays. some part of my block coding is written below. Please help me.
<?php
global $base_url;
include($_SERVER['DOCUMENT_ROOT']."/travellar/geoiploc.php"); // indluded file
$ip = "203.189.25.0"; // Australia IP test
$country_code = getCountryFromIP($ip, "code");
I've had no problems loading functions from modules into custom blocks, but I've never tried loading one from a theme before. It's not clear to me whether or not theme functions are loaded before the page content is loaded.
You might have to create a custom module or include file to hold the function. Check out the module_load_include() function for how to load a specific include file.
A custom module would be a good approach as it is loaded before the theme layer and can be accessed from almost anywhere in Drupal except other modules with a lower weight than the custom module. It is also likely to come in handy for hooks and other overrides.
However, if you must have it in the theme layer, another option is adding it to template.php of your theme which should make it available within page.tpl.php and such, but not blocks I don't believe.
/sites/all/modules/mymodule/mymodule.info
name = My Module
package = !
description = It is MY module, not yours!
core = 6.x
The package "!" will make this module appear at the top of the modules page
/sites/all/modules/mymodule/mymodule.module
<?php
// Load mymodule.morePHP.inc
module_load_include('inc', 'mymodule', 'mymodule.morePHP');
// A custom function
function mymodule_my_custom_function($args) {
/* do custom stuff here */
return 'output';
}
/sites/all/modules/mymodule/mymodule.morePHP.inc
<?php
// An included custom function
function mymodule_other_custom_stuff() {
}

Resources