WordPress – jak v PHP nastavit cron (wp_cron)

Dnes si ukážeme jak v pluginu pro WordPressu nastavit wp_cron. Cron je script (ve WP světě funkce) který se spustí vždy v požadovanou dobu.

Jediné případné použití je na hostingu, který nepodporuje cron, nebo má omezený počet úloh pro cron. Wp_cron totiž funguje tak, že když přijde návštěvník na web, podívá se zda uplynula doba na spuštění cron úlohy. Pokud doba uplynula spustí cron úlohu a poznamená si čas kdy tato úloha byla naposledy spuštěna aby věděl kdy ji spustit příště.

To je fajn ale má to několik nedostatků:

  • Pokud na Váš web za celý den nepřijde žádný člověk, nevykoná se cron pro hourly četnost ani jednou (normálně by se vykonal 24x)
  • Pokud máte cron úlohu, která se vykonává dlouho, návštěvník který tuto úlohu „spustil“ musí počkat než doběhne aby se mu zobrazila požadovaná stránka

Raději doporučuji spouštět kód klasickým cronem.

Ukázka nejjednoduššího cronu, který se vykoná každou hodinu – odesílá email:

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  wp_mail( 'your@email.com', 'Automatic email', 'Automatic scheduled email from WordPress.');
}

Cron pro WordPress plugin

U pluginu je nejrozumnější cron zapnout při aktivaci pluginu. Nezapomeňte cron opět odebrat při deaktivaci pluginu.

Jak zjistím, že plugin byl aktivován nebo deaktivován?

function activate_plugin_name() {
   //plugin byl aktivovan
}

function deactivate_plugin_name() {
   //plugin byl deaktivovan
}
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

Jednoduché, ale stálo mne to dost vlasů 🙂 Finální kód pro plugin:

/**
 * Tento kod se vykona pri aktivaci pluginu
 */
function activate_plugin_name() {
   if( !wp_next_scheduled( 'mycronjob' ) ) {
      wp_schedule_event( time(), 'hourly', 'mycronjob' );
   }
}
/**
 * Tento kod se vykona pri deaktivaci pluginu
 */
function deactivate_plugin_name() {
   wp_clear_scheduled_hook('mycronjob');
}
//hook pro aktivaci a deaktivaci pluginu
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

/**
 * Funkce s vykonym kodem pro cron ulohu
 */
function my_repeat_function() {
   file_put_contents( realpath(dirname(__FILE__)) . "/cron.txt", date( "d.m.Y H:i:s" ) . " cron\n", FILE_APPEND);
}

Doufám, že pomůže 🙂

Android aplikace + New Relic

Pro analýzu používání a padání Android aplikací se mi osvědčil New Relic (mimochodem, je super i na server). V základní verzi je zadarmo. Obsahuje základní informace které pro malé aplikace bohatě stačí (v kombinaci New relic + Google play API mi momentálně nechybí žádná funkčnost). Pro mne nejužitečnější je crash list report, kde vidíte všechny pády vaší aplikace včetně mnoha informací (jaké to bylo zařízení, verze Androidu , …), Je naivní si myslet, že když aplikace funguje na mém zařízení, bude fungovat všude… Vždy jsem matně vzpomínal jsem jsem New Relic do aplikace dostal. To co stačí udělat naleznete v tomto videu:

Ať slouží 🙂

Android: GPS souřadnice zařízení

V dnešním článku si ukážeme jak z Android zařízení získat aktuální GPS polohu. K získání polohy použijeme LocationListener.

Oprávnění pro přístup k poloze

Do AndroidManifest.xml přidáme následující oprvnění:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Používáme Android LocationManager

Activita ve které chceme zjistit GPS polohu musíme implementovat rozhraní LocationListener (z package android.location.LocationListener)

public class MainActivity extends Activity implements LocationListener {
    
    private LocationManager locationManager;

kde následně musíme přetížit tyto metody:

    @Override
    public void onLocationChanged(Location location) {
        Log.d("GPS", "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude());
        Toast.makeText(getActivity(), "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude(), Toast.LENGTH_LONG).show();
        locationManager.removeUpdates(this);//stop gps changes, only ONE
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned ON", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned OFF", Toast.LENGTH_SHORT).show();
    }

Vynutíme získání polohy:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
 
   locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
   locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, this);
}

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, this) kde parametry funkce:

