Plugin: To do list nella dashboard di wordpress

L’idea di questo mini plugin è quella di avere uno spazio nella dashboard per poter annotare delle cose senza usare le funzioni di base di wordpress, ma facendo si che il plugin crei una tabella nel database al momento della attivazione.

Importante: Questo plugin non è completo, è soltanto un esempio e non è stato testato completamente

Il principio di questo plugin è una “To do list” semplice, con la possibilità soltanto di inserire e cancellare gli elementi che ogni utente ha, senza poter vedere quelli degli altri utenti di wordpress.

La prima funzione “ToDoList_Installation_Function”, usando l’hook “activated_plugin”, esegue il codice per creare la tabella nel database sql. Questa tabella che l’ho chiamata “to_do_list” gli viene aggiunto il prefisso del sito di wordpress in cui verrà installata usando “$wpdb->prefix”. La tabella è molto semplice, una chiave primaria, un campo testo e un id_utente, che ha come tipo BIGINT perchè il database di wordpress usa questo formato nella tabella utenti di wordpress. (Link allo schema).

La funzione “my_custom_dashboard_widgets_for_todolist”, attraverso l’hook “wp_dashboard_setup” crea un dashboard widget e chiama la funzione che da l’output del widget che è “custom_dashboard_help_for_todolist”. All’inizio per fare qualche test con il database avevo creato la funzione “custom_dashboard_help_for_todolist_old”, ma quello che volevo andare a fare era usare Ajax per fare le richieste in modo da non dover aggiornare ogni volta la pagina.

Da qui ho scoperto che wordpress ha un metodo interno per risolvere le richieste ajax. Intanto per fare le chiamate Ajax nel front end ho usato l’hook “admin_footer” per aggiungere il codice JS con Jquery, in modo da poter creare le funzioni per inserire nuovi elementi, eliminare quelli esistenti e intanto ottenere l’elenco completo. La funzione potrebbe essere ancora più efficiente riducendo la banda utilizzando una piccola cache interna in modo da evitare di chiedere ogni volta il risultato per ogni operazione, ma soltanto la conferma per la cancellazione e l’id del nuovo inserito, ma si potranno sempre implementare. Il link per inviare la richiesta si trova nella variabile “ajaxurl” che viene fornita da wordpress nel backend, poi nel dati che si passano si mette la viariabile “Action” che serve per identificare, attraverso l’hook dinamico “add_action( ‘wp_ajax_my_action1’, ‘my_action’ );” quale funzione eseguire, in particolare l’hook è formato dalla parte fissa “wp_ajax_” con l’aggiunta del nome dell’azione, per esempio se l’azione è Cancella bisogna usare l’hook “wp_ajax_Cancella”, il secondo parametro è la funzione in php che viene chiamata.

Infine nella funzione di php per gestire i dati della “To do list” ho usato “$wpdb->prepare” per migliorare la sicurezza, perchè crea la query formattando gli input in modo da evitare sql injection. Oltre a questo bisognerebbe controllare che gli input non siano codici e, nel caso lo fossero, formattarli in modo da evitare che nella visualizzazione compaiano come codice, ma questo è solo un semplice esempio.

Alcuni link della documentazione di wordpress:

https://codex.wordpress.org/AJAX_in_Plugins
https://codex.wordpress.org/Creating_Tables_with_Plugins
https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/

Codice:


<?php

function ToDoList_Installation_Function() {

  global $wpdb;
  $table_name = $wpdb->prefix . 'to_do_list';
  $charset_collate = $wpdb->get_charset_collate();

  $sql = "CREATE TABLE $table_name (
    `id_to_do_list` INT NOT NULL AUTO_INCREMENT,
  	`id_user` BIGINT unsigned,
  	`text` TEXT,
  	PRIMARY KEY (`id_to_do_list`)
  ) $charset_collate;";

  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
  dbDelta( $sql );

}
add_action( 'activated_plugin', 'ToDoList_Installation_Function',10,0 );




/*--------------------------------------------------------------------------------*/

add_action('wp_dashboard_setup', 'my_custom_dashboard_widgets_for_todolist');

function my_custom_dashboard_widgets_for_todolist() {
global $wp_meta_boxes;
//wp_add_dashboard_widget('custom_widget_dashboard_todolist', 'To do list', 'custom_dashboard_help_for_todolist_old');


wp_add_dashboard_widget('custom_widget_dashboard_todolist', 'To do list', 'custom_dashboard_help_for_todolist');
}

