Código

Algunas notas para mí

Simple and clean

// Target
$url = 'https://target.domain.com';
$path = '/webservice/postExample.php';
 
// Apache authentication 
$httpUsername = 'apacheUser';
$httpPassword = 'apachePass';
 
// Data to POST
$dataPOST = '&id=XXX&name=XXX';
 
$opts = array('http' =>
  array(
    'method'  => 'POST',
    'header'  => "Content-Type: text/html\r\n".
      "Authorization: Basic ".base64_encode("$httpUsername:$httpPassword")."\r\n",
    'content' => $dataPOST,
    'timeout' => 60
  )
);
 
$context  = stream_context_create($opts);
$result = file_get_contents($url . $path, false, $context, -1, 40000);
 
var_dump(json_decode($result));

Objective

  • Create a custom table with data from a database sql query, with sort and pagination, in WordPress admin panel.
  • Step 1: create a custom menu link to access a new page for the table
  • Step 2: create callback function for the menu link, prepare data input for pagination, sort and print form + table
  • Note: this should be improved to use full WordPress advantages of wp_list_table

Step 1: create a custom menu link to access a new page for the table

Easy one: http://guillermocerezo.com/en/blog/codigo-php-desarrollo-web-cms-wordpre...

function register_table_example_menu_page() {
    add_menu_page(
        __('Custom table example link'), // link title
        __('Custom table example link'), // link display on screen
        'manage_options', // capability / permission to see display the link
        'example_table', // menu slug / clean url
        'example_table_with_custom_data', // function name to display content when an user clicks 
        '', // icon url, example: plugins_url( 'myplugin/images/icon.png' ),
        6 // menu order, must be unique, if the number exists it will overwrite another menu link
    ); 
}
 
add_action( 'admin_menu', 'register_table_example_menu_page' );

Step 2: create callback function for the menu link, prepare data input for pagination, sort and print form + table

/**
 * Print form and table.
 * Example fields for sent mails table 'wp_example_messages': subject, body, created, user_id 
 */