provider provider pro zjištění polohy
minTime minimální interval pro aktualizaci polohy (v milisekundách)
minDistance minimální vzdálenost mezi aktualizacemi (v metrech). Pokud nepotřebujeme změnu po metrech, nastavíme na 0 -> tím se bude aktualizovat pouze podle česového intervalu (minTime)
listener listener jehož metoda onLocationChanged(Location) se zavolá s každou změnou

Pokud budeme chtít listener pro zjišťování polohy ukončit, zavoláme:

locationManager.removeUpdates(this);

Všimněte si že první zjištění polohy trvá docela dlouho a zařízení se zahřívá více než obvykle. I baterie ubývá rychleji než obvykle 🙂 Příště si ukážeme šetrnější způsob jak zjišťovat polohu zařízení, který při prvním spuštění rychle vrátí naposledy známou polohu a poté ji zpřesní, nebo jak zjistit, že GPS je vypnuta.

Jak nainstalovat Bower pod Windows

Minule jsme si nainstalovali Grunt a vytvořili package.json

Nyní se rovnou pustíme do instalace Boweru. Bower nainstalujeme globálně abychom ho mohli použít kdekoliv:

npm install -g bower

Také Bower nainstalujeme lokálně aby se přidal do projektu (package.json)

npm install bower --save-dev

Inicializujeme Bower (vytvoří soubor bower.json):

bower init

 

Hledání balíčků

Existují 2 způsoby jak najít balíček pro Bower. Buď přes webový prohlížeč nebo přes příkazovou řádku.

Chcete li vyhledat balíček přes příkazovou řádku, použijte následující příkaz:

bower search <balicek>

Pro vyhledání balíčku obsahující slovo jQuery použijeme příkaz:

bower search jquery

Tento příkaz vrátí spoustu výsledků:

    jquery git://github.com/components/jquery.git
    jquery-ui git://github.com/components/jqueryui
    jquery.cookie git://github.com/carhartl/jquery-cookie.git
    jquery-placeholder git://github.com/mathiasbynens/jquery-placeholder.git
    jquery-file-upload git://github.com/blueimp/jQuery-File-Upload.git
    jasmine-jquery git://github.com/velesin/jasmine-jquery
    jquery.ui git://github.com/jquery/jquery-ui.git
    ...

Každý balíček odkazuje na Git repozitář.

Instalace Balíčků

bower install jquery#1.*.* --save-dev         //last version jquery 1.x.x
bower install nette-forms --save-dev
bower install bootstrap --save-dev
bower install bootstrap-sass-official --save-dev
bower install jquery-smooth-scroll --save-dev
bower install font-awesome --save-dev

Android: Začínáme s Volley

Knihovnu Volley vyvinula společností Google. Slouží pro rychlou a snadnou komunikaci přes internet v systému Android. Dnes si ukážeme jak Volley používám pro stahování dat z internetu. Především stahování dat z REST API.

Do knihovny Volley přispěl svým kódem můj kolega Zdeněk Kořán 🙂

Gradle v Android Studiu

Pro všechny mé projekty pro Android používám Android Studio. Je to ideální volba. Zprovoznění simulátoru a nainstalování SDK (oproti Eclipse) je velice jednoduché a příjemné.

Gradle je nástroj pro automatizaci. Slouží k: build, CI, deployment, generování dokumentace, … Po vytvoření nového projektu v Android Studio je Gradle výchozí nástroj.

Přidání Volley knihovny do projektu v Android Studiu

Vytvořte v Android Studio nový projekt. Otevřete soubor build.gradle do kterého doplníme závislost:

// /app/build.gradle
// ...

dependencies {
  // ...
  compile 'com.mcxiaoke.volley:library:1.0.+'
}

Lepší je načíst poslední verzi knihovny Volley: File -> Project Structure… -> app -> Dependencies -> Add -> Library dependency kde v modálním okně vyhledáme „com.mcxiaoke.volley:library“ kterou přidáte. Hotovo 🙂

Soubor build.gradle pak vypadá takto:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "cz.vencax.beerdroid.beerdroid"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
    compile 'com.android.support:support-v4:22.0.0'
    compile 'com.mcxiaoke.volley:library:1.0.+'
}

Použití Volley knihovny

