• Как получить ссылки на товары при оформлении заказа?

    Скорее всего это:
    // Get an instance of the WC_Order object
    $order = wc_get_order($order_id);
    
    // Iterating through each WC_Order_Item_Product objects
    foreach ($order->get_items() as $item_key => $item_values):
    
        ## Using WC_Order_Item methods ##
    
        // Item ID is directly accessible from the $item_key in the foreach loop or
        $item_id = $item_values->get_id();
    
        ## Using WC_Order_Item_Product methods ##
    
        $item_name = $item_values->get_name(); // Name of the product
        $item_type = $item_values->get_type(); // Type of the order item ("line_item")
    
        $product_id = $item_values->get_product_id(); // the Product id
        $wc_product = $item_values->get_product(); // the WC_Product object
        ## Access Order Items data properties (in an array of values) ##
        $item_data = $item_values->get_data();
    
        $product_name = $item_data['name'];
        $product_id = $item_data['product_id'];
        $variation_id = $item_data['variation_id'];
        $quantity = $item_data['quantity'];
        $tax_class = $item_data['tax_class'];
        $line_subtotal = $item_data['subtotal'];
        $line_subtotal_tax = $item_data['subtotal_tax'];
        $line_total = $item_data['total'];
        $line_total_tax = $item_data['total_tax'];
    
    endforeach;
    Ответ написан
  • Как обратиться к нескольким img через this?

    Добавьте картинке data-атрибут со значением ID инпута, который за ней закреплен:
    <img src="http://lorempixel.com/30/30/city" data-input="check-option-1">

    Далее получайте ID чекнутого инпута
    $('body').on('change', '.check', function(){
        let id = $(this).attr('id');
        if ($(this).prop('checked')) {
            let img = $('img[data-id="'+id+'"]').attr('src');
    }
    });


    В коде могут быть ошибки, работоспособность не проверял.

    UPD: добавил песочницу https://jsfiddle.net/qf8zgshw/
    Ответ написан
  • Как реализовать в Woocommerce ползунок выбора товара?

    Можно, ничего сложного в этом нет. Берете обычный jquery ui slider например. При перемещении ползунка просто получаете значение цены с вашего сайта (причем не из блока с ценой, в из скрытого поля, например, чтобы хранить всегда первоначальную цену) и умножаете на кол-во цветов, которое пользователь выбрал на ползунке, после подсчета вставляете полученное значение цены в ваш блок с ценой (не в скрытый блок, а в блок, где показывается цена). Все.

    Для этого не нужно воротить внутренности вукомерса. Достаточно просто написать скрипт, ах да, не забудьте хранить и передавать кол-во выбранных цветов пользователем.
    Ответ написан
  • Почему массив $_FILES пуст при передаче AJAX?

    Я может и ошибаюсь, но вы открываете страницу:
    window.open('../admin/handlers/images.php', '_blank');
    после того, как скрипт выполнился. То есть вы просто переходите на страницу скрипта, на который уже ничего не передается.

    Вам надо смотреть что в массиве файлов в инструментах разработчика, вкладка Network. Там уже смотреть ответ от сервера после выполнения скрипта.
    Ответ написан
  • Как вставить этот код js в гугл карту?

    А если бы вы нажали на кнопку: Need a bit more help? Download a simple example, там бы появился JS код с примером, который вам и нужен.
    // When the window has finished loading create our google map below
                google.maps.event.addDomListener(window, 'load', init);
            
                function init() {
                    // Basic options for a simple Google Map
                    // For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
                    var mapOptions = {
                        // How zoomed in you want the map to start at (always required)
                        zoom: 11,
    
                        // The latitude and longitude to center the map (always required)
                        center: new google.maps.LatLng(40.6700, -73.9400), // New York
    
                        // How you would like to style the map. 
                        // This is where you would paste any style found on Snazzy Maps.
                        styles: [{"elementType":"labels","stylers":[{"visibility":"off"},{"color":"#f49f53"}]},{"featureType":"landscape","stylers":[{"color":"#f9ddc5"},{"lightness":-7}]},{"featureType":"road","stylers":[{"color":"#813033"},{"lightness":43}]},{"featureType":"poi.business","stylers":[{"color":"#645c20"},{"lightness":38}]},{"featureType":"water","stylers":[{"color":"#1994bf"},{"saturation":-69},{"gamma":0.99},{"lightness":43}]},{"featureType":"road.local","elementType":"geometry.fill","stylers":[{"color":"#f19f53"},{"weight":1.3},{"visibility":"on"},{"lightness":16}]},{"featureType":"poi.business"},{"featureType":"poi.park","stylers":[{"color":"#645c20"},{"lightness":39}]},{"featureType":"poi.school","stylers":[{"color":"#a95521"},{"lightness":35}]},{},{"featureType":"poi.medical","elementType":"geometry.fill","stylers":[{"color":"#813033"},{"lightness":38},{"visibility":"off"}]},{},{},{},{},{},{},{},{},{},{},{},{"elementType":"labels"},{"featureType":"poi.sports_complex","stylers":[{"color":"#9e5916"},{"lightness":32}]},{},{"featureType":"poi.government","stylers":[{"color":"#9e5916"},{"lightness":46}]},{"featureType":"transit.station","stylers":[{"visibility":"off"}]},{"featureType":"transit.line","stylers":[{"color":"#813033"},{"lightness":22}]},{"featureType":"transit","stylers":[{"lightness":38}]},{"featureType":"road.local","elementType":"geometry.stroke","stylers":[{"color":"#f19f53"},{"lightness":-10}]},{},{},{}]
                    };
    
                    // Get the HTML DOM element that will contain your map 
                    // We are using a div with id="map" seen below in the <body>
                    var mapElement = document.getElementById('map');
    
                    // Create the Google Map using our element and options defined above
                    var map = new google.maps.Map(mapElement, mapOptions);
    
                    // Let's also add a marker while we're at it
                    var marker = new google.maps.Marker({
                        position: new google.maps.LatLng(40.6700, -73.9400),
                        map: map,
                        title: 'Snazzy!'
                    });
                }


    Весь ваш код вставляется в качестве параметра styles:
    Ответ написан
  • Как отправить письмо?

    /* получатели */
    $to= "Mary <mary@example.com>" . ", " ; //обратите внимание на запятую
    $to .= "Kelly <kelly@example.com>";
    
    /* тема/subject */
    $subject = "Birthday Reminders for August";
    
    // Предопределенные переменные,
    // для e-mail сообщения
    $email_vars = array(
        'name' => $_POST['name'],
        'message' => ($_POST['message']) ? $_POST['message'] : '—',
        'phone' => $_POST['phone'],
        'utm_source' => $_POST['utm_source'],
        'utm_medium' => $_POST['utm_medium'],
        'utm_campaign' => $_POST['utm_campaign'],
    );
    
    $message = file_get_contents('templates/mail.question.html'); // Шаблон письма
    
    // Заменяем все наши переменные на данные
    if(isset($email_vars)){
        foreach($email_vars as $k=>$v){
            $message = str_replace('{'.$k.'}', $v, $message);
        }
    }
    /* Для отправки HTML-почты вы можете установить шапку Content-type. */
    $headers= "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
    
    /* дополнительные шапки */
    $headers .= "From: Birthday Reminder <birthday@example.com>\r\n";
    $headers .= "Cc: birthdayarchive@example.com\r\n";
    $headers .= "Bcc: birthdaycheck@example.com\r\n";
    
    /* и теперь отправим из */
    mail($to, $subject, $message, $headers);


    В файле шаблона вставляете переменные такого вида: {phone} , {name} итд
    Ответ написан
  • @font-face различные варианты одного шрифта?

    У вас HelveticaRegular это шрифт Helvetica с 400 жирностью, то есть если вы подключите этот шрифт и поставите font-weight:700,то у шрифта все равно жирность не поменяется.

    Вам нужно делать так:

    @font-face {
      font-family: Helvetica;
      src: url(/fonts/Helvetica/HelveticaRegular.ttf);
      font-weight:400;
    }
    @font-face {
      font-family: Helvetica;
      src: url(/fonts/Helvetica/HelveticaLight.ttf);
      font-weight:300;
    }
    @font-face {
      font-family: Helvetica;
      src: url(/fonts/Helvetica/HelveticaBold.ttf);
      font-weight:700
    }
    Ответ написан
  • Как понять компонент это или нет в vue?

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

    Например, компонент Button в вашем случае не очень нужен пока, например, не придется этим кнопкам навешивать обработчики событий (которых определенно некоторое конкретное количество).

    Легко понять на примере обычных шаблонов постов любой CMS, они как правило вынесены в отдельный файл. Не всегда понятно где на сайте они используются, но всегда можно наверняка поправить В ОДНОМ МЕСТЕ шаблон поста и быть уверенным, что он поменяется везде.

    Так же и с вашей кнопкой. Вы можете создать компонент Button, зная, что возможно эти кнопки надо будет дополнить какими-то properties, либо изменить структуру самой кнопки.

    Button это слишком простой пример в вашем случае. Вам нужно понимать, что у компонента существуют свои данные, методы, watchers событий и тд. И как только вам что-то из этого понадобится - вы используете компонент.
    Ответ написан
  • Нужен хороший, функциональный плагин review (отзывов), кто знает?

    Писал ответ уже в этом посте. То что вам нужно, остается добавить только возможность загрузки фотографий.
    Ответ написан
  • Какие области в веб - разработке осваивать в перспективе?

    У вас каша в голове, связанная с отсутствием опыта решения задач.

    1. Ваш первый пункт вытекает из второго. Если вы умеете п. 2, то и п. 1 вы сможете научиться (быстро). Уметь только в CMS это примерно как уметь забивать гвозди только одного вида (а ведь могут потребоваться и другие гвозди).
    2. Вам нужно понимать, что есть задача, а есть инструмент. Все что вы перечисляете - это инструменты для решения задач. Какие инструменты изучать? Инструменты, которые подходят под задачи, которые вы решаете. Какие задачи вы решаете или хотите решать? Это основной вопрос.
    3. Не стоит обращать внимания на длительность уроков. Никто не начинает работать только после того, как просидит N часов за теорией и N часов за практикой. Осваиваете базу, начинаете что-то делать на реальных задачах и постепенно учитесь (не в ущерб времени и деньгам клиента конечно же).
    4. Этот пункт - продолжение третьего. Вы смотрели что такое jQuery? Вы пытались им пользоваться? Зная js, приучить себя к jquery можно за 3-4 проекта. Надо просто брать и делать, а не думать: "там по jquery уроков на 300 часов, видимо это слишком сложно для меня". Вам нужно брать и начинать.
    5. Задачи всегда бывают разные, следовательно и подбор инструментов тоже, следовательно нужно знать и jQuery и Vue.js, а не что-то одно. Не всегда же вы пилить SPA будете? Кому-то потребуется сделать простой калькулятор, чтобы человек мог его поправить потом. Будете использовать Vue, который клиент может не знать? Или все же jQuery или нативный js? Ответ очевиден.

    Опишу свою ситуацию:
    1. Начинал с HTML + CSS
    2. Начал учить JS и параллельно Jquery (никогда так не делайте, сначала js, потом jq).
    3. При набранном опыте я смог нормально освоить Vue за 1 проект (объемный).
    4. Так как иногда роюсь в PHP, освоиться в Laravel на уровне: есть проблема - знаю где посмотреть и как ее решить в случае чего, смог за 1 проект длиною в месяц.

    Все эти фреймворки и тд пишутся на том языке, который вы, по логике, уже должны знать, так что перестать бояться какой-либо фреймворк можно через неделю. Писать на нем что-либо толковое через 1 месяц.

    Поэтому вам нужно:
    1. Определиться с выбором области работы, судя по вашему вопросу у вас выбор между фронтом (javascript + frameworks) и беком (python, php + frameworks)
    2. Далее загуглить road map по фронту или бекенду (в зависимости от вашего выбора)
    3. Поступательно двигаться и не бояться.
    4. У вас еще хватит времени прожить счастливую и долгую жизнь.

    P.S вся эта арифметика со скоростью изучения фреймворком исключительно мой опыт, у кого-то быстрее, у кого-то медленнее. Дабы внести разъяснения, добавлю: я вполне себя спокойно ощущаю в том или ином фреймворке, однако не являюсь очень серьезным разработчиком.

    P.S.S Отвечая на главный вопрос: "Какие области в веб — разработке осваивать в перспективе?" - в перспективе нужно становиться разработчиком, у которого есть достаточно опыта в смежных областях, есть знания, помогающие решать те или иные задачи (чем сложнее задачи, тем больше ваша зп, тем вы ценнее), и постоянное развитие, так как наука продвигается, задачи и их сложность меняется, инструменты добавляются и так далее. И не забывайте, программирование это не только делать сайты или приложения, если области задач, не связанные с веб разработкой, но которые тоже интересны.
    Ответ написан
  • Плагин для добавления автоматических отзывов WordPress?

    Обычно свои наработки не выкладываю, но вот держите:

    Сама html-форма:
    html-код
    <form class="form-wrapper reviews-form" id="reviews-form">
    					<h3>Оставить отзыв</h3>
    					<div class="reviews-form__row">
    						<div class="form-wrapper__group">
    							<input type="text" name="name" value="" placeholder="Ваше имя" required>
    						</div>
    						<div class="form-wrapper__group">
    							<input type="text" name="email" value="" placeholder="Ваш e-mail" required>
    						</div>
    						<div class="reviews-form__mark-wrapper">
    							<ul class="reviews-form__marks-list">
    								<li><button class="green" data-review-mark="positive"><img src="<?php echo get_template_directory_uri(); ?>/images/svg/happy.svg" alt="Положительный" class="svg"></button></li>
    								<li><button class="yellow" data-review-mark="medium"><img src="<?php echo get_template_directory_uri(); ?>/images/svg/surprised.svg" alt="Удовлетворительный" class="svg"></button></li>
    								<li><button class="red" data-review-mark="negative"><img src="<?php echo get_template_directory_uri(); ?>/images/svg/sad.svg" alt="Отрицательный" class="svg"></button></li>
    							</ul>
    						</div>
    					</div>
    					<div class="reivews-form__message-wrapper">
    						<textarea name="message" placeholder="Ваш отзыв" required></textarea>
    						<input type="hidden" name="rating" value="" required>
    					</div>
    					<button type="submit" class="button button--green">Оставить отзыв</button>
    				</form>

    Обработчики форм:
    /**
          * @module       Marks
          * @description  Выставление оценки в форме
          */
         $('button[data-review-mark]').on('click',function(e){
           e.preventDefault();
           $('button[data-review-mark]').removeClass('active');
           $(this).addClass('active');
           $('#reviews-form').find('[name="rating"]').val($(this).attr('data-review-mark'));
         });

    /**
         * @module       Добавление отзыва
         * @description  Добавление отзыва
         */
        $('#reviews-form').submit(function(e) {
          e.preventDefault();
          $.ajax({
            type: "POST",
            url: "/api/newreview.php",
            data: $(this).serialize(),
            success: function(){
              $('#successreviewmodal').modal('show');
            },
            error: function() {
              $('#errormodal').modal('show');
            }
          });
        });



    Так как запрос отсылается на /api/newreview.php, то по этому адресу у вас должен располагаться этот файл со следующим кодом:

    Код newreview.php:
    <?php
    ini_set("display_errors",1);
    error_reporting(E_ALL);
    
    // *
    // Подключаем все файлы для работы
    // *
    require_once( $_SERVER['DOCUMENT_ROOT'].'/wp-load.php');
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );
    
    
    $user_name = trim($_POST['name']);
    $user_mail = trim($_POST['email']);
    $message = trim($_POST['message']);
    $rating  = trim($_POST['rating']);
    
    $post_data = array(
    	'post_title'    => 'Отзыв #' . uniqid(),
    	'post_content'  => $message,
    	'post_status'   => 'pending',
    	'post_author'   => 1,
      'post_type'     => 'reviews'
    );
    
    // Вставляем запись в базу данных
    $post_id = wp_insert_post( $post_data );
    // *
    // Добавляем все дополнительные поля
    // *
    update_field( 'rating', $rating, $post_id );
    update_field( 'author', $user_name, $post_id );
    update_field( 'e-mail', $user_email, $post_id );
    
    
    
    ?>



    Так как у нас пост добавляется в кастомный тип записей, нужно его сначала создать. Для этого в файл functions.php добавляем следующее:

    Кастомный тип записей
    /**
     * Кастомный тип записей:  Отзывы
     */
    function create_posttype_reviews() {
      register_post_type( 'reviews',
        array(
          'labels' => array(
            'name' => __( 'Отзывы' ),
            'singular_name' => __( 'Отзывы' )
          ),
          'public' => true,
          'has_archive' => false,
          'rewrite' => array('slug' => 'reviews'),
        )
      );
    }
    add_action( 'init', 'create_posttype_reviews' );



    На этом все. В админке wordpress у вас появится новый блок меню "Отзывы", куда и будут попадать все отзывы. В качестве бонуса, могу вам прикрепить код, который надо поместить в functions.php, благодаря которому, боявится балун с количеством неопубликованных отзывов (так проще их отслеживать):

    php код
    /**
     * Уведомления о новых неопубликованных постах
     */
    
    add_action( 'admin_menu', 'add_user_menu_bubble' );
    function add_user_menu_bubble(){
    	global $menu;
    
    	// Отзывы
    	$count = wp_count_posts('reviews')->pending; // на подтверждении
    	if( $count ){
    		foreach( $menu as $key => $value ){
    			if( $menu[$key][2] == 'edit.php?post_type=reviews' ){
    				$menu[$key][0] .= ' <span class="awaiting-mod"><span class="pending-count">' . $count . '</span></span>';
    				break;
    			}
    		}
    	}
    }



    P.S не забудьте проверять всю информацию, поступающую от клиента.

    UPD: забыл добавить, чтобы отзывы где-то выводились, вам нужно в каком-то месте шаблона их вывести:

    WP Loop
    <?php
    							$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    							query_posts(array(
    								'post_type' => 'reviews',
    								'posts_per_page' => -1,
    								'paged' => $paged,
    							));
    						?>
    						<?php if ( have_posts() ) : ?>
    							<?php $i = 1; ?>
    							<?php while ( have_posts() ) : the_post(); ?>
    								<div class="col-lg-6">
    									<?php echo get_template_part('template-parts/content','review'); ?>
    								</div>
    								<?php $i++; ?>
    
    
    							<?php endwhile; ?>
    						<?php endif; ?>
    						<?php wp_reset_postdata(); ?>



    Так же прошу заметить, что при добавлении нового отзыва (файл newreview.php), в этом блоке кода:
    $post_data = array(
    	'post_title'    => 'Отзыв #' . uniqid(),
    	'post_content'  => $message,
    	'post_status'   => 'pending',
    	'post_author'   => 1,
      'post_type'     => 'reviews'
    );

    указано: 'post_status' => 'pending',, что означает добавление всех новых отзывов со статусом На модерации, если нужно отключить эту настройку, то поставьте 'post_status' => 'publish',
    Ответ написан
  • Как отловить null в ответе ajax?

    Во-первых, это не ответ сервера, это ошибка JS.

    Во-вторых, эта ошибка говорит: "не могу прочесть свойство predid" у null-переменной. Следовательно, result2.users у вас NULL. Проверяйте именно это условие.
    Ответ написан
  • Где купить такие векторы?

    Подобные элемент в красной рамке спокойно ищутся и свободно скачиваются на freepik.com. Например, тут. Не забудьте только почитать про лицензии.
    Ответ написан