PHP функции для записи логов в файл

function silver_logs_to_file($output, $filename = 'log') {
	$time = date( "d/m/y, H:i:s") . ' - ';
	$content = $time .  print_r($output, true) . PHP_EOL;
	$filename = __DIR__ . '/logs/' . $filename . '.log';
    $fh = fopen($filename, "a");
    fwrite($fh, $content);
    fclose($fh);
}

 

Пагинация в ACF Repeater

Advanced Custom Fields это ‘must have’ плагин для создания любого сайта на Worpdress. Он позволяет с лёгкостью создавать, управлять и выводить произвольные поля в любом месте вашего шаблона. И его функционал можно ещё больше расширить используя дополнение Repeater Field.  Но страница на которой используется Repeater может получится слишком большой, если вы используете много записей и возможно вам придётся использовать для неё пагинацию. И сейчас я покажу вам как это сделать.

В этом примере, мы будем добавлять пагинацию к полю image_gallery, с дочерним полем image которое содержит объект изображения. Наш Repeater будет на странице с ссылкой /gallery.

На странице будет выведено 10 изображений и ссылки под ними позволят пользователю переходить по страницам галереи. Наши ссылки будут иметь вид /gallery/2/, /gallery/3/ и т.д.

Ну и собственно сам код:

<?php
/* 
 * Paginate Advanced Custom Field repeater
 */

if( get_query_var('page') ) {
  $page = get_query_var( 'page' );
} else {
  $page = 1;
}

// Variables
$row              = 0;
$images_per_page  = 10; // How many images to display on each page
$images           = get_field( 'image_gallery' );
$total            = count( $images );
$pages            = ceil( $total / $images_per_page );
$min              = ( ( $page * $images_per_page ) - $images_per_page ) + 1;
$max              = ( $min + $images_per_page ) - 1;

// ACF Loop
if( have_rows( 'image_gallery' ) ) : ?>

  <?php while( have_rows( 'image_gallery' ) ): the_row();

    $row++;

    // Ignore this image if $row is lower than $min
    if($row < $min) { continue; }

    // Stop loop completely if $row is higher than $max
    if($row > $max) { break; } ?>                     
    
    <?php $img_obj = get_sub_field( 'image' ); ?>
    <a href="<?php echo $img_obj['sizes']['large']; ?>">
      <img src="<?php echo $img_obj['sizes']['thumbnail']; ?>" alt="">
    </a>

  <?php endwhile;

  // Pagination
  echo paginate_links( array(
    'base' => get_permalink() . '%#%' . '/',
    'format' => '?page=%#%',
    'current' => $page,
    'total' => $pages
  ) );
  ?>

<?php else: ?>

  No images found

<?php endif; ?>

Источник: http://jonathannicol.com/blog/2014/03/06/paginating-an-advanced-custom-fields-repeater/

How to convert a string to a boolean (the right way)

There are a couple of ways to convert a string variable to a boolean variable in Javascript. However, when doing this, you have to be kind of careful: it’s kind of easy to mess up this sort of logic and doing it wrong can result in some nasty bugs. So, in order to save you a headache or two, I’ve detailed how to do it properly in this article. Read on, if you’re interested.

1) You might be tempted to say if(myString)…

…and this would appear to work, for a while. However, it’s really thewrong way to go about this. Observe:

var myString = true;
 
if (myString) {
    // this should evaluate to true because myString = "true", and it does. Good!
}
 
if (!myString) {
    // uh oh! This evaluates to true as well. Why? Because if(!myString)
    // is checking to see if myString *exists*, not if it's *true*.
}

As I mentioned, if(!myString) evaluates to true because that statement only checks if myString exists (e.g. if it’s not undefined or null), not if it evaluates to false.

2) What about creating a boolean object from the string?

Why not try to create a Boolean object from the string? Well, you’d run into an issue similar to the previous problem. Let’s let some example code do the talking, though, have a look:

var myString = "true";
 
if(Boolean(myString)) {
    // very good, this if statement evaluates to true correctly!
}
 
if(!Boolean(myString)) {
    // and this one evaluates to false! Our problems are solved!
}
 
var myOtherString = "false";
 
if(Boolean(myOtherString)) {
    // ...or are they? This evaluates to true, although we clearly set it to "false"!
}

As you can see, if(Boolean(“false”)) evaluates to true–why? When you create a new Boolean object from a string, it doesn’t try to check whether the string equals “true” or “false”. Instead, rather misleadingly, it checks whether the variable is a non-falsy value (e.g. a value that evalutes to false–0, undefined, an empty string, null, etc). Because myString is not an empty string, the Boolean evaluates to true–even if myString equals false.

3) Right, let’s try comparing our string against the string “true”

Really, the correct way we should be going about this is to check if our string equals “true” — if so, then our string is obviously “true”. Otherwise, it must be false. We can do it this way:

var myString = "true";
 
if(myString == "true") {
    // this evaluates to true correctly, myString is true
}
 
if(myString == "false") {
    // this evaluates to false, also correct, since myString doesn't equal false.
}

Wonderful, it looks like our problem is solved! But, you know something? The above code is kind of messy and a bit long just to check if our string is “true” or not. Let’s see if we can’t clean it up a bit:

myString = (myString == "true");

Ahh, nice and clean. Just the way I like it! (note: the parentheses are just there for clarity–if you don’t like them or you’re extra extra concerned about line length, removing them won’t cause any errors).

Как преобразовать строку в логический тип?