Volley knihovnu již máme naimportovanou. Pojďme ji začít používat k stahování obsahu z internetu. Kdybychom nepoužili Volley museli bychom obsah stahovat v samostatném vlákně přes AsyncTask. S Volley to je jednoduché. Volley pro požadavky ke stažení používá Request Queue. Pro globální frontu požadavků si vytvoříme statickou třídu VolleySingleton.

VolleySingleton.java:

import android.content.Context;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class VolleySingleton {

    private static VolleySingleton mInstance;
    private RequestQueue mRequestQueue;
    private static Context mCtx;

    private VolleySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
    }

    public synchronized static VolleySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new VolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }
}

Přidáme oprávnění pro přístup na internet (<uses-permission android:name=„android.permission.INTERNET“ />):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cz.vencax.beerdroid.beerdroid" >

    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
       //...
    </application>

</manifest>

 Stažení JSONu přes Volley

Nyní máme vše připraveno a můžeme začít stahovat obsah z internetu přes Volley.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> volley
        JsonObjectRequest request = new JsonObjectRequest("http://cblunt.github.io/blog-android-volley/response.json", null,
                new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
                    }
                },

                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(), "EROOR: " + error.toString(), Toast.LENGTH_SHORT).show();
                    }
                }
        );

        VolleySingleton volleySingleton = VolleySingleton.getInstance(getApplicationContext());

        volleySingleton.getRequestQueue().add(request);
        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< volley
    }

Jak sami vidíte, s knihovnou Volley je stahování zdrojů z internetu velice jednoduché a rychlé. Sám Google ji používá u svých služeb (Google Play, Youtube, …), nemusíte se tudíž bát že Vaši aplikaci zpomalí.

Mne tato knihovna ušetřila spousty vlasů na hlavě 🙂

Na co si dát pozor

U JSONu se rozlišují 2 typy. Pozor na to při requestu.

JSONObject

