Made in China - Paranoidní povídka na dobrou noc

China právě vyhlásila jednostranné embargo na vývoz výrobku vyrobených na jejich území. USA a prakticky celá Evropa se potýká s akutním nedostatkem výrobků určených k běžné spotřebě. Chybí zejména elektronika, plastové a kovové výrobky a léků. Díky embargu došlo k ohrožení ekonomické stability řady firem. Na hranici bankrotu se pohybují firmy jako Apple, IKEA nebo Mattel. Ty se překotně snaží alespoň o částečnou obnovu výroby. Rovněž se pokoušejí přesunout výrobu do svých domovských států. Potýkají se se zoufalým nedostatkem odborníků a extrémní finanční náročností nechtěného stěhování. Prezident USA se tento týden sejde s představiteli Evropské Unie. Společně se pokusí dohodnout alespoň částečnou obnovu exportu výrobků vyrobených na území Chiny. Cílem je vyhnou se celosvětovému ekonomickému kolapsu. A zamezení chaosu do kterého se postupně propadají jednotlivé státy. O dalším vývoji situace Vás budeme průběžně informovat.

WYSIWYG pro popis uživatele ve Wordpress

Následující kratičký kód zobrazí #WYSIWYG editor u popisu autora u uživatelského profilu: Kód stačí přidat do function.php ve vašem template:

<?php
/**
 * WYSIWYG pro uzivatelsky profil Wordpress
 *
 * @author Roman Ozana <ozana@omdesign.cz>
 */
class CustomUserProfile {

  /** @var array */
  private $tinymceOptions = array(
    'teeny' => true,
    'quicktags' => false,
    'media_buttons' => false, 'textarea_rows' => 8,
    'wpautop' => false,
    'tinymce' => array(
      'theme_advanced_buttons1' => 'p, bold, italic, ul, |,link,unlink,code',
      'theme_advanced_buttons2' => '',
      'theme_advanced_buttons3' => '',
      'theme_advanced_buttons4' => '',
    ),
  );

  public function __construct() {
    add_action('show_user_profile', array($this, 'initDescriptionWysywig'));
    add_action('edit_user_profile', array($this, 'initDescriptionWysywig'));
  }

  /**
   * Wysywig editor take pro description
   *
   * @param $options
   */
  public function initDescriptionWysywig($options) {
    if ( ! class_exists('_WP_Editors' ) )
      require_once( ABSPATH . WPINC . '/class-wp-editor.php' );

    $options = _WP_Editors::parse_settings('description', $this->tinymceOptions);
    _WP_Editors::editor_settings('description', $options);
    wp_print_styles('editor-buttons');
  }

}
new CustomUserProfile();

#wordpress #php

Hash tags pro Wordpress

Napsal jsem velmi jednoduchý plugin, který přidává do Wordpress podporu pro hash tagy:

<?php
/*
Plugin Name: Hashs
Description: Twitter like hash for Wordpress
Version: 1.0
Author: Roman Ozana <ozana@omdesign.cz>
Author URI: http://www.omdesign.cz/
*/
class Hashs {

  const PATTERN = '/\B#([^\s\W#]+)/i';

  /**
   * @param string $content
   * @return string mixed
   */
  public static function processContent($content) {
    return preg_replace(Hashs::PATTERN, '<a href="' . get_home_url(null, '/tag/$1') . '" class="tag">#$1</a> ', $content);
  }

  /**
   * Auto hash tags
   *
   * @param $post_id
   * @return bool
   */
  public static function addAutoTags($post_id) {
    $post = get_post($post_id);
    preg_match_all(Hashs::PATTERN, $post->post_content, $matches);
    if (!isset($matches[1])) return;
    wp_set_object_terms($post_id, $matches[1], 'post_tag', false); // replace
  }
}

add_filter('the_content', array('Hashs', 'processContent'), 1);
add_action('save_post', array('Hashs', 'addAutoTags'));

Povšimněte si zejména řádku wp_set_object_terms($post_id, $matches[1], 'post_tag', false); ten totiž ukládá nalezené tagy k postu. Pokud je poslední hodnota true, provede append (přidání ke stávajícím tagům). Pokud je false, provede nahrazení všech tagů u postu nalezenými hashtagy.