В Javascript существует несколько вариантов преобразовать строку в логический тип. Тем не менее, вы должны быть очень осторожны: это может нарушить логику вашего приложения и привести к непредвиденным ошибкам. И так для того чтобы избежать этих ошибок, была написана эта статья.

Читать далее Как преобразовать строку в логический тип?

CSS3 Box Shadow, только сверху/снизу/слева/справа

.top {
    box-shadow: 0 -5px 5px -5px #333;
}

.right {
    box-shadow: 5px 0 5px -5px #333;
}

.bottom {
    box-shadow: 0 5px 5px -5px #333;
}

.left {
    box-shadow: -5px 0 5px -5px #333;
}

 

Разделение цены пробелами (JS)

addSpaceToPrice = function(value, count) {
        if (value != undefined) {
            price = value.replace(/ /g, "")
            if (price.indexOf(',') > 0)
                price = price.substring(0, price.indexOf(','));
            fprice = '';
            price_ln = price.length;
            if (price_ln > count) {
                for (i = price_ln; i >= 0; i--) {
                    tmp = i % count === 0 ? ' ' : '';
                    fprice = fprice + tmp + price.substr(price_ln - i, 1);
                }
            } else {
                fprice = price;
            }
            return fprice;
        }
    }

Адаптивная таблица на чистом CSS

@media screen and (max-width: 950px) {
    table {
        border: 0;
        width: 100%;
        display: table !important;
    }
    table thead {
        display: none;
    }
    table tr {
        margin-bottom: 10px;
        display: block;
        border-bottom: 2px solid #ddd;
    }
    table td {
        display: block;
        text-align: right !important;
        font-size: 13px;
        border-bottom: 1px dotted #ccc;
        &:last-of-type {
            text-align: center !important;
        }
    }
    table td:last-child {
        border-bottom: 0;
    }
    table td:before {
        content: attr(data-label);
        float: left;
        text-transform: uppercase;
        font-weight: bold;
    }
}

Весь блок <thead> будет скрыт, вместо него нужно каждой ячейке <td> добавить заголовок через атрибут data-label.

Exchange Rates Today — простой плагин WordPress для изменения курса валют на сайте

2015-04-14 22-50-19 WordPress › Exchange Rates Today « WordPress Plugins - Google Chrome

 

Exchange Rates Today — плагин для WooCommerce который позволяет Вам задать в магазине национальную валюту, но вести учёт в зависимости от текущего курса валют. Вы просто указываете цену в нужной Вам валюте и каждый день обновляете курс.

К примеру валюта вашего сайта гривна, но все цены у Вас привязаны к доллару. Вы устанавливаете плагин https://wordpress.org/plugins/exchange-rates-today/

В настройках ставите валюту гривны:

2015-04-14 22-58-03 WooCommerce Settings ‹ Jane Doe — WordPress - Google Chrome

 

Все цены на сайте указываете в долларах:

2015-04-14 22-59-14 Add New Product ‹ Jane Doe — WordPress - Google Chrome

 

В главном меню, в разделе WooCommerce находите ссылку «Курс сегодня» и указываете текущий курс валют:

2015-04-14 23-14-07 Курс сегодня ‹ Jane Doe — WordPress - Google Chrome

 

После этого все цены на сайте пересчитаются по текущему курсу валют:

2015-04-14 23-05-52 Products Jane Doe - Google Chrome

 

Скачать плагин. 

UPD: плагин обновлён, должна пропасть ошибка с дробной ценой, о которой писали в комментариях.

Добавляем заказ в WooCommerce программно.

Наверное кто хоть раз сталкивались с созданием интернет-магазина на Woocommerce знают о его громоздкой и не приспособленной для стран СНГ странице checkout. (P.S. да, я знаю о saphali и о множестве плагинов для её редактирования, но речь сейчас не об этом).

В одном из проектов мне понадобилось оформлять заказ прям из корзины, вообще минуя эту страницу и с минимумом полей для ввода. Выглядело это примерно так:

2015-04-07 14-10-47 Cart Wptest - Google Chrome

 

 

 

 

 

 

В WC для этого есть функция wc_create_order() которая создаёт новый заказ и возвращает его в виде объекта в который мы можем добавить нужные свойства.

 

$order=wc_create_order(); //создаём новый заказ
//Записываем в массив данные о доставке заказа и данные клиента
$address = array(
        'first_name' => $first_name,
        'last_name'  => $last_name,
        'company'    => '',
        'email'      => $email,
        'phone'      => '',
        'address_1'  => $adress_one,
        'address_2'  => $adress_two, 
        'city'       => $city,
        'state'      => '',
        'postcode'   => $postcode,
        'country'    => ''
    ); 
 $order->add_product( get_product( '99' ), 1 );//Добавляем в заказ товары: 99-ID товара, 1-количество
 $order->set_address( $address, 'billing' ); //Добавляем данные о доставке
 $order->set_address( $address, 'shipping' ); // и оплате
 $order->calculate_totals(); //подбиваем сумму и видим что наш заказ появился в админке

Это минимальные данные нужные для оформления заказа (кол-во элементов в массиве можно уменьшить, заполнив только необходимые поля).

Так же вы можете использовать методы описсаные на странице WooCommerce API: http://docs.woothemes.com/wc-apidocs/class-WC_Order.html. Я для сокращённой формы заказ использовал так-же:

$order->add_order_note($comment); //добавляет комментарий к заказу
$order->update_status('processing', $payment); //устанавливает статус заказа "В обработке" (в этом случае WooCommerce отправляет уведомление администратору сайта и клиенту) и записываем информацию об оплате