začíná znakem {

JSONArray

začíná znakem [

První projekt s Apache Wicket

Jeden z nejlepších webových frameworků pro programovací jazyk Java je Apache Wicket. V dnešním článku si ukážeme jak ho rozchodit na Windows.

Maven

Maven je mocný nástroj pro správu projektů. My ho použijeme pro Wicket Quickstart

  1. http://maven.apache.org/download.html
  2. Stáhnout apache-maven-3.3.1-bin.zip
  3. Stažený Maven rozbalíme do: C:\apache-maven-3.3.1
  4. Přidáme proměnné prostředí s názvem MAVEN_HOME s hodnotou C:\apache-maven-3.3.1
  5. Do proměnného prostředí s názvem Path přidáme (na úplný konce, nezapomeňte na středník!):
    ;C:\apache-maven-3.3.1\bin
  6. Restartujeme PC. Maven je nainstalován. Vyzkoušejte jeho správnou funkčnost: Start -> cmd
    mvn -version

    Zobrazí se verze nainstalovaného Mavenu

Instalace Eclipse

Eclipse je nástroj, který je zdarma a vřele ho doporučuji všem začátečníkům.

  1. http://www.eclipse.org/downloads/
  2. Stáhněte Eclipse IDE for Java EE Developers
  3. Stáhne se zip soubor, který stačí rozbalit a rovnou spustit eclipse.exe (neinstaluje se)

Vytvoření Wicket projektu

Na stránce: https://wicket.apache.org/start/quickstart.html naklikáme vlastnosti (můžeme nechat defaultní) a v cmd vykonáme Command line kód:

mvn archetype:generate -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=6.19.0 -DgroupId=com.mycompany -DartifactId=myproject -DarchetypeRepository=https://repository.apache.org/ -DinteractiveMode=false

Kód vytvoří nový projekt ve složce myproject

Spuštění Wicket projektu v Eclipse

v příkazové řádce se dostaneme do projektu:

cd myproject

Nyní spusťte příkaz:

mvn eclipse:eclipse

Tím se vytvoří soubory: .project, .settings, a .classpath které vyžaduje Eclipse.

Nyní naimportujeme projekt do Eclipse. V menu vyberte: File->Import->General->Existing Project into Workspace

V levé části Eclipse najedeme na soubor: src/test/java kde nás zajímá soubor Start.java klikneme na něj pravým tlačítkem a vybereme: Debug as… -> Java Application. Ve spodní části eclipse je Console ve které můžete vidět spouštěná webového serveru.

Správnou funkčnost Wicketu otestujete zobrazením adresy: http://localhost:8080 na které vás vítá Apache Wicket

MySQL vzdálenost GPS souřadnic

Jak v MySQL spočítat vzdálenost mezi 2 body? Použijeme uloženou proceduru:

DROP FUNCTION IF EXISTS `gps_distance`;

DELIMITER $$
CREATE FUNCTION `gps_distance` (lat1 float, lng1 float, lat2 float, lng2 float) RETURNS float
BEGIN
 
    SET lat1 = lat1 * pi() / 180;
    SET lng1 = lng1 * pi() / 180;
    SET lat2 = lat2 * pi() / 180;
    SET lng2 = lng2 * pi() / 180;
 
    RETURN acos
    (   cos(lat1)*cos(lng1)*cos(lat2)*cos(lng2)
      + cos(lat1)*sin(lng1)*cos(lat2)*sin(lng2)
      + sin(lat1)*sin(lat2)
    ) * 6372.795;
 
END$$

DELIMITER ;

 

Jak v jQuery vytvořit jednoduchý doplněk

Dělám doplněk který zobrazuje Google mapu. Doplněk umožňuje zobrazit několik markerů na mapě, nebo zobrazit 1 marker kterým je možné uživatelsky vybrat pozici. Nyní bych potřeboval rozšířit tento doplněk o možnost zadání souřadnic markeru z venku doplňku.

Jak to nyní funguje

<div id="google-map">v tomto divu je zobrazena mapa na které je marker</div>

Úkolem je této mapě (map může být na stránce více) nastavit souřadnice markeru.

Vyřešení

Do JavaScriptu pro zobrazení mapy přidám následující kód:

$( document ).ready( function() {

  $.fn.setMarkerPosition = function(lon, lat){
    $(this).css("border", "pink solid 10px");//at je to videt :-)
    alert("lon: " + lon + ", lat: " + lat );
    return this;
  };
  //...

Nyní stačí zavolat námi vytvořenou funkci setMarkerPosition()

$( "div#nette-g-map-canvas" ).setMarkerPosition( 1.1111, 2.2222 );

 

Google Analytics: Změna URL

Dost často se setkávám se stránkami které mají veškerý svůj obsah na jedné dlouhé stránce. Stránka je rozdělena na sekce a při zobrazení sekce se změní URL adresa (většinou se změní hashtag: #kontakt, #nabidka, #kontaktni-formular, … )

Pokud na tokovou stránku nasadíte Google Analytics, měření nebude dávat smysl (uvidíte statistiky pouze pro jednu stránku). Nebudete vědět jaké sekce uživatele zajímají, na jaké sekce přicházejí, z jakých sekcí odcházejí,….

Tento problém jsem vyřešil zajímavým způsobem. Pokud dojde ke změně URL (změní se hashtag), pošlu do Google Analytics zprávu o tom kde se nachází uživatel:

var page = location.pathname + "#"+ hashtag;
ga( 'send', 'pageview', page );

Kde location.pathname je cesta aktuální URL.

 

Breadcrumbs – drobečková navigace

Co je to breadcrumbs?

Breadcrumbs neboli drobečková navigace je sada odkazů které mohou uživateli pomoci pochopit a procházet hierarchii stránek. Příklad:

Webmaster ToolsHelp articlesMy site and GoogleCreating Google-friendly sites

Přidáte-li breaderumbs navigaci na Vaše stránky pomůžete vyhledávačům pochopit navigaci na stránkách a vyhledávače tuto informaci začnou prezentovat při vyhledávání:

breadcrumbs

 Ukázka použití

<div itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <a href="http://www.example.com/knihy" itemprop="url">
    <span itemprop="title">Knihy</span>
  </a> ›
  <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
    <a href="http://www.example.com/knihy/autori" itemprop="url">
      <span itemprop="title">Autoři</span>
    </a> ›
    <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
      <a href="http://www.example.com/knihy/autori/bozena-nemcova" itemprop="url">
        <span itemprop="title">Božena Němcona</span>
      </a>
    </div>
  </div>
</div>

 Ověření správné funkčnosti

Správnost konfigurace drobečkové navigace můžete ověřit na adrese: https://developers.google.com/structured-data/testing-tool/