Zdrojový kód ke stažení zde: https://bitbucket.org/OzzyCzech/omhashtag

Zjištění práv k souboru nebo adresáři v PHP

function getPermisions($file) {
  return (is_dir($file) || is_file($file)) ? substr(decoct(fileperms($path)), -4) : '0000';
}

Nebo pro kontrolu, zda jsou práva dostatečná:

function hasPermisions($path, $permission = 777) {
  $current = substr(decoct(fileperms($path)), $permission > 1000 ? -4 : -3);
  return ($current > $permission);
}

Jak správně přepsat ojeté auto

Popíšu jak to probíhalo u mě. Kupoval jsem ojeté auto přímo od majitele. Platil jsem hotově bez úvěru. Auto má platnou technickou prohlídku a emise do roku 2015.

  1. uzavřeli jsme s majitelem kupní smlouvu, kde byl uveden VIN kód auta
  2. poslal jsme mu peníze na účet
  3. původní majitel odhlásil auto na spádovém dopravním inspektorátu (Praha)
  4. prostřihli mu tam malý TP
  5. do velkého TP mě jménem uvedl jako budoucího nového majitele (ušetří se tím plná moc v budoucnu)
  6. na VIN jsem si uzavřel s pojišťovnou povinné ručení
  7. původní majitel si teď už mohl své povinné ručení zrušit

S prostřiženým malým TP je možné jezdit bez úhony 10 dní, pak už se jedná o přestupek. Ale nikdy nesmíte vyjet na cestu s nepojištěným autem - proto povinné ručení. Je to dokonce tak přísné, že na smlouvě o povinném ručení je uvedena i hodina uzavření. Zelenou kartu tedy musíte mít v ruce už při převzetí auta od původního majitele. Rovněž auto nesmí na silnici pokud nemá platnou STK. To si jej pak musíte nechat odtáhnout rovnou na stanici STK a pokusit se ji obnovit. Pokud chcete s autem jezdit, musíte do 10 dní dokončit úplný přepis na sebe. Což provedete na svém spádovém dopravním inspektorátu. V mém případě to je Ostrava - podle trvalého bydliště. Jedná se tedy o přepis mezi dvěma kraji. Což znamená automaticky nutnost výměny registračních značek vozidla. Pokud se jedná pouze o přepis v rámci kraje, není výměna značek povinná. Záleží na novém majiteli, zda nové značky chce a připlatí si za ně. Pro dokončení přepisu budete potřebovat spoustu papírů: - občanku (doklad totožnosti) - doklad o způsobu nabytí vozidla (u mě kupní smlouva) - původní (staré) registrační značky vozidla - osvědčení o registraci vozidla část II (tzv. velký technický průkaz) - osvědčení o registraci vozidla část I (tzv. malý technický průkaz - ten prostřižený) - plnou moc k přepisu vozidla, pokud Vás majitel neuvedl jako budoucího majitele při odhlášení auta (což mě uvedl, takže jsem nepotřeboval) - doklad o technické prohlídce (zápis o platné pravidelné technické prohlídce v technickém průkazu nebo protokol o pravidelné technické prohlídce vystavený STK) - doklad o sjednání pojištění odpovědnosti z provozu vozidla (tzv. povinné ručení) tzv. zelená karta - žádost o přepis vozidla (dostanete a vyplníte na inspektorátu) - protokol o evidenční kontrole silničního motorového (viz. níže)

Pro úspěšný přepis auta potřebujete tzv. protokol o evidenční kontrole silničního motorového vozidla - ten získáte na jakékoliv stanici STK v ČR. K získání protokolu je nutné: - ukázat občanku - malý a velký technický průkaz - a auto.

