Código

Algunas notas para mí

/**
 * DateHelper class
 *
 */
class DateHelper
{
    private $LC_TIME;
 
    /**
     * 
     * @param string $timezone [optional] default timezone
     * @param string $LC_TIME [optional] default language for string date format
     */
    public function __construct($timezone = "Europe/Madrid", $LC_TIME = 'es_ES')
    {
        date_default_timezone_set($timezone);
        $this->LC_TIME = $LC_TIME;
    }
 
    /**
     * Convert Date/Datetime to MySQL format (Y-m-d H:i:s)
     * @param string $date
     * @param string $format [optional] d/m/Y | d/m/Y H:i | d/m/Y H:i:s
     * @param string $separator [optional] '/'
     * @return string|null Date in format Y-m-d (H:i:s) or <b>NULL</b>
     */
    public function DateConvert($date, $format = 'd/m/Y', $separator = '/')
    {
        $finalDate = null;
        $datePreFilter = str_replace($separator, '-', $date);
 
        switch ($format) {
            case 'd/m/Y':
                if ($this->isValidDate($datePreFilter, $format, $separator)) {
                    $oDate = new \DateTime($datePreFilter);
                    $finalDate = $oDate->format('Y-m-d');
                }
                break;
 
            case 'd/m/Y H:i':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0]) &&
                            $this->isValidHour($hourMinute, 'H:i')) {
                        $oDate = new \DateTime($datePreFilter . ':00');
                        $finalDate = $oDate->format('Y-m-d H:i:s');
                    }
                }
                break;
            case 'd/m/Y H:i:s':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0]) && 
                        $this->isValidHour($hourMinute, 'H:i:s')) {
                        $oDate = new \DateTime($datePreFilter);
                        $finalDate = $oDate->format('Y-m-d H:i:s');
                    }
                }
                break;
        }
 
        return $finalDate;
    }
 
    /**
     * Transform a Y-m-d date to another format (short|medium|large). Eg: <br>
     * short: 20-11-2014 <br>
     * medium: 20 Noviembre 2014 <br>
     * large: Jueves, 20 de Noviembre 2014
     * 
     * @param string $date
     * @param string $formatType [optional] short|medium|large
     * @param string $originalFormat [optional] 
     * @param string $time [optional] print H:i:s
     * @return string
     */
    public function DateFormat($date, $formatType = 'medium', $originalFormat = 'Y-m-d', $time = false)
    {
        setlocale(LC_TIME, $this->LC_TIME);
 
        $dateFormatted = $date;
 
        if ($this->isValidDate($date, $originalFormat, '-')) {
            $oDate = new \DateTime($date);
            switch ($formatType) {
                case 'short':
                    $format = $time ? "%d/%m/%Y %H:%M:%S" : "%d-%m-%Y";
                    $dateFormatted = strftime($format, $oDate->getTimestamp());
                    break;
                case 'large':
                    $format = $time ? "%A, %d de %B %Y %H:%M:%S" : "%A, %d de %B %Y";
                    $dateFormatted = strftime($format, $oDate->getTimestamp());
                    break;
                case 'medium':
                default:
                    $format = $time ? "%d %B %Y %H:%M:%S" : "%d %B %Y";
                    $dateFormatted = strftime($format, $oDate->getTimestamp());
                    break;
            }
        }
        return $dateFormatted;
    }
 
 
    /**
     * Checks for a valid date by format and separator
     * 
     * @param string $date
     * @param string $originalFormat [optional] d/m/Y | d/m/Y H:i | d/m/Y H:i:s
     * @param string $separator [optional] '/'
     * @return boolean
     */
    public function isValidDate($date, $originalFormat = 'd/m/Y', $separator = '/')
    {
        $isValidDate = false;
 
        $datePreFilter = str_replace($separator, '-', $date);
        switch ($originalFormat) {
            case 'd/m/Y':
                $arrayDate = explode('-', $datePreFilter);
                if (isset($arrayDate[0]) && isset($arrayDate[1]) && isset($arrayDate[2])
                    && (is_numeric($arrayDate[1]) && is_numeric($arrayDate[0]) && is_numeric($arrayDate[2])) 
                    && checkdate($arrayDate[1], $arrayDate[0], $arrayDate[2])) {
                    $isValidDate = true;
                }
                break;
            case 'Y-m-d':
                $arrayDate = explode('-', $datePreFilter);
                if (isset($arrayDate[0]) && isset($arrayDate[1]) && isset($arrayDate[2])
                    && (is_numeric($arrayDate[1]) && is_numeric($arrayDate[0]) && is_numeric($arrayDate[2])) 
                    && checkdate($arrayDate[1], $arrayDate[2], $arrayDate[1])) {
                    $isValidDate = true;
                }
                break;
            case 'd/m/Y H:i':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0]) &&
                            $this->isValidHour($hourMinute, 'H:i')) {
                         $isValidDate = true;
                    }
                }
                break;
            case 'd/m/Y H:i:s':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0]) && 
                        $this->isValidHour($hourMinute, 'H:i:s')) {
                         $isValidDate = true;
                    }
                }
                break;
            case 'Y-m-d H:i:s':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0], 'Y-m-d') && 
                        $this->isValidHour($hourMinute, 'H:i:s')) {
                         $isValidDate = true;
                    }
                }
                break;
            case 'Y-m-d H:i:s':
                $auxDate = explode(' ', $datePreFilter);
                if (isset($auxDate[0]) && isset($auxDate[1])) {
                    $arrayDate = explode('-',$auxDate[0]);
                    $hourMinute = $auxDate[1];
 
                    if ($this->isValidDate($auxDate[0], 'Y-m-d') && 
                        $this->isValidHour($hourMinute, 'H:i:s')) {
                         $isValidDate = true;
                    }
                }
                break;
        }
        return $isValidDate;
    }
 
    /**
     * Checks valid hour:minute or hour:minute:second
     * @param string $hour 
     * @param string $format [optional] H:i | H:i:s
     * @return boolean
     */
    public function isValidHour($hour, $format = 'H:i')
    {
        $isValidHour = false;
 
        switch ($format) {
            case 'H:i':
                if (preg_match("/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/", $hour)) {
                    $isValidHour = true;
                }
                break;
 
            case 'H:i:s':
                if (preg_match("/^([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/", $hour)) {
                    $isValidHour = true;
                }
                break;
        }
 
        return $isValidHour;
    }
}
 
