Global variable is not working between functions - wordpress

i am creating plugin for my project. i want to create one page when plugin gets activate and same way i want to delete that page when plugin gets deactivate... i am able to create page but i am facing problem while deleting page...
my code is
global $page_id;
register_activation_hook(__FILE__,'createPage');
register_deactivation_hook(__FILE__, 'dropPage');
function createPage()
{
global $page_id;
$page['post_type'] = 'page';
$page['post_content'] = 'hello this page created by plugin';
$page['post_status'] = 'publish';
$page['post_title'] = 'dpage';
$page_id = wp_insert_post ($page);
}
function dropPage()
{
global $page_id;
wp_delete_page($page_id);
}
it's not deleting page... if i give wp_delete_post('116') then it's working fine... i have assigning page id in global variable then also i am not able to retrieve it..
can any one suggest me how to do it?
Thanks in advance

the global $page_id you're adding will only contain the page ID when you're activating the plugin. To store the page ID, use the Options API.
register_activation_hook(__FILE__,'createPage');
register_deactivation_hook(__FILE__, 'dropPage');
function createPage()
{
$page['post_type'] = 'page';
$page['post_content'] = 'hello this page created by plugin';
$page['post_status'] = 'publish';
$page['post_title'] = 'dpage';
$page_id = wp_insert_post ($page);
update_option('the_page_id_i_created', $page_id );
}
function dropPage()
{
if( get_option('the_page_id_i_created') ){
wp_delete_page( get_option('the_page_id_i_created') );
}
}

Related

Override wordpress routing / url rewriting?

I would like to serve different content based on the URL.
I started with a custom page setup via a custom template but I am open to something else.
The main goal is to have one PHP page that can serve different contents programmatically based on the URL.
For example:
https://some-url.com/my-plugin/ -> run my page
https://some-url.com/my-plugin/foo/ -> run my page
https://some-url.com/my-plugin/foo2/abc/ -> run my page
etc...
I have been looking at add_rewrite_rule, add_rewrite_tag, flush_rewrite_rules and WP_Rewrite API but I am getting confused about which one I should use?
I found an example here but I could not make it work, I get 404s, any idea why?:
/*
Plugin Name: Products Plugin
Plugin URI: http://clivern.com/
Description: Register URL rules for our products
Version: 1.0
Author: Clivern
Author URI: http://clivern.com
License: MIT
*/
function products_plugin_activate() {
products_plugin_rules();
flush_rewrite_rules();
}
function products_plugin_deactivate() {
flush_rewrite_rules();
}
function products_plugin_rules() {
add_rewrite_rule('products/?([^/]*)', 'index.php?pagename=products&product_id=$matches[1]', 'top');
}
function products_plugin_query_vars($vars) {
$vars[] = 'product_id';
return $vars;
}
function products_plugin_display() {
$products_page = get_query_var('pagename');
$product_id = get_query_var('product_id');
if ('products' == $products_page && '' == $product_id):
//show all products
exit;
elseif ('products' == $products_page && '' != $product_id):
//show product page
exit;
endif;
}
//register activation function
register_activation_hook(__FILE__, 'products_plugin_activate');
//register deactivation function
register_deactivation_hook(__FILE__, 'products_plugin_deactivate');
//add rewrite rules in case another plugin flushes rules
add_action('init', 'products_plugin_rules');
//add plugin query vars (product_id) to wordpress
add_filter('query_vars', 'products_plugin_query_vars');
//register plugin custom pages display
add_filter('template_redirect', 'products_plugin_display');
First of all, make sure your pretty permalinks are enabled, in this case the option "Plain" in Settings - Permalinks should be unselected:
Select one of these options to enable pretty permalinks
You can check whether pretty permalinks are enabled in the code like so:
function is_enabled_pretty_permalinks() {
return !empty( get_option( 'permalink_structure' ) );
}
if ( is_enabled_pretty_permalinks() ) {
echo 'Pretty permalinks enabled';
}
Next add a new rewrite rule:
function add_my_rewrite_rule() {
$page_slug = 'products'; // slug of the page you want to be shown to
$param = 'do'; // param name you want to handle on the page
add_rewrite_rule('my-plugin/?([^/]*)', 'index.php?pagename=' . $page_slug . '&' . $param . '=$matches[1]', 'top');
}
add_action('init', 'add_my_rewrite_rule');
Add your parameter to query vars so you will be able to handle it on the page:
function add_my_query_vars($vars) {
$vars[] = 'do'; // param name you want to handle on the page
return $vars;
}
add_filter('query_vars', 'add_my_query_vars');
Then you can access your query var do in the page template or in a shortcode, for example:
function my_plugin_shortcode_handler( $atts ){
$do = get_query_var( 'do' );
if ( $do === 'this' ) {
return 'do this';
} else {
return 'do that';
}
}
add_shortcode( 'myshortcode', 'my_plugin_shortcode_handler' );
Then place the shortcode to the content via Gutenberg.
Check out the links:
https://some-url.com/my-plugin/this/ - outputs "do this"
https://some-url.com/my-plugin/that/ - outputs "do that".
This can be solved by using query params. Like you mentioned you have set up custom page via a custom template. You can read the URL and check for the parameters and based on that you can send data from the PHP template page.
e.g,
function cleanTheInput($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
$data = htmlentities($data);
return $data;
}
if (isset($_GET['page_url'])) {
$theUrl = cleanTheInput($_GET['page_url']);
}
if($theUrl == 266)){
// data for https://some-url.com/?page_url=266
}
if($theUrl == 366)){
// data for https://some-url.com/?page_url=366
}