Celkově záležitost na 5 minut. Pracovník STK zkontroloval VIN, barvu vozidla, stav tachometru a číslo motoru. Stálo to kolem 200 Kč. Platnost protokolu je opět 10 dní. Po předložení všech náležitostí jsem na inspektorátu dostal nové ostravské značky a nový neprostřižený malý technický průkaz. Všechno byla záležitost cca na 10 minut. Stálo to na správních poplatcích 800 Kč. Kopii velkého technického průkazu jsem pak ještě poslal na pojišťovnu a ta mi obratem poslala novou zelenou kartu, kde je uvedena moje nová registrační značka. Ještě malý dodatek. Pokud je v autě na skle nalepená dálniční známka, zneplatní se výměnou značek. Dálniční známku si prý můžete nechat vyměnit na jakékoliv větší poště. Stačí k tomu původní známka a nový technický průkaz. Ještě jsem to nestihl udělat, takže přesně nevím.Petr Novák: Dovoluji si doplnit, že podle odkazované stránky České pošty se při výměně značky dálniční známka nemění a zůstává platná, specificky to zmiňuje bod 2.13 jejich metodického pokynu. (Možná to změnili, podle hlaviček ta stránka byla aktualizovaná 27. května letošního roku.)

Popis výměny dálniční známky najdete na stránkách České Pošty. #posta #auto #how-to #registrace

Jak spočítat počet řádků kódu?

V mém příkladu počítám počet řádků PHP kódu:

grep -v '^ *$' `find . -iname "*.php"` | wc -l

Pro zajímavost takový Wordpress má více jak 250 000 řádků PHP.

Jak okopírovat adresář s celým obsahem v PHP

Složitých a ošklivých funkcí pro kopírování adresářů a podadresářů vč. jejich obsahu jsem viděl několik. Tahle celkem běžná úloha jde vyřešit i jednoduše pomocí PHP iterátoru:

$source = "/foo/bar/dir";
$dest= "/dest/dir";

foreach (
 $iterator = new RecursiveIteratorIterator(
  new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
  RecursiveIteratorIterator::SELF_FIRST) as $item
) {
  if ($item->isDir()) {
    mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
  } else {
    copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
  }
}

Výpočet hash objektu v PHP

Funkce spl_object_hash() má jednu nevýhodu, její výsledek se v čase mění. Pokud objekt naplníte stejnými hodnotami, dostanete při dvou requestech dva různé výsledky. Což nemusí být vždy žádoucí. Někdy potřebujete objekt identifikovat na základě jeho vnitřních hodnot pomocí neměnného řetězce. Takový hash můžete snadno získat například takto:

class Foo {
 private $p;
 public function setProperty($p) {
  $this->p = $p;
 }
 // vypocita hash objektu na zaklade hodnot jeho propert
 public function __toString() {
  return md5(http_build_query(get_object_vars($this)));
 }
}

Pro vypsání/získání hash pak stačí:

$bar = new Foo();
$bar->setProperty('25');
echo $bar;
$hash = (string) $bar;

Odstranění odkazů z admin menu Wordpress

Pro manažer odkazů #wordpress jsem nenašel nikdy smysluplné využití. Proč ho rovnou z menu neodstranit? Stejně tam jen zavazí:

add_action('admin_menu', function(){
  remove_menu_page('link-manager.php');
});

Obdobně je možné odstranit cokoliv dalšího např. remove_menu_page('edit-comments.php'); - odstraní odkaz na komentáře.

Case insensitive in_array v PHP

PHP funkce in_array je case sensitive - což se nemusí vždy hodit. Občas potřebujete prohledat pole a nezáleží Vám na velikosti písmen u jeho prvků:

$array = array('a', 'B', 'cE');

function inArrayCaseInsensitive($needle, $array) {
 return (bool) preg_grep('/^' . preg_quote($needle, '/') . '$/i', $array);
}

inArrayCaseInsensitive('a', $array); // true
inArrayCaseInsensitive('A', $array); // true
inArrayCaseInsensitive('ce', $array); // true
inArrayCaseInsensitive('be', $array); // false

Funkce preg_grep má ještě zajímavý přepínač PREG_GREP_INVERT. Tímto přepínačem odfiltrujete všechny hodnoty v poli, které neodpovídají zadanému regulárnímu výrazu. Filtrace zachovává klíče pole.

$array = array('a', 'A', 'cE');

function filterArrayValues($needle, $array) {
 return preg_grep('/^' . preg_quote($needle, '/') . '$/i', $array, PREG_GREP_INVERT);
}

print_r(filterArrayValues('a', $array)); // vypíše jen cE