// Examples
$oDateHelper = new DateHelper();
 
$dateMySQL = '2014-10-30';
 
echo $oDateHelper->DateFormat($dateMySQL);
// 30 octubre 2014
 
echo $oDateHelper->DateFormat($dateMySQL,'large');
// jueves, 30 de octubre 2014
 
echo $oDateHelper->DateFormat($dateMySQL,'short'). "<br>";
// 30-10-2014
 
 
$spanishDate = '30/10/2014';
 
echo $oDateHelper->DateConvert($spanishDate);
// 2014-10-30 
 
echo $oDateHelper->DateConvert($spanishDate . ' 14:30', 'd/m/Y H:i');
// 2014-10-30 14:30:00
 
echo $oDateHelper->DateConvert($spanishDate . ' 14:30:25', 'd/m/Y H:i:s');
// 2014-10-30 14:30:25
 
 
$incorrectDate = '99/12/2014';
 
if (!$oDateHelper->isValidDate($incorrectDate)) {
    echo "Wrong date format";
}

Dump structure only, without data

mysqldump -d -h localhost -u root -pmypassword databasename > dump_file.sql

*Note: "-d" option is the only difference between this command and the typical mysqldump with all data

Dump all with drop table and drop database if exists

mysqldump --user=root --password=mypassword -h localhost  databasename --add-drop-table --add-drop-database > dump_file.sql

