MODx how to create a xtype combobox based on modResource

Hello everyone!

In this post I will try to explain how to create a xtype combobox for your custom CMP in MODx.
This can be helpful if you create a CMP page using this tutorial – Developing an Extra in MODX Revolution.

Let’s get started!

Part 1: create Javascript/Extjs template

In my case I need to create a combobox in an update window and I need to load to this combobox a modResource entity by some criteria. For example for these entities I need to set parent id in my query in xPDOObject.

First you need create combobox xtype/template and will name it – modx-combo-employees:


 MODx.combo.Template = function(config) {
     config = config || {};
     Ext.applyIf(config,{
         name: 'manager_id'
         ,hiddenName: 'manager_id'
         ,displayField: 'pagetitle'
         ,valueField: 'id'
         ,pageSize: 20
         ,fields: ['id','pagetitle']
         ,tpl: new Ext.XTemplate('<tpl for="."><div class="x-combo-list-item"><span style="font-weight: bold">{pagetitle}</span>'
             ,'<tpl if="pagetitle"> - <span style="font-style:italic">{pagetitle}</span></tpl>'
             ,'<br />{description}</div></tpl>')
	 ,url: testimonials.config.connectorUrl
         ,baseParams: {
             action: 'mgr/managers/getList'
         }
         ,allowBlank: true
     });
     MODx.combo.Template.superclass.constructor.call(this,config);
 };
 Ext.extend(MODx.combo.Template,MODx.combo.ComboBox);
 Ext.reg('modx-combo-employees',MODx.combo.Template);

In this code example I use xtype/template from modx-combo-category but I have some changes.

According to the official tutorial you must have a separate directory with the name like – doodles.
In my case I created directory with the name – testimonials.
And entities/objects that are displayed on CMP page named – Testimonials.
Each testimonial has some parameters like name/text/phone/photos/avatar/etc.
And it has a parameter – manager_id.
The id of this parameter belongs to modResource object type which contain standard fields like – name/pagetitle/content/etc.
And I need to receive these fields in my combobox to display a name of managers in it.

For receive this data to in combobox you need to create processor for this combobox, path to this processor defined in JS code above:

 baseParams: {
  action: 'mgr/managers/getList'
 }

Part 2: create php processor

You need to create the processor for connector – getlist.class.php in directory – path_to_your_package/mgr/managers and then defined your class.
In my case like this:

class ManagersGetListProcessor extends modObjectGetListProcessor {
		public $classKey = 'modResource';
		public $defaultSortField = 'id';
		public function prepareQueryBeforeCount(xPDOQuery $c) {
				$c->where(array(
				    'parent' => 1683
				));
				return $c;
		}

Public method prepareQueryBeforeCount provides a possibility to change query in xPDOObject before it executes and returns the results to the connector.
I change WHERE clause and set parent id because I have collection of my entities with this id. But you can set any other criterias for xPDOObject like – join/sort/limit and etc.
This collection contains managers that I need to displayed in my combobox.

In conclusion

After completing the above these actions you should get the combobox like this:
screen-shot-2017-08-28-at-20-12-31


How to set limit of input file field with jQuery

Hello everyone!

By default, in current implementation of HTML language in modern browsers input tag doesn’t support limit for uploading files.
And if you need to set limit of maximum uploading files in your field:

<input type="file" name="photos" multiple />

you can use a simple jQuery snippet:

$(document).ready(function(){
	var limit_of_files = 5;
	$('input[type="file"]').on('change',function(){

		if($(this).prop('files').length>limit_of_files)
		{
			alert('You exceeded limit for uploading files! Maximum of uploading files is 5!');
			$(this).val('');
			return false;
		}

	});
});

How to delete zero byte files in your folders

It is easy peasy like this:

find . -type f -name "*.php" -size 0 -print0 | xargs -0 rm

And that’s all!


New order email is not sending for new clients in woocommerce

Hi there

If you met with problem when your clients don’t receive the letter about a new order after they complete the checkout form and you are using any plugin for modify the checkout form fields, and your checkout form doesn’t contain the field with name – billing_email, then you need to add this code to your functions.php:

function custom_billing_email_field($id, $recipient, $object)
{
	if(empty($object->billing_email))
	{
		return $_POST['your_custom_field_name'];
	}
	return $object->billing_email;
}

add_filter('woocommerce_email_recipient_customer_on_hold_order','custom_billing_email_field',10,3);

Where variable $_POST must contain your custom email field –

$_POST['your_custom_field_name']

.
And you need to use filter for your default type order status for new orders, in my case it is a hold status and filter –

woocommerce_email_recipient_customer_on_hold_order

.

But other filters also exists, they are formed from the concatenation strings – woocommerce_email_recipient_ and id of email WC_Email class in get_recipient() method:

	/**
	 * Get valid recipients.
	 * @return string
	 */
	public function get_recipient() {
		$recipient  = apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object );
		$recipients = array_map( 'trim', explode( ',', $recipient ) );
		$recipients = array_filter( $recipients, 'is_email' );
		return implode( ', ', $recipients );
	}


Disable woocommerce product gallery metabox

It is very simply remove this metabox with follow code:

add_action( 'add_meta_boxes' , 'remove_my_meta_boxes', 40 );
function remove_my_meta_boxes()
{
    remove_meta_box( 'woocommerce-product-images',  'product', 'side');
}

Useful plugin for fix your javascript files with errors

If you have many files that wrote not you, for example in theme for your favourite CMS, and those files have many error like – missing semicolon or other same errors. You can use this plugin library for fix it – fixmyjs.


How to decode address to coordinates with Google maps api

Hello

For do this simple operation you need implement next function:

function  address_func(addresses, callback) {
        var coords = [];
        for(var i = 0; i < addresses.length; i++) {
            currAddress = addresses[i];
            var geocoder = new google.maps.Geocoder();
            if (geocoder) {
                geocoder.geocode({'address':currAddress}, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        coords.push(results[0].geometry.location);
                        if(coords.length == addresses.length) {
                            if( typeof callback == 'function' ) {
                                callback(coords);
                            }
                        }
                    }
                    else {
                        throw('No results found: ' + status);
                    }
                });
            }
       }
    }

And use this function as:


var address_array = ["514 Broadway, Brooklyn, New York, NY, United States"]
address_func([select_val], function(results){
for(marker in results)
{
   var marker_lat_lng = new google.maps.LatLng(results[marker].lat(), results[marker].lng());
   var marker = new google.maps.Marker({
					 position: marker_lat_lng,
					 map: map,
					});
}
});

How add tail slash redirect with .htaccees

If you need to do redirect from urls without tail slash to urls with slash, you can simply add this lines in your .htaccess:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*[^/])$ http://www.site.ru/$1/ [L,R=301]

How to change recipient email on send event in Contact Form 7 (WordPress)

Hello everyone!

Sometimes you may need to send letter from your form on the your website to another recipient, for example user changed some parameters.

You can change recipient email with this hook:

function wpcf7_param_change_on_send($contact_form) {

    $custom_email = $_POST['some_field'];
    if(!empty($custom_email))
    {
      $mail = $contact_form->prop( 'mail' );
      $mail['recipient'] = $custom_email;
      $contact_form->set_properties(array('mail'=>$mail));
    }
}

add_action("wpcf7_before_send_mail", "wpcf7_param_change_on_send");

How to match all h1-h6 tags in PHP

For matching all H tags in html code you need to do this:

preg_match_all('/<h([1-6]).*[^>]*>(.*)<\/h([1-6])>/',$content,$all_h_tags);

Where $content is a string variable with html tags and $all_h_tags is a variable where all matches are put.