Hook to run after removing a user

I have a function where I duplicate a user to all subsite when they registered.
I achieved that by doing this:
function sync_user( $user_id )
{
$list_ids = get_sites();
$current_site = get_current_site();
$info = get_userdata($user_id);
foreach( $list_ids as $list )
{
if ( $list->blog_id != $current_site->id )
{
add_user_to_blog($list->id, $info->ID, 'subscriber');
}
}
// quick fix for: above somehow doesn't add to main site. add to main site here.
add_user_to_blog(1, $info->ID, 'subscriber');
}
Now, I want to "unsyc" the user when I removed the user from the site. I tried to hook it by using 'remove_user_from_blog', but it caused infinite loop.
Where can I hook the following code so that I can remove all those users that I added previously using above code?
function unsync_user( $user_id )
{
$list_ids = get_sites();
foreach( $list_ids as $list )
{
remove_user_from_blog( $user_id, $list->ID );
}
}
edited the title for clarity
AbdulRahman was correct about that. When user click 'remove' from the user list, the action not fire 'delete_user' or 'deleted_user' hook. I tested it.
I think it is tricky. So, here is how to add custom removed_user action. Add these lines below into your plugin.
add_action('remove_user_from_blog', function($user_id, $blog_id) {
// checking current action
// refer: wp-admin/users.php:99
$wp_list_table = _get_list_table( 'WP_Users_List_Table' );
if( $wp_list_table->current_action() != 'doremove' ) {
return; // only proceed for specific user list action
}
$fire_removed_user_hook = null; // closure reference
$fire_removed_user_hook = function() use ($user_id, $blog_id, &$fire_removed_user_hook) {
do_action( 'removed_user', $user_id, $blog_id );
// remove the hook back
remove_action('switch_blog', $fire_removed_user_hook);
};
// restore_current_blog called at the last line in the remove_user_from_blog function
// so action switch_blog fired
add_action('switch_blog', $fire_removed_user_hook);
}, 10, 2);
add_action('removed_user', function($user_id, $blog_id) {
// the user removed from be blog at this point
}, 10, 2);
The hook "deleted_user" runs after a user is deleted ("delete_user" runs before the deletion occurs):
https://codex.wordpress.org/Plugin_API/Action_Reference/deleted_user

Admin-side hooks don't work (WordPress)

I want to send an email whenever a file is attached to a certain CPT, however I can't make add_attachment hook work. In fact I can't seem to make any dashboard hook (such as post_updated) work. The code below does nothing whenever a file is attached to a post or post gets updated:
add_action( 'add_attachment', 'goldorak' );
add_action( 'post_updated', 'goldorak' );
function goldorak() {
echo 'Fired!';
echo "<script>alert('Fired!');</script>";
}
Note: my attachment is a file field created with Advanced Custom Fields plugin.
I am not sure ACF fires the same actions as the normal wordpress. Here is the ACF version of your code:
add_action( 'acf/save_post', 'goldorak', 15 ); // The saving is done with priority 10, so 15 is after the save to DB, 5 before it.
function goldorak() {
die('test');
}
But in your case, the hook acf/update_value/type=file would simplify your task:
add_action('acf/update_value', 'acf_hook_update_value', 1, 3);
function acf_hook_update_value($new_value, $post_id, $field_options) {
$key = $field_options['key']; // internal key name
$name = $field_options['name']; // pretty name
$old_value = get_field($key, $this->post_id, false);
$new_value = stripslashes($new_value);
if ($new_value != $old_value) {
die('test'); // Do something ...
}
}

How to edit a post dynamically in wordpress plugin