Dump with UTF8 encode

mysqldump --user=root --password=mypassword -h localhost  databasename --default-character-set utf8 > dump_file.sql

Dump all but ignore a specific table

mysqldump --user=root --password=mypassword -h localhost  databasename --ignore-table=databasename.table_name_to_ignore > dump_ignore_one_table_file.sql

Dump only specific tables

mysqldump --user=root --password=mypassword -h localhost  databasename table_name_to_dump table_name_to_dump_2 > dump_only_two_tables_file.sql

Dump and alter one line to change owner of a view

mysqldump --user=root --password=mypassword -h localhost  databasename | sed -r 's/DEFINER=`[^`]+`@`[^`]+`/DEFINER=new_user_owner/g' > dump_with_owner_altered.sql

Objective

Create a custom module with a form to set/get custom system variables from Drupal. We're going to add custom permissions to access this new page. Bonus: add simple page to count every node for each content type.

Summary

  • Step 1: create custom module
  • Step 2: call hook_menu and hook_permissions
  • Step 3: create custom callbacks for new menus
  • Step 4: create a Drupal form by code. Form, validate and submit
  • Step 5: bonus, send mail after submit

Step 1: create custom module

  • Create '.module' and '.info' files inside your Drupal installation. Can be in 'drupal/sites/all/modules/configuration_module' or 'drupal/sites/default/modules/configuration_module'

File: configuration_module.info

;$Id$
name = Configuration module
description = Example module for a form with custom system variables
package = Example modules
core = 7.x
files[] = configuration_module.module
;dependencies[] = autoload
;php = 5.3
version = "7.x-1.0"

Step 2: call hook_menu and hook_permissions

File: configuration_module.module

/**
 * hook_menu
 */
function configuration_module_menu()
{
    $items = array();
 
    $items['configuration_module/variables'] = array(
        'title' => t('Configuration module configuration'),
        'description' => t('Configuration module variables page'),
        'page callback' => 'configuration_module_callback_variables_form',
        'access arguments' => array('access configuration_module configuration'),
    );
 
    $items['configuration_module/counter'] = array(
        'title' => t('Configuration module counter'),
        'description' => t('Configuration module counter'),
        'page callback' => 'configuration_module_callback_counter',
        'access arguments' => array('access configuration_module counter'),
    );
 
    return $items;
}
 
/**
 * Implements hook_permission() to provide a demonstration access string.
 */
function configuration_module_variables_permission()
{
    return array(
        'access configuration_module configuration' => array(
            'title' => t('Access Configuration module configuration'),
            'description' => t('Access Configuration module  parameters configuration.'),
        ),
        'access configuration_module count' => array(
            'title' => t('Access Configuration module count'),
            'description' => t('Access Configuration module  count list.'),
        ),
    );
}

Step 3: create custom callbacks for new menus

/**
 * Print table with counter for every content type
 * @return string
 */
function configuration_module_callback_counter()
{
    // query for count every content type, group by type
    $query = db_select('node', 'n');
    $query->condition('n.status', 1)
            ->fields('n', array('type', 'nid'))
            ->groupBy('type');
    $query->addExpression('COUNT(n.nid)', 'count');
    $query->orderBy('count', 'DESC');
    $results = $query->execute();
 
    if ($results) {
        // prepare table header and rows
        $header = array(
            'content' => array('data' => t('Content')),
            'quantity' => array('data' => t('Quantity'))
        );
        $rows = array();
        foreach ($results as $key => $value) {
            $rows[] = array(strtoupper($value->type), $value->count);
        }
        $attributes = array('width' => '100%');
 
        $table = array(
            'header' => $header,
            'rows' => $rows,
            'attributes' => $attributes,
            'sticky' => FALSE
        );
        return theme_table($table);
    }
}
 
/**
 * Callback variables form
 * @return string
 */
