• Нужно ли комментировать код?

    @IgorNoskov
    Вот здесь https://learn.javascript.ru/comments очень хорошо пояснено про комментарии. Там пояснено на примере javascript, но актуально для всех языков.
    Ответ написан
    Комментировать
  • Правильно ли я понять суть реляционных бд?

    @IgorNoskov
    Связи между таблицами нужны в первую очередь для целостности данных. Например, можно сделать такую связь между таблицей пользователей и их постами, чтобы при удалении пользователя, база данных автоматически удаляла все его посты. Либо наоборот, сделать такую связь, что нельзя удалить пользователя, если есть посты от него. То есть связями можно создать защиту, которая гарантирует, что случайно не удалится какая-то запись.

    То что у вас нет связей, это не значит, что у вас не реляционная база данных. Это определяется самой базой данных, а не вашими связями.

    С помощью связей, автоматом у вас не получится при вставке или удалении записи обновить количество записей в другой таблице. Это нужно делать в запросе.

    Update
    Ещё связи помогают избежать ошибок, например, по ошибке никак не получится добавить пост в несуществующую категорию или удалить категории, в которой есть посты. Надеюсь поняли суть.
    Ответ написан
    1 комментарий
  • Как паравильно реализовать запросы к БД?

    @IgorNoskov
    Добавьте в таблицу роли. Храните в базе данных не пароль, а хэш пароля, например, созданный с помощью функции password_hash(). Никогда не храните пароли напрямую в базе данных, не используйте устаревшие методы хэширования для хранения паролей (например алгоритм md5).

    При входе в административную панель:
    1. извлекайте по логину данные пользователя;
    2. с помощью функции password_verify() сверяйте пароль.

    Здесь https://www.php.net/manual/ru/function.password-ha... читайте о функции password_hash(), и о том, как проверять пароль.
    Ответ написан
    Комментировать
  • Как в WordPress сменить почту отправителя?

    @IgorNoskov
    Скорее всего стоит какой-то плагин, где в настройках указан адрес отравителя определённых писем. Например, может быть установлен плагин Contact Form 7, который выводит формы в определённых местах сайта. В настройках этого плагина указан адрес отправителя конкретно форм этого плагина, поэтому ваши манипуляции со сменой отправителя в других местах не помогают.

    Update

    Если стоит Contact Form 7 -> настройка плагина -> выбрать конкретную форму -> открыть вкладку "Письмо" -> отредактировать поле "От кого".

    Если это касается писем от плагина Woocommerce -> Woocommerce -> настройки -> Email'ы -> проскролить вниз -> отредактировать поле "Адрес отправителя".
    Ответ написан
    9 комментариев
  • Как перенести незакоммиченные изменения в другую ветку?

    @IgorNoskov
    Не делая коммит переходите в нужную ветку, изменения никуда не денутся, закоммитите их в нужной ветке.

    Update
    Это касается случая, когда две ветки находятся на одном коммите. Если они ушли друг от друга, то можно сделать стеш изменений, перейти на нужную ветку и применить стэш, а затем сделать коммит.

    Update2
    Посмотрите видео https://learn.javascript.ru/screencast/git#branche... там всё подробно рассказано о данной ситуации. Советую посмотреть все видео из данного скринкаста.
    Ответ написан
    1 комментарий
  • Какой валидатор использовать?

    @IgorNoskov
    https://github.com/rakit/validation Подход как у Laravel, пользуюсь на одном проекте, удобно.
    Ответ написан
    Комментировать
  • Как загрузить модуль в npm на компе без интернета?

    @IgorNoskov
    Если я правильно понял вопрос. Нужно в файл проекта package.json в объект dependencies прописать название модуля с версией, а также добавить в файл проекта package-lock.json все необходимые зависимости этого плагина. Вообще, плохая практика руками ковыряться в package-lock.json. Не факт что всё это заработает в итоге, потому что нужно, чтобы подтянулись зависимости этого модуля.
    Если имеется ввиду, что нужно отправить код модуля в репозиторий nmp без интернета, можно попробовать написать код на бумаге и отправить письмо в офис npm.
    Ответ написан
    1 комментарий
  • Как фиксировать предыдущий элемент?

    @IgorNoskov
    В функции _makeRow сделайте уникальными все id, при генерации новой строки создаются элементы с уже существующими id. У элементов формы нужно также генерировать элементы с уникальными атрибутами name, а то получается у вас в одной и той же форме создаются элементы с идентичными атрибутами name и id.
    Ответ написан
    Комментировать
  • Как убрать hover при разных разрешениях?

    @IgorNoskov
    @media all and (max-width: 991px) {
        .element:hover {
          // переопределить значение
       }
    }
    Ответ написан
    2 комментария
  • Как построить массив из поля "loop" в Visual Composer?

    @IgorNoskov Автор вопроса
    Нашёл функцию:
    list($args, $wp_query) = vc_build_loop_query($atts["loop"]);
    
    while ( $wp_query->have_posts() ) {
    $wp_query->the_post();
    }
    
    wp_reset_postdata();
    Ответ написан
    Комментировать
  • Revolution Slider при переноси с домена на домен теряются картинки?

    @IgorNoskov
    Здравствуйте, переносите сайты с помощью плагина Duplicator. Перенос упрощается в разы, ссылки автоматом корректируются.
    Ответ написан
    Комментировать
  • Как осуществить массовую установка изображений по атрибуту для каждой вариации?

    @IgorNoskov Автор вопроса
    Не нашёл нигде ответа, поэтому написал небольшой снипет, который решает эту проблему. Пригодится в тех случаях, когда создаётся много вариаций и для каждой нужно задать своё изображение. К примеру, если сейчас у меня на сайте дверь имеет 12 размеров и 10 цветов, получается 120 вариаций. Ранее приходилось устанавливать для каждой из 120 вариаций своё изображение. Затрата времени - до 10 минут на каждый товар! Теперь тоже самое можно сделать, примерно, за 30 секунд!

    Инструкция:
    1. Вставляем код в functions.php вашей темы.
    1. Если код вставлен верно, в поле variation_actions появятся дополнительные варианты, на основе атрибутов, выбранных для вариаций.
    2. Выбираем нужный атрибут, нажимает "Применить".

    5c91c619eb2c44fb9278884aecc1e74b.png

    3. В открывшемся окне загружаем изображение с локального диска или выбираем из библиотеки, а затем жмём "Задать изображение для вариаций с выбранным атрибутом".

    4819a0eb833c4eec993ea22fe9e8ca40.png

    4. Повторяем операцию для каждого выбранного атрибута.

    Код:
    add_action( 'woocommerce_variable_product_bulk_edit_actions', 'set_image_by_attributes', 10); 
    
    function set_image_by_attributes() {
    	global $post, $woocommerce;
     
        $attributes = maybe_unserialize( get_post_meta( $post->ID, '_product_attributes', true ) );
    	
    	$out = "";
    
    	foreach( $attributes as $attribute ) {
    		if ($attribute['is_variation']) {
    
    			$out .= '<optgroup label="Изображение по aтрибуту «' . wc_attribute_label($attribute['name']) . '»">';
    			
    				foreach( wc_get_product_terms( $post->ID, $attribute['name'] ) as $attribute_value ){
    					$term = get_term_by('name', $attribute_value, $attribute['name']);
    					$out .= '<option value="set_image_attribute" data-attribute-name="' . $attribute['name'] . '" data-attribute-value="' . $term->slug . '">' . $attribute_value . '</option>';
    				}
    				
    			$out .= '</optgroup>';
    		}
    	}
    	?>
    	<script>
    		jQuery('.wc-metaboxes-wrapper').on('click', 'a.bulk_edit', function(event) {
    			var field_to_edit = jQuery('select#field_to_edit').val();
    
    			if ( field_to_edit == 'set_image_attribute' ) {
    				var input_tag = jQuery('select#field_to_edit :selected').attr('rel') ? jQuery('select#field_to_edit :selected').attr('rel') : 'input';
    				
    				var mediaUploader,
    					data = {};
    					
    				data.attribute_name = jQuery('select#field_to_edit :selected').data('attribute-name');
    				data.attribute_value = jQuery('select#field_to_edit :selected').data('attribute-value');
    				
    				if (mediaUploader) {
    					mediaUploader.open();
    					return;
    				}
    
    				mediaUploader = wp.media.frames.file_frame = wp.media({
    					title: 'Выберите изображение',
    					button: {
    					text: 'Задать изображение для вариаций с выбранным атрибутом'
    				}, multiple: false });
    
    				mediaUploader.on('select', function() {
    					var attachment = mediaUploader.state().get('selection').first().toJSON();
    					data.attachment_id = attachment.id;
    					jQuery( '#woocommerce-product-data' ).block({
    						message: null,
    						overlayCSS: {
    							background: '#fff',
    							opacity: 0.6
    						}
    					});
    					
    					jQuery.ajax({
    						url: woocommerce_admin_meta_boxes_variations.ajax_url,
    						data: {
    							action:       'woocommerce_bulk_edit_variations',
    							security:     woocommerce_admin_meta_boxes_variations.bulk_edit_variations_nonce,
    							product_id:   <?php echo $post->ID; ?>,
    							product_type: jQuery( '#product-type' ).val(),
    							bulk_action:  field_to_edit,
    							data:         data
    						},
    						type: 'POST',
    						success: function(data) {
    							jQuery( '.variations-pagenav .page-selector' ).val( 1 ).first().change();
    						}
    					});
    					
    					jQuery( '#woocommerce-product-data' ).unblock();
    
    				});
    				
    				mediaUploader.open();
    				
    				return false;
    			}
    		});
    	
    	</script>
    	<?php
    	
    	echo $out;
    	
    }
    
    add_action( 'woocommerce_bulk_edit_variations_default', 'action_woocommerce_bulk_edit_variations_default', 10, 4 );
    
    function action_woocommerce_bulk_edit_variations_default( $bulk_action, $data, $product_id, $variations ) {
    	
        if ($bulk_action == 'set_image_attribute') {
    		
    		foreach($variations as $variation) {
    			$attribute_name = "attribute_" . $data["attribute_name"];
    			$meta = get_post_meta($variation);
    			
    			if( $meta[$attribute_name][0] === $data["attribute_value"]) {
    				set_post_thumbnail( $variation, $data["attachment_id"] );
    			}
    		}
    	}
    	
    	exit;
    };
    Ответ написан
    2 комментария