I have created a small wordpress plugin that displays a list of people in a page via shortcode.
When the user clicks on one of the names from the list, a query_var gets set and my plugin catches the $_GET with the specific id of the person the user just clicked. All very well until now.
My problem is that now I want to display a page with the details (for the clicked element) but I dont seem to be able to edit the content or post that gets to the page and it returns me to the page with the list of people.
My question is how do I edit the post? I have tried adding a add_filter('the_content','my_func') to this, but this does not work since this hook is probably already passed.
I can access the post directly via get_content() or get_post(), but I dont seem to be able to make the page populated new data.
In other words... this does nore seem to work
$fid = $_GET['fid'];
global $wpdb;
$sql = "select * from fighters where fighter_id = {$fid} limit 1";
$fighter = $wpdb->get_row($sql);
$html = $this->_getFighterPageLayout($fighter);
$post = get_post();
$post->post_content = $html;
$post->title = 'test';
$post->private = false;
// or even just global $content = $html;
What am I doing wrong and what ways do I have to edit/update the content/post?
You have to use the hooks of Wordpress to update the content. This works with the add_filter function
Try something like this, it should works
function mytheme_content_filter( $content ) {
// Do stuff to $content, which contains the_content()
// Then return it
return $content;
}
add_filter( 'the_content', 'mytheme_content_filter' );

Date-based archives for custom post_types (wordpress 3.0)

If I have a custom post type named 'my_type', how can I get Wordpress to make date-based archives, for example:
mysite.com/my_type/2010/
mysite.com/my_type/2010/07/
mysite.com/my_type/2010/07/28/
I'm looking for tips both on creating the rewrite rules and on linking the urls to templates.
Thanks!
Update:
I've tried the following in my functions.php (EVENT_TYPE_SLUG is a constant defined elsewhere):
function event_rewrite_rules() {
global $wp_rewrite;
$new_rules = array(
EVENT_TYPE_SLUG."/([0-9]{4})/([0-9]{1,2})/$" => 'index.php?post_type=event&year='.$wp_rewrite->preg_index(1).'&monthnum='.$wp_rewrite->preg_index(2),
EVENT_TYPE_SLUG."/([0-9]{4})/$" => 'index.php?post_type=event&year='.$wp_rewrite->preg_index(1),
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'event_rewrite_rules');
the rewrite rules show up in $wp_rewrite-> rules, but when I navigate to those pages I get a 404 error. If I manually navigate to mysite.com/index.php?post_type=event&year=2010, I get redirected to mysite.com/2010?post_type=event
Benj I think WordPress automatically creates archives for custom post type
OK ... took some time but I figured this out (there may be more elegant solutions out there).
1) Create a standard wordpress page to serve as the archive page (and to give me access to the template). I defined the page's slug as a constant (EVENT_ARCHIVE_BASE) so that it's just hard-coded in one place and referenced everywhere else.
2) Make custom rewrite rules that catch that page's urls and redirect them to the page:
function event_date_queryvars($qvars) {
array_push($qvars, 'eyear', 'emonth');
return $qvars;
}
add_filter('query_vars', 'event_date_queryvars');
function event_date_rewrite_rules() {
// Adds rewrite rules for date-based event archives
global $wp_rewrite;
$new_rules = array(
EVENT_ARCHIVE_BASE."/([0-9]{4})/([0-9]{1,2})/?$" =>
"index.php?pagename=".EVENT_ARCHIVE_BASE."&eyear=".$wp_rewrite->preg_index(1)."&emonth=".$wp_rewrite->preg_index(2),
EVENT_ARCHIVE_BASE."/([0-9]{4})/?$" => "index.php?pagename=".EVENT_ARCHIVE_BASE."&eyear=".$wp_rewrite->preg_index(1),
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'event_date_rewrite_rules');
3) At the top of my page template, I check for the custom query vars and build the page accordingly. (I should have been able to use the built-in year and monthnum, but couldn't get them to work properly. Future troubleshooting):
// Was the page called with a specific year, month, or just plain?
$year = get_query_var('eyear');
$monthnum = sprintf('%02d', get_query_var('emonth'));
if ($monthnum) {
$list_type = 'Month';
$monthname = $month[$monthnum];
$heading = "Events from $monthname, $year";
} elseif ($year) {
$list_type = 'Year';
$heading = "Events from $year";
} else {
$list_type = 'AllPast';
$heading = get_the_title();
}
Thanks for the help, and hope this is useful for someone else! Let me know if you have a simpler/built-in way to do this.
I managed to find a more elegant/built-in solution.
The trick is in the "post_type=article" parameter.
If you create a rewrite like so:
'(articles)/([0-9]{4})' => 'index.php?post_type=article&eyear=' . $wp_rewrite->preg_index(2)
This will then keep your URL structure, but go through the default 'archive' template.
Then you steal the template away from the default to your own archive template. (for instance 'archive-articles.php')
This function accomplishes this (works for me):
add_action("template_redirect", 'my_template_redirect');
// Template selection
function my_template_redirect()
{
global $wp;
global $wp_query;
if ($wp->query_vars["post_type"] == "article")
{
if (have_posts())
{
include(TEMPLATEPATH . '/archive-articles.php');
die();
}
else
{
$wp_query->is_404 = true;
}
}
}
You'll still need to create your own methods to handle the get_query_var()'s for the year/month/day, but at least you don't need to create a custom page template.

Resources