function configuration_module_callback_variables_form()
{
    $obj = drupal_get_form('configuration_module_variables_form');
    return drupal_render($obj);
}

Step 4: create a Drupal form by code. Form, validate and submit

/**
 * Generate Drupal form with hook_form
 */
function configuration_module_variables_form($form, &$form_state)
{
    // use Drupal variable_get 
    $variable_one = variable_get('variable_one');
    $variable_two = variable_get('variable_two');
 
    $form['variable_one'] = array(
        '#type' => 'textfield',
        '#title' => t('Variable one'),
        '#size' => 2,
        '#default_value' => $variable_one,
        '#required' => TRUE,
    );
 
    $form['variable_two'] = array(
        '#type' => 'textfield',
        '#title' => t('Variable two'),
        '#size' => 2,
        '#default_value' => $variable_two,
        '#required' => TRUE,
    );
 
    $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
 
    return $form;
}
 
/**
 * Validate hook before submit with hook form_validate
 */
function configuration_module_variables_form_validate($form, &$form_state)
{
    if (isset($form_state['values']['variable_one']) 
            && !is_numeric($form_state['values']['variable_one'])) {
        form_set_error('variable_one', t('The value must be numeric.'));
    }
 
    if (isset($form_state['values']['variable_two']) 
            && !is_numeric($form_state['values']['variable_two'])) {
        form_set_error('variable_two', t('The value must be numeric.'));
    }
}
 
/**
 * Save form data with hook form_submit
 */
