Dynamic function name in php - php

I would like to simplify the creation of "Custom Post Types" in WordPress as it is tedious to go through the same script and change all the custom post type name instances manually over and over.
It's quite simple to achieve by creating a variable containing the CPT name and use it everywhere it is needed. This way, All I have to do is declare the variable in the beginning of the script and that should take care of the rest.
The only issue is that, to make it work, I also need to prefix the CPT name in front of every function inside the script and it seems that using a variable in a function name is not easy or even recommended in PHP.
So how could I solve this?
Here is an example below to make it clear:
$prefix = 'news';
function news_custom_type_init()
{
global $prefix;
register_post_type($prefix, array(
'labels' => array(
'name' => $prefix,
'singular_label' => $prefix,
'add_new' => 'Add',
...
));
register_taxonomy_for_object_type( 'category', $prefix );
}
add_action('init', $prefix.'_custom_type_init');
This is almost fine and could be standardized if only I could dynamically rename the function in order not to have to write the word "news" in front of it but use the "$prefix" instead.
This could have been nice but just doesn't work:
$prefix = 'news';
$functionName= $prefix."_custom_type_init";
function $functionName()
{
global $prefix;
register_post_type($prefix, array(
'labels' => array(
'name' => $prefix,
'singular_label' => $prefix,
'add_new' => 'Add',
...
));
register_taxonomy_for_object_type( 'category', $prefix );
}
add_action('init', $prefix.'_custom_type_init');
Having to name manually the function kinda defeat the original purpose of my attempt (especially when the script embeds dozens of functions like this one).
What would be the best way to do this?
PS: I googled and "stackoverflowed" a lot about this but didn't find any working solution that fit my needs and doesn't generate a WordPress error message.
Thank you.

Simple enough, here's a similar snipped form a project:
$function = $prefix . '_custom_type_init';
if(function_exists($function)) {
$function();
}

This is an old thread but simply use anonymous functions:
add_action('init', function() use($args) {
//...
});
Then there is no need to declare so many functions.

Edit (2017-04): Anonymous functions (properly implemented) are the way to go, see answer by David Vielhuber.
This answer is ill advised, as is any approach that involves code as a string, because this invites (among other things) concatenation.
Im not sure if it is advisable to use, or if it helps you, but php allows you to create "anonymous" functions :
function generateFunction ($prefix) {
$funcname = create_function(
'/* comma separated args here */',
'/* insert code as string here, using $prefix as you please */'
);
return $funcname;
}
$func= generateFunction ("news_custom_type_init");
$func(); // runs generated function
I am assuming add_action just calls whatever function you passed.
http://php.net/manual/en/function.create-function.php
Note: create_function will not return a function with the name you want, but the contents of the function will be under your control, and the real name of the function is not important.

I think you could use
runkit_function_add
http://php.net/manual/pl/function.runkit-function-add.php
One other available method is to use eval()

This post is old, but PHP 7 may solve this question.
Try:
$prefix = 'news';
$functionName = $prefix . "_custom_type_init";
${$functionName} = function() use ($prefix) {
register_post_type($prefix, array(
'labels' => array(
'name' => $prefix,
'singular_label' => $prefix,
'add_new' => 'Add'
)
);
register_taxonomy_for_object_type( 'category', $prefix );
};
add_action('init', '$' . $functionName);
I think it should work for WordPress.

You can use string in brackets
("function_name_{$dynamic_var}")()

I'm not sure any of the above actually answer the question about dynamically creating custom post types. This works for me though:
$languages = ("English", "Spanish", "French");
foreach($languages as $language):
$example = function () use ($language) {
$labels = array(
'name' => __( $language . ' Posts' ),
'singular_name' => __( $language . ' Post' )
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
"rewrite" => array( "slug" => $language . "_posts", "with_front" => true ),
'capability_type' => 'page',
);
register_post_type( $language . "_posts", $args );
};
add_action( 'init', $example, 0 );
endforeach;

Dynamic function named in PHP as variable functions
https://www.php.net/manual/en/functions.variable-functions.php
as example
$functionName = function () {
global $prefix;
register_post_type($prefix, array(
'labels' => array(
'name' => $prefix,
'singular_label' => $prefix,
'add_new' => 'Add',
...
));
register_taxonomy_for_object_type( 'category', $prefix );
}
you can call it by typing $functionName()

I was also looking for a way to do this, as I wanted to create a function that could make aliases for functions, just like in ruby. e.g.
function an_insanely_long_function_name($a, $b) {
// do something with $a and $b
}
// I'll go insane if I have to type that stupidly long function name every time 😵
// Aliases to the rescue :)
define_alias('shrt_nm', 'an_insanely_long_function_name');
shrt_nm('a', 'b');
I did quite a lot of research — for like 2 mins :p — and found nothing that could help me achieve that functionality.
I was about to give up and do it all manually, but then I remembered good old "eval", my long time buddy :).
Here's what you need to do:
function define_alias($alias, $function) {
if (function_exists($alias))
throw new \Exception('A function named ' . $alias . ' already exists!');
// create the function
eval("function $alias(...\$args) { $function(...\$args); }")
}

eval() is the simpliest method
https://www.php.net/manual/en/function.eval.php
$name='new_func';
$var = eval($name."();");
function new_func(){echo "It work";}

Related

update plugin via code

is it somehow possible to update a wordpress-plugin via another plugin with php code?
i tried something like this
$request = wp_remote_post(
'http://wordpress2/wp-admin/admin-ajax.php',
array(
'body' => array(
'plugin' => 'hello-dolly/hello.php',
'slug' => 'hello-dolly',
'action' => 'update-plugin',
'_ajax_nonce' => wp_create_nonce( 'nonce-test' ),
)
));
but this only leads in a 400 status...
I thought this kind of stuff would be easy in wordpress, dumb me! :-D
Found a solution:
after all plugins are loaded add a filter which define to auto-update plugins
add_action( 'plugins_loaded', array( CLASS, 'abpr_plugins_loaded' ), 1 );
public static function abpr_plugins_loaded(){
add_filter( 'auto_update_plugin', '__return_true');
}
the define some function which will be triggered from something, in my case it is an custom api-url which calls this:
public static function update_all_defined_plugins($data){
set_site_transient( 'update_plugins', '' );
wp_maybe_auto_update(); }
keep in mind that this is some bare stuff here without any code- & results-checking

Drupal : Create variable from custom .module to custom .tpl.php

I create a custom module and I want use the complete_url of my future website in the template who used/created by my module.
I tried several ways and searched Google but I don't find a solution.
However this issue seems very simply, that became me crazy x)
So, I must create a variable in my .module and add her when I return the array in the main_socialtag_theme function. Where/How can I do that ?
My .module:
function main_socialtag_block_info(){
$block['main_socialtag']=array(
'info' => t('Main socialtag'),
'cache' => DRUPAL_NO_CACHE,
);
return $block;
}
function main_socialtag_theme(){
return array(
'main_socialtag_block' => array(
'template' => 'theme/main_socialtag_block',
'variables' => array(),
),
);
}
function main_socialtag_block_view($delta=''){
if ($delta == 'main_socialtag'){
return array(
'subject' => '',
'content' => array(
'#theme' => 'main_socialtag_block',
)
);
}
}
Thanks for help, and sorry for my bad english writing !
If you are looking for a way to add, modify and call variables. Check variable_get and variable_set.
To add or modify a variable value:
variable_set("my_variable_name", "value");
To retrieve the value:
$myVal = variable_get("my_variable_name", "");
For hook_theme Implementation, kindly check this question.

syntax error, unexpected T_FUNCTION on "use" operator [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I use PHP closure function like function() use() on PHP 5.2 version?
I'm trying to run this on a server that's running php 5.2.
function add_post_type($name, $args = array() ) {
add_action('init',function() use($name, $args) {
// execute custom post type code here
});
};
The 2nd line is throwing an unexpected T_FUNCTION error, I suspect its cause of the "use" operator. Can someone help point me as to how I can rewrite this function to run in php 5.2?
See this function:-
/* Add Post Type */
function wpse54191_plugin_init() {
add_post_type('Netherlands', array(
'supports' => array('title', 'editor', 'thumbnail', 'comments')
));
}
add_action('init', 'wpse54191_plugin_init');
/* Add Post Type */
function add_post_type($name, $args = array() ) {
if ( !isset($name) ) return;
$name = strtolower(str_replace(' ', '_', $name));
$args = array_merge(
array(
'label' => 'Members ' . ucwords($name) . '',
'labels' => array('add_new_item' => "Add New $name"),
'singular_name' => $name,
'public' => true,
'supports' => array('title', 'editor', 'comments'),
),
$args
);
register_post_type( $name, $args);
}
This answer seems to provide a good solution for what you're trying to do in PHP 5.2: converting anonymous functions to user-defined functions.
Converting Code with Anonymous functions to PHP 5.2
Good luck! And try and upgrade your PHP version :P

How can I use PHP closure function like function() use() on PHP 5.2 version?

How can I use PHP closure function like function() use() on PHP 5.2 version as it has no support for anonymous functions?
Currently my code is something like below
$this->init(function() use($taxonomy_name, $plural, $post_type_name, $options)
{
// Override defaults with user provided options
$options = array_merge(
array(
"hierarchical" => false,
"label" => $taxonomy_name,
"singular_label" => $plural,
"show_ui" => true,
"query_var" => true,
"rewrite" => array("slug" => strtolower($taxonomy_name))
), $options
);
// name of taxonomy, associated post type, options
register_taxonomy(strtolower($taxonomy_name), $post_type_name, $options);
});
Php supports anonymous functions since 5.3.0, read about it in manual.
You could use create_function but you should avoid this (for example because of this comment) and it's practically the same as eval... One bad enclosure and you'll make your sources vulnerable. It's also evaluted on runtime, not on compilation time what can decrease performance and may cause fatal error in the middle of included file.
Rather declare that function somewhere, it'll be more effective.
I assume you are asking for the 'use' directive due to the early value bindings, right?
You could use 'create function' and insert there some static variables with the values you have at the creation time, for example
$code = '
static $taxonomy_name = "'.$taxonomy_name.'";
static $plural = "'.$plural.'";
static $post_type_name = "'.$post_type_name.'";
static $options = json_decode("'.json_encode($options).'");
$options = array_merge(
array(
"hierarchical" => false,
"label" => $taxonomy_name,
"singular_label" => $plural,
"show_ui" => true,
"query_var" => true,
"rewrite" => array("slug" => strtolower($taxonomy_name))
),
$options
);
// name of taxonomy, associated post type, options
register_taxonomy(strtolower($taxonomy_name), $post_type_name, $options);
';
$func = create_function('', $code);
Something like that should do:
$this->init(create_function('','
$taxonomy_name = '.var_export($taxonomy_name,TRUE).';
$plural = '.var_export($plural,TRUE).';
$post_type_name = '.var_export($post_type_name,TRUE).';
$options = '.var_export($options,TRUE).';
$options = array_merge(
array(
"hierarchical" => false,
"label" => $taxonomy_name,
"singular_label" => $plural,
"show_ui" => true,
"query_var" => true,
"rewrite" => array("slug" => strtolower($taxonomy_name))
), $options
);
// name of taxonomy, associated post type, options
register_taxonomy(strtolower($taxonomy_name), $post_type_name, $options);
'));

Zend Framework Form Irrational Behaviour

Let's start this off with a short code snippet I will use to demonstrate my opinion:
$title = new Zend_Form_Element_Text('title', array(
'label' => 'Title',
'required' => false,
'filters' => array(
'StringTrim',
'HtmlEntities'
),
'validators' => array(
array('StringLength', false, array(3, 100))
),
));
This important line is:
'required' => false,
Which means that the input field is not required and you can submit the form without filling it. However, this also means that any filters and validators won't apply to it if you choose to fill in this field.
Common sense tells me that is an irrational behavior. The way I understand the word 'required' in relation with HTML input fields: an input field that is not required should return NULL if it is not filled in but if user decides to fill it both filters and validators should apply to it. That's what makes sense to me. Do you agree with me or is my common sense not so common?
Now more practical question, because this is how Zend_Form behaves, how can I achieve not required fields which would work as I described above (if nothing is typed in by user it returns NULL otherwise filters and validators normally apply).
Not really a complete answer to your question, but since comments don't have syntax formatting; here's a filter you can use to make your field values null if empty.
class My_Filter_NullIfEmpty implements Zend_Filter_Interface
{
public function filter( $value )
{
// maybe you need to expand the conditions here
if( 0 == strlen( $value ) )
{
return null;
}
return $value;
}
}
About the required part:
I'm not sure really. You could try to search the ZF mailinglists on Nabble:
http://www.nabble.com/Zend-Framework-Community-f16154.html
Or subscribe to their mailinglist, and ask them the question. Either through Nabble, or directly via the addresses on framework.zend.com:
http://tinyurl.com/y4f9lz
Edit:
Ok, so now I've done some tests myself, cause what you said all sounded counter intuitive to me. Your example works fine with me. This is what I've used:
<?php
class Form extends Zend_Form
{
public function init()
{
$title = new Zend_Form_Element_Text('title', array(
'label' => 'Title',
'required' => false,
'filters' => array(
'StringTrim',
'HtmlEntities',
'NullIfEmpty' // be sure this one is available
),
'validators' => array(
array('StringLength', false, array(3, 100))
),
));
$this->addElement( $title );
}
}
$form = new Form();
$postValues = array( 'title' => '' ); // or
$postValues = array( 'title' => ' ' ); // or
$postValues = array( 'title' => 'ab' ); // or
$postValues = array( 'title' => ' ab ' ); // or
$postValues = array( 'title' => '<abc>' ); // all work perfectly fine with me
// validate the form (which automatically sets the values in the form object)
if( $form->isValid( $postValues ) )
{
// retrieve the relevant value
var_dump( $form->getValue( 'title' ) );
}
else
{
echo 'form invalid';
}
?>
Actually, what you describe as your expectations are exactly how Zend_Form works. If you mark the element as not required, then the following happens: (a) if no value is passed, it skips validation, but if (b) a value is passed, then it must pass all validators in order to be valid.
BTW, best place to ask ZF questions is on the ZF mailing lists: http://framework.zend.com/archives

Categories