function example_table_with_custom_data()
{
    global $wpdb;
 
    // prepare user input for pagination and sorting
 
    // user id
    $user_id = isset($_GET['user_id']) ? $_GET['user_id'] : null;
 
    // page number
    $paged = isset($_GET['paged']) ? $_GET['paged'] : 1;
 
    // date filter example
    $filter['date_begin'] = isset($_GET['date_begin']) ? $_GET['date_begin'] : "";
    $filter['date_end'] = isset($_GET['date_end']) ? $_GET['date_end'] : "";
    $conditions = example_table_page_filter($filter);
 
    // sort by row column or created
    $sort['name'] = isset($_GET['sort']) ? $_GET['sort'] : 'created';
    $sort['order'] = isset($_GET['order']) ? $_GET['order'] : 'DESC';
    $sort_by = ' ORDER BY ' . $sort['name'] . ' '. $sort['order'];
 
    // init html output
    $html = '';
 
    // if we have the user id...
    if ($user_id && is_numeric($user_id)) {
 
        // initial link for pagination.
        // "page" must be the  menu slug / clean url from the add_menu_page
        $link = 'admin.php?page=example_table';
 
        // user info by WordPress function
        $user_info = get_userdata($user_id);
 
        // initial form html
        $html = '<h1>'. __('Emails sent by').' '. $user_info->display_name.'</h1>';
        $html .= '
            <form action="' . $link . '" method="get">
                <input type="hidden" name="page" value="example_table">
                <input type="hidden" name="user_id" value="'.$user_id.'">
                <input type="hidden" name="sort" value="'.$sort['name'].'">
                <input type="hidden" name="order" value="'.$sort['order'].'">
                <input type="hidden" name="paged" value="'.$paged.'">
                <label for="date_begin">'.__('Date begin').'</label>
                <input type="text" name="date_begin" value="' .$filter['date_begin']. '" placeholder="YYYY-MM-DD">
                <label for="date_end">'.__('Date end').'</label>
                <input type="text" name="date_end" value="' .$filter['date_end']. '" placeholder="YYYY-MM-DD">
                <input type="submit" value="'.__('Send').'">
            </form>';
 
        // example sql query to get user emails
        $sql = '
            SELECT u.display_name as "from", u.ID, m.subject,  m.body, m.created
            FROM wp_example_messages m 
            LEFT JOIN wp_users u ON u.ID=m.user_id 
            WHERE u.ID = '.$user_id.' '.$conditions.' '.$sort_by;
        $rows = $wpdb->get_results($sql);
 
        $rows_per_page = 20;
 
        // add pagination arguments from WordPress
        $pagination_args = array(
            'base' => add_query_arg('paged','%#%'),
            'format' => '',
            'total' => ceil(sizeof($rows)/$rows_per_page),
            'current' => $paged,
            'show_all' => false,
            'type' => 'plain',
        );
 
        $start = ($paged - 1) * $rows_per_page;
        $end_initial = $start + $rows_per_page;
        $end = (sizeof($rows) < $end_initial) ? sizeof($rows) : $end_initial;
 
        // if we have results
        if (count($rows) > 0) {
            // prepare link for pagination
            $link .= '&date_begin=' . $filter['date_begin'] 
                    . '&date_end=' . $filter['date_end'] 
                    . '&user_id=' . $user_id
                    . '&paged=' . $paged;
 
            $order = $sort['order'] == "ASC" ? "DESC" : "ASC";
 
            // html table head
            $html .= '<table id="user-sent-mail" class="wp-list-table widefat fixed users">
                    <thead>
                    <tr class="manage-column">
                        <th class="col-from">
                            <a href="' . $link . '&sort=from&order=' . $order . '">
                            ' . __('From') . '
                            </a>
                        </th>
                        <th class="col-subject">
                            <a href="' . $link . '&sort=subject&order=' . $order . '">
                            ' . __('Subject') . '
                            </a>
                        </th>
                        <th class="col-body">
                            <a href="' . $link . '&sort=body&order=' . $order . '">
                                ' . __('Body') . '
                            </a>
                        </th>
                        <th class="col-created">
                            <a href="' . $link . '&sort=created&order=' . $order . '">
                            ' . __('Created') . '
                            </a>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    ';
 
            // add rows
            for ($index = $start; $index < $end;  ++$index) {
                $row = $rows[$index];
 
                $class_row = ($index % 2 == 1 ) ? ' class="alternate"' : '';
                $html .= '
                    <tr ' . $class_row . '>
                        <td>' . $row->from . '</td>
                        <td>' . $row->subject . '</td>
                        <td>' . $row->body . '</td>
                        <td>' . $row->created . '</td>
                    </tr>';
            }
 
            $html .= '</tbody></table>';
 
            // add pagination links from WordPress
            $html .= paginate_links($pagination_args);
        } else {
            $html .= '<p>' . __('No records found, try again please') . '</p>';
        } // endif count($rows)
 
    } // endif $user_id exists
 
    // print form + table
    echo $html;
 
} // end example_table_with_custom_data
 
 
/**
 * Add where conditions for dates
 * 
 * @param array $filter date_begin | date_end
 * @return string
 */
function example_table_page_filter($filter)
{
    $conditions = '';
    if (isset($filter) && count($filter)>0) {
        if (isset($filter['date_begin']) && $filter['date_begin'] 
            && checkdate(
                substr($filter['date_begin'], 5,2),
                substr($filter['date_begin'], 8,2),
                substr($filter['date_begin'], 0,4)
                )) {
            $conditions .= ' AND DATE_FORMAT(m.created,"%Y-%m-%d") 
                >= DATE_FORMAT("'.$filter['date_begin'].'","%Y-%m-%d") ';
        }
        if (isset($filter['date_end']) && $filter['date_end'] 
                && checkdate(
                substr($filter['date_end'], 5,2),
                substr($filter['date_end'], 8,2),
                substr($filter['date_end'], 0,4)
                )) {
            $conditions .= ' AND DATE_FORMAT(m.created,"%Y-%m-%d") 
                <= DATE_FORMAT("'.$filter['date_end'].'","%Y-%m-%d") ';
        }
    }
    return $conditions;
}
  • Step 1: call add_action 'admin_menu'
  • Step 2: create custom function for the new link

Step 1: call add_action 'admin_menu'

add_action( 'admin_menu', 'register_example_custom_menu_link_menu_page' );

Step 2: create custom function for the new link

function register_example_custom_menu_link_menu_page() {
    add_menu_page(
        __('New admin link'), // link title
        __('New admin link'), // link display on screen
        'manage_options', // capability / permission to see display the link
        'example_custom_menu_link', // menu slug / clean url
        'example_custom_menu_link_function', // function name to display content when an user clicks 
        '', // icon url, example: plugins_url( 'myplugin/images/icon.png' ),
        6 // menu order, must be unique, if the number exists it will overwrite another menu link
    ); 
}
 
function example_custom_menu_link_function() {
    echo "Here goes the magic!"
}

More info: http://codex.wordpress.org/Function_Reference/add_menu_page

/**
 * Disable Admin Bar for All Users Except for Administrators
 */