function configuration_module_variables_form_submit($form, &$form_state)
{
    if (isset($form_state['values']['variable_one'])) {
        variable_set('variable_one', $form_state['values']['variable_one']);
    }
 
    if (isset($form_state['values']['variable_two'])) {
        variable_set('variable_two', $form_state['values']['variable_two']);
    }
 
    if (custom_function_send_mail($form, $form_state) {
        drupal_set_message(t('Data saved.'));         
    } else {
        drupal_set_message(t('Error sending email.'));         
    }
}

Step 5: bonus, send mail after submit

/**
 * Send mail with Drupal
 * @return boolean
 */
function custom_function_send_mail($form, &$form_state)
{
    global $base_url;
 
    // Form data
    $params['variable_one'] = $form_state['input']['variable_one'];
    $params['variable_two'] = $form_state['input']['variable_two'];
 
    $from = 'example@mail.com';
    $to = variable_get('site_mail', ini_get('sendmail_from'));
 
    // Send email
    $message = drupal_mail(
        'configuration_module',
        'configuration_module',
        $to,
        'es',
        $params,
        $from
    );
 
    if ($message['result']) {
        watchdog('configuration_module', t('Email sent to %recipient'), array('%recipient' => $to));
        return true;
    } else {
        return false;
    }
}
 
/**
 * hook_mail
 */
function configuration_module_mail($key, &$message, $params)
{
    $message['subject'] = t('Configuration module example mail');
    $message['body'][] = t("Request data");
    $message['body'][] = t("Variable one: @variable_one", array('@variable_one' => $params['variable_one']));
    $message['body'][] = t("Variable two: @variable_two", array('@variable_two' => $params['variable_two']));
}

List of countries and regions of the world in MySQL format.

Archivos:
AdjuntoTamaño
Binary Data MySQL world countries list7.97 KB
Binary Data MySQL world regions list157.93 KB

Objective

Get latitude and longitude from a Google Address when an user type in an input form

HTML

<form method="post">
    <input id="place" name="place" type="text" placeholder="Address">
    <input id="lat" name="lat" type="hidden" value="">
    <input id="lng" name="lng" type="hidden" value="">
 
     <input id="submit-search" type="submit" value="Send">
</form>
 
<!-- call Google Maps javascript files, note libraries=places and language -->
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places&language=es_ES"></script>

Javascript

<script>
var input = (document.getElementById('place'));
var searchBox = new google.maps.places.SearchBox((input));
var places;
 
google.maps.event.addListener(searchBox, 'places_changed', function() {
    places = searchBox.getPlaces();
 
    // if Google returns something, assign latitude and longitude
    if (places[0]) {
        $('#lat').val(places[0].geometry.location.lat());
        $('#lng').val(places[0].geometry.location.lng());
    }
});
 
// avoid submit by return key
$("#place").on("keypress", function(e) {
    if (e.keyCode === 13) return false;
});
</script>

Objective

Create a module and a new block that will call an ajax function to show some info dynamically

Summary

  • Step 1: create your module
  • Step 2: call hooks 'block_info' and 'block_view' for a new block
  • Step 3: create function for block content
  • Step 4: create javascript file with the ajax call inside your module
  • Step 5: add hook menu for ajax call
  • Step 6: create function for ajax callback
  • Step 7: css styles

Step 1: create custom module

  • Create '.module' and '.info' files inside your Drupal installation. Can be in 'drupal/sites/all/modules/example' or 'drupal/sites/default/modules/example'

example.info

;$Id$
name = Example module
description = Example module for a block with an ajax call
package = Example modules
core = 7.x
files[] = example.module
;dependencies[] = autoload
;php = 5.3
version = "7.x-1.0"

Step 2: call hooks 'block_info' and 'block_view' for a new block

example.module

function example_block_info() {
 
    $blocks['example_name_block'] = array(
            'info' => t('This will be the block title'),
            'status' => 1,
            'cache' => DRUPAL_NO_CACHE // this will exclude the block from Drupal cache
    );
 
    return $blocks;
}
 
/**
 * This hook generates the contents of the blocks themselves.
 */
function example_block_view($delta = '') {
 
    switch ($delta) {
        case 'example_name_block': // note the same name from the block_info
            $block['subject'] = '';
            $block['content'] = example_block_content(); // this function will print the block content
 
            // call javascript file
            drupal_add_js(drupal_get_path('module', 'example') . '/js/example.js');
 
            // call css file
            drupal_add_css(drupal_get_path('module', 'example') . '/css/example.css');
    }
    return $block;
}

Step 3: create function for block content

/**
 *  Output search block content
 * @return string
 */
function example_block_content() {
    global $base_url;
 
    // Keep the title value if we have the block in every page 
    $title = isset($_GET['title']) ? $_GET['title'] : "";
 
    $output ='       
            <div class="row form-search-example">
                <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                    <h2>Search form example</h2>
                    <form class="example-form" method="get">
                        <input type="text" id="title" name="title" autocomplete="off" value="'. $title .'"  placeholder="' . t('Type article title') .'">
                        <button type="submit" class="submit"><i class="fa fa-2x fa-search"></i> </button>
                    </form>
                </div>
            </div>
          <div id="form-ajax-results"></div>
    ';
    return $output;
}

Step 4: create javascript file with the ajax call inside your module

  • Example: drupal/sites/default/modules/example/js/example.js
  • We are going to autocomplete an article/page title when an user type something in the title field
(function($) {
Drupal.behaviors.example_search = {
  attach: function (context, settings) {
    //code starts
 
    $(".example-form").on("keyup", "#title", function () {
        var title = $(this).val();
        $.ajax({
            url: Drupal.settings.basePath + 'example/ajax/search',
            type: 'post',
            data: 'title=' + title,
            dataType: 'json',
            success: function (data) {
                if (data.success === true) {
                    $('#form-ajax-results').removeClass('hide-form-search');
                    $('#form-ajax-results').addClass('show-form-search');
                    $('#form-ajax-results').html(data.content);
                } else {
                    $('#form-ajax-results').addClass('hide-form-search');
                    $('#form-ajax-results').removeClass('show-form-search');
                }
            }
        });
    }); // end keyup   
 
    //code ends
  }
};
})(jQuery);

Step 5: add hook menu for ajax call

/**
 * Implements hook_menu().
 */
function example_menu() {
 
    $items['example/ajax/search'] = array(
        'page callback' => 'example_ajax_serach',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK,
    );
 
    return $items;
}

Step 6: create function for ajax callback inside your module

/**
 * AJAX: search
 */
function example_ajax_search() {
    global $base_url;
 
    $title = $_POST['title'];
    $found = false;
    $output = null;
    if (strlen($title)>3) {
        // Query article and page content type
        $query = db_select('node', 'n')->fields('n', array('title','nid'));
        $db_or = db_or();
        $db_or->condition('n.type', 'article');
        $db_or->condition('n.type', 'page'); 
 
        $results = $query->condition($db_or)
        ->condition('n.title','%'.$title.'%','LIKE')
        ->orderBy('n.title', 'ASC')
        ->range(0,10)
        ->execute()
        ->fetchAll();
 
        if (!empty($results)) {
            $found = true;
            foreach ($results as $node) {
                // get the alias url 
                $url = drupal_get_path_alias("node/" . $node->nid);
                $output .= '
                    <div class="ajax-content-selector" data-title="'.$node->title.'">
                        <a href="'.$url.'" title="' . $node->title . '">' . $node->title . '</a>
                    </div>';
            }
        }
    } 
 
    echo json_encode(array('success' => $found, 'content' => $output));
 
    module_invoke_all('exit');
    exit;
}

Step 7: add css file

  • Example: drupal/sites/default/modules/example/css/example.css
.show-form-search {
    background-color: #fff;
    border: 1px solid #d4d4d4;
    color: #000;
    display: block;
    margin: -32px 0 10px 240px;
    padding: 5px 20px 2px;
    position: absolute;
    text-align: left;
    width: 433px;
    z-index: 99999;
}
 
.hide-form-search {
    display:none;
}
// focus first visible element after load Bootstrap modal
$('.modal').on('shown.bs.modal', function (e) {
    $(this).find('input, textarea, select').filter(':visible:first').focus(); 
});
  • Simple ajax example to show some info every 3 seconds, loading it from php in your plugin or theme functions.php file

Javascript

  • Include this code in your theme header.php for example
<script type="text/javascript">
    jQuery(document).ready(function() {
        function refreshData()
        {
            jQuery.ajax({
                url: <?php echo admin_url('admin-ajax.php'); ?>, 
                data: 'action=function_example',
                success: function(data) {
                    jQuery('#ajax-results').html(data);
                }
            });
        }
 
        refreshData();
        var auto_refresh = setInterval(function(){ refreshData() }, "3000");
    });
</script>
 
<!-- div to refresh -->
<div id="ajax-results"></div>

PHP

  • Include this in your plugin or theme functions.php
function function_example()
{
    // echo whatever you need to show it every 3 seconds...
    echo "Whatever you want";
}
 
add_action( 'wp_ajax_function_example', 'function_example' );
/**
 * Filter main search with post content type only
 * @param object $query
 * @return object
 */
function search_filter($query) {
    if ($query->is_search) {
        $query->set('post_type', 'post');
    }
    return $query;
}
add_filter('pre_get_posts','search_filter');

Summary

  • Step 1: create page from WordPress admin and note the url slug
  • Step 2: create a file in your active theme named 'page-url-slug.php'
  • Step 3: load WordPress header and footer in the file

Step 1: create page from WordPress admin and note the url slug

  • Just create a simple page from your WordPress installation, wp-admin.php > New Page
  • Call it 'example', the url slug will be that.

Step 2: create a file in your active theme named 'page-url-slug.php'

  • Inside your theme, create a file called 'page-example.php', something like that: wordpress/wp-content/themes/your-active-theme/page-example.php

Step 3: load WordPress header and footer in the file

  • 'page-example.php' content:
<?php get_header(); ?>
 
// Your code goes here
 
// You can use whatever WordPress function, like global objects like $wpdb or user functions
 
<?php get_footer(); ?>

Páginas