function custom_dashboard_help_for_todolist_old() {
//Prima versione della visualizzazione dei dati senza ajax
  global $wp_query;
  global $wpdb;
  $Output="<table>";
  include_once("wp-config.php");
  include_once("wp-includes/wp-db.php");
  $table_name = $wpdb->prefix . 'to_do_list';

  $sql = "select * from ".$table_name ." WHERE id_user=".get_current_user_id();
  $results = $wpdb->get_results($sql,ARRAY_A);

  //$Output.=print_r($results);
  for($i=0;$i<sizeof($results);$i++) { $Output.="<tr><td>".$results[$i]['text']."</td></tr>"; } $Output.="</table>"; echo $Output;
}

function custom_dashboard_help_for_todolist() {
   //Questa è la funzione che visualizza i componenti html base per poi gestire con jquery e Ajax il resto
 ?>
    <div id="ToDoList"></div>
    <input type="text" id="InputToDoList" >
  <?php
}

add_action( 'admin_footer', 'my_action_javascript' ); // Write our JS below here

function my_action_javascript() { ?>
	<script type="text/javascript" >


    function cancella(id)
    {
      var data = {
  			'action': 'delete_to_do_list',
  			'id': id,
  		};

  		// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
  		jQuery.post(ajaxurl, data, function(response) {
  			document.getElementById("ToDoList").innerHTML=response;
  		});
    }

	jQuery(document).ready(function($) {


    $("#InputToDoList").keypress(function(event) {
            if (event.keyCode === 13) {
              jQuery(document).ready(function($) {

              var inputOfToDoList=document.getElementById("InputToDoList").value;
              document.getElementById("InputToDoList").value="";
               var data = {
                 'action': 'my_action1',
                 'input': inputOfToDoList,
               };

               // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
               if(inputOfToDoList!="")
                 jQuery.post(ajaxurl, data, function(response) {
                   document.getElementById("ToDoList").innerHTML=response;
                 });
             });
            }
        });

		var data = {
			'action': 'my_action1',
			'input': '',
		};

		// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
		jQuery.post(ajaxurl, data, function(response) {
			document.getElementById("ToDoList").innerHTML=response;
		});
	});
	</script> ?php }

add_action( 'wp_ajax_my_action1', 'my_action' );

function my_action()
{ 
     global $wp_query;
     global $wpdb;
     $Output="&lt;table&gt;";
     include_once("wp-config.php");
     include_once("wp-includes/wp-db.php");
     $table_name = $wpdb->prefix . 'to_do_list';
     if(isset($_POST['input'])) if(!empty($_POST['input']))
       {
          $Input=sanitize_text_field($_POST['input']);
          $sql1 = $wpdb->prepare("INSERT INTO ".$table_name ." ( `text`,`id_user`) VALUES (%s,".get_current_user_id().")",$Input);
          $wpdb->get_results($sql1,ARRAY_A);
        } 
      $sql = "select * from ".$table_name ." WHERE id_user=".get_current_user_id();
      $results = $wpdb->get_results($sql,ARRAY_A);
      for($i=0;$i<sizeof($results);$i++) 
         {
            $Output.="&lt;tr&gt;&lt;td&gt;&lt;input type='button' onclick='cancella(".$results[$i]['id_to_do_list'].")' value='x'&gt;&lt;/td&gt;&lt;td&gt;".$results[$i]['text']."&lt;/td&gt;&lt;/tr&gt;";
         } 
      $Output.="&lt;/table&gt;";
      echo $Output;
      wp_die(); // this is required to terminate immediately and return a proper response
} 

add_action( 'wp_ajax_delete_to_do_list', 'delete_to_do_list' );
function delete_to_do_list()
{
     global $wp_query;
     global $wpdb;
     $table_name = $wpdb->prefix . 'to_do_list';
     $IdToDelete=$_POST['id'];
     $sql = $wpdb->prepare("delete from ".$table_name ." WHERE id_to_do_list=%s and id_user=".get_current_user_id(),$IdToDelete);
     $results = $wpdb->get_results($sql,ARRAY_A);
     my_action();
     wp_die();
  } 

add_action('admin_head', 'css_for_ToDoList_plugin'); function css_for_ToDoList_plugin()
{ 
?-->
      #ToDoList tr:nth-child(even) {background: #CCC}
      #ToDoList tr:nth-child(odd) {background: #FFF}
      #ToDoList table { border-collapse: collapse; width: 100%;}
      #ToDoList tr
      {
        border-width:0px;
      }
      #ToDoList input[type='button']
      {
        border:1px solid black;
        border-radius: 30px;
        background-color: transparent;
        font-size: 20px;
        padding:10px;
        margin-right: 10px;
        margin-left: 5px;
      }
      #ToDoList input[type='button']:hover
      {
        background-color: blue;
        color:white;
      }
      #InputToDoList
      {
        width: 100%;
      }
    </style>
  <?php
}
?>

———

Qualora aveste bisogno di un plugin funzionante e più completo di questa versione, potete trovarlo nel repository di wordpress: https://it.wordpress.org/plugins/tags/todo-list/