function remove_admin_bar() {
    if (!current_user_can('administrator')) {
        show_admin_bar(false);
    }
}
add_action('after_setup_theme', 'remove_admin_bar');
  • Method 1: by global $current_user for the current user logged in
  • Method 2: check if an user has a specific role by SQL query

Method 1: by global $current_user for the current user logged in

/**
 * Checks if current user has administrator role
 * @return boolean
 */
function user_is_admin_example() {
    global $current_user;
 
    // check if current user is logged in
    if (is_user_logged_in()) {
        // if has administrator rol, return true
        if (in_array('administrator', $current_user->roles)) {
            return true;
        }
    }
    return false;
}

Method 2: check if an user has a specific role by SQL query

/**
 * Returns true|false if user has role
 * @param integer $ID
 * @param string $role
 * @return boolean
 */
function userHasRole($ID, $role)
{
    global $wpdb;
    $sql = "SELECT ID,display_name 
                FROM $wpdb->users u 
                    INNER JOIN $wpdb->usermeta m ON m.user_id = u.ID 
                WHERE u.ID = ".$ID." 
                   AND m.meta_key = 'wp_capabilities' 
                   AND m.meta_value LIKE '%" . $role . "%'" ;
    $result = $wpdb->get_results($sql);
    if (count($result)>0) {
        return true;
    } else {
        return false;
    }
}

Collapse only one div

HTML

<!-- user should click here -->
<button class="btn btn-collapse-toggle" type="button" data-toggle="collapse" data-target="target-div" title="Collapse">
        <i class="fa fa-lg fa-compress"></i>
</button>
 
<!-- "collapse in" start expanded, "collapse" start collapsed -->
<div id="target-div" class="collapse in"> Some content to be collapsed </div>

Javascript

$('.btn-collapse-toggle').on('click', function () {
    var ico = $(this).find('i');
    var target = $(this).attr('data-target');
 
    if (ico.hasClass('fa-expand')) {
        ico.removeClass('fa-expand');
        ico.addClass('fa-compress');
        $(this).attr('title','Minimize');
    } else {
        ico.removeClass('fa-compress');
        ico.addClass('fa-expand');
        $(this).attr('title','Maximize');
    }
 
    // here comes the effect
    $(target).collapse('toggle');
});

Collapse all div with the same class

HTML

<!-- user should click here -->
<button class="btn btn-collapse-toggle-all" type="button" data-toggle="collapse" data-target="target-div" title="Collapse All">
        <i class="fa fa-lg fa-compress"></i>
</button>
 
<!-- "collapse in" start expanded, "collapse" start collapsed -->
<div class="collapsible collapse in"> Some content to be collapsed 1 </div>
<div class="collapsible collapse in"> Some content to be collapsed 2 </div>
<div class="collapsible collapse in"> Some content to be collapsed 3 </div>

Javascript

$('.btn-collapse-toggle-all').on('click', function () {
    var ico = $(this).find('i');
 
    if (ico.hasClass('fa-expand')) {
        ico.removeClass('fa-expand');
        ico.addClass('fa-compress');
        $(this).attr('title','Minimize All');
    } else {
        ico.removeClass('fa-compress');
        ico.addClass('fa-expand');
        $(this).attr('title','Maximize All');
    }
 
    // here comes the effect
    $('.collapsible').collapse('toggle');
});
  • Step 1: make your own function inside your plugin
  • Step 2: call add_shortcode inside your plugin
  • Step 3: use the shortcode in a text widget

Step 1: make your own function inside your plugin

/**
 * shortcode: site url
 * @return string
 */
function wp_home_shortcode() {
    return WP_HOME;
}

Step 2: call add_shortcode inside your plugin

add_shortcode('wp_home','wp_home_shortcode');

Step 3: use the shortcode in a text widget

Just add a Text widget from WordPress administration and type [wp_home] inside the box to get the current url of your WordPress installation

Summary

  • Step 1: make some string in your plugin translatable
  • Step 2: load the function with add_action 'init' in your plugin
  • Step 3: create folder and file for translations inside your plugin
  • Step 4: update your language files with poedit

In the example, we are going to translate the plugin to Spanish.

  • Plugin name: my_plugin
  • Path: wordpress/wp-content/plugins/my_plugin
  • Language file: wordpress/wp-content/plugins/my_plugin/languages/my_plugin-es_ES.po
  • Note: the language file should be called like the plugin name plus '-xx_XX', the code for each language. In this case, '-es_ES' for Spanish.

Step 1: make some strings in your plugin translatable

  • We can use Wordpress functions like '__' to make something translatable. Example for strings 'Father' and 'Teacher':
function change_role_name() {
    global $wp_roles;
 
    if (!isset($wp_roles)) {
        $wp_roles = new WP_Roles();
    }
 
    //You can list all currently available roles like this...
    $roles = $wp_roles->get_names();  
 
    //You can replace "administrator" with any other role "editor", "author", "contributor" or "subscriber"...
    $wp_roles->roles['parent']['name'] = __( 'Father', 'my_plugin');
    $wp_roles->role_names['parent'] = __( 'Father', 'my_plugin');           
    $wp_roles->roles['teacher']['name'] = __( 'Teacher', 'my_plugin');
    $wp_roles->role_names['teacher'] = __( 'Teacher', 'my_plugin');           
}
add_action('init', 'change_role_name');

Step 2: load the function 'load_plugin_textdomain' with add_action 'init' in your plugin

/**
 * Action: init
 */
function my_plugin_action_init()
{
    // this will search language files in 'wordpress/wp-content/my_plugin/languages'
    load_plugin_textdomain('my_plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
add_action('init', 'my_plugin_action_init');

Step 3: create folder and file for translations inside your plugin

<my_plugin-es_ES.po> file example without any strings translated

# Translation of Development in Spanish (Spain)
# This file is distributed under the same license as the Development package.
msgid ""
msgstr ""
"Project-Id-Version: My Plugin \n"
"POT-Creation-Date: 2014-09-20 11:54+0100\n"
"PO-Revision-Date: 2014-09-20 11:55+0100\n"
"Last-Translator: Guillermo Cerezo Somera \n"
"Language-Team:  \n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.5.4\n"
"X-Poedit-Basepath: ../\n"
"X-Poedit-KeywordsList: __;_;_e;_ex;_x;_n\n"
"X-Poedit-SearchPath-0: .\n"

Step 4: update your language files with poedit

We don't really need to create from scratch the '.po' language file, we should use http://poedit.net/ to do it. It's really easy update your language files with it, only need to open the file 'my_plugin-es_ES.po' with poedit, click in update strings from source code and automatically the news strings will appear to be translated. Just save the file when finished and Wordpress will do the rest.

After that, the file 'my_plugin-es-ES.po' will appear with the new translated strings:

#: my_plugin.php:47
msgid "Father"
msgstr "Padre"
 
#: my_plugin.php 48
msgid "Teacher"
msgstr "Profesor"
  • Javacript
function getFile() {
    document.getElementById("file-input-image").click();
}
function sub(obj) {
    var file = obj.value;
    var fileName = file.split("\\");
    document.getElementById("file-input-text").innerHTML = fileName[fileName.length - 1];    
    return false;
}
  • HTML (Bootstrap css used)
<div id="file-btn" class="btn btn-info" onclick="getFile()">
    <i class="fa fa-camera fa-lg"></i> <span id="file-input-text">Upload picture</span>
</div>
<div class="hidden">
    <input id="file-input-image" name="file-input-image" type="file" value="upload" onchange="sub(this)"/>
</div>

Use colors in the shell output

First asign color variables

red='\e[0;31m'
RED='\e[1;31m'
blue='\e[0;34m'
BLUE='\e[1;34m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
NC='\e[0m' # No Color

Color variables with echo

echo ""
echo "Text example with some colors"
echo -e "${RED} Red text ${NC}"
echo -e "${BLUE} Blue text :${NC}"
  • Note: echo must be used with the -e parameter to print colors.
  • Note: if you don't end the line with ${NC} (No color), all the following echos will keep the last color set

Pause the script, wait for user input

function pause(){
   read -p "$*"
}
 
echo ""
pause "Press a key to continue..."

Assign first and second user input to variables

VARIABLE_USER_INPUT1=$1
VARIABLE_USER_INPUT2=$2

Check if a folder doesn't exists in the system

if [ ! -d "$DIR_VARIABLE" ]; then
  echo "${DIR_VARIABLE} doesn't exists"
fi

Check if a file exists in the system

if [ -f "filename.txt" ]; then
  echo "filename.txt exists"
fi

Check if the user has executed the script with at least one parameter

if [ $# -ne 1 ]; then
        echo -e "${RED} User hasn't introduced a parameter ${NC}"
else
        echo -e "${CYAN} User has introduced a parameter ${NC}"
fi

Arrays in bash

DIR_ARRAY=('folder1' 'folder2' 'folder3')

Loop an array in bash

for DIR in "${DIR_ARRAY[@]}"
do
        :
        echo "Dirname: ${DIR}"
done

Páginas