Version Notes
Release History
v0.1.3
* Fix: added check for google CDN state.
v0.1.2
* Stable release
v0.1.1
* Fix: some gmaps suggestions were considered premise level when they were not.
v0.1.0
* Initial Release
Download this release
Release Info
Developer | Crafty Clicks |
Extension | Crafty_Clicks_International_Address_Validation |
Version | 0.1.3 |
Comparing to | |
See all releases |
Code changes from version 0.1.2 to 0.1.3
app/code/local/CraftyClicksValidate/etc/config.xml
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<config>
|
13 |
<modules>
|
14 |
<CraftyClicksValidate>
|
15 |
-
<version>0.1.
|
16 |
</CraftyClicksValidate>
|
17 |
</modules>
|
18 |
|
12 |
<config>
|
13 |
<modules>
|
14 |
<CraftyClicksValidate>
|
15 |
+
<version>0.1.3</version>
|
16 |
</CraftyClicksValidate>
|
17 |
</modules>
|
18 |
|
app/design/frontend/base/default/template/craftyclicksvalidate/post_checkout.phtml
CHANGED
@@ -72,7 +72,7 @@ if($conf['craftyclicksvalidate']['active'] && !($shippingAddress->country_id ==
|
|
72 |
|
73 |
</div>
|
74 |
</div>
|
75 |
-
<script src="
|
76 |
<script type="text/javascript">
|
77 |
|
78 |
<?php
|
@@ -119,194 +119,197 @@ document.observe('dom:loaded', function() {
|
|
119 |
}
|
120 |
$loading_image = $this->getSkinUrl('images/craftyclicksvalidate/'.$loading_image);
|
121 |
?>
|
|
|
|
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
var address = shipping.street+" "+shipping.postcode+" "+shipping.city+" "+shipping.country_id;
|
129 |
|
130 |
-
var geocoder = new google.maps.Geocoder();
|
131 |
|
132 |
-
|
133 |
|
134 |
-
|
135 |
-
original.postalcode = shipping.postcode.toLowerCase();
|
136 |
-
original.city = shipping.city.toLowerCase();
|
137 |
|
|
|
138 |
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
if (geocoder) {
|
143 |
-
geocoder.geocode({ 'address': address }, function (results, status) {
|
144 |
-
var doCheck = false;
|
145 |
-
//if gmaps fails to locate, then we have some super bogus address.
|
146 |
-
if (status == google.maps.GeocoderStatus.OK) {
|
147 |
-
//parse gmaps data into some more useable format.
|
148 |
-
for(var i = 0; i< results.length; i++ ){
|
149 |
-
data.push(getDataFromMaps(results[i]));
|
150 |
-
}
|
151 |
|
152 |
-
//first hit on gmaps is the best find; check if it's premise level.
|
153 |
-
if(typeof data[0].country !== "undefined" && typeof data[0].locality !== "undefined" && typeof data[0].postal_code !== "undefined" && typeof data[0].route !== "undefined" && typeof data[0].street_number !== "undefined"){
|
154 |
|
155 |
-
|
|
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
162 |
|
163 |
-
|
164 |
-
|
165 |
|
166 |
-
|
167 |
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
doCheck = true;
|
172 |
}
|
173 |
-
|
174 |
-
//everything matches, remove the validation div. (valid address)
|
175 |
-
$('correct_box').remove();
|
176 |
-
}
|
177 |
} else {
|
178 |
doCheck = true;
|
|
|
179 |
}
|
180 |
|
181 |
-
} else {
|
182 |
-
doCheck = true;
|
183 |
-
//not premise level
|
184 |
}
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
//super bogus data
|
189 |
-
doCheck = true;
|
190 |
-
}
|
191 |
-
|
192 |
-
if(doCheck){
|
193 |
-
|
194 |
-
$('correct_box').update($('hidden-correction').innerHTML);
|
195 |
-
$('hidden-correction').remove();
|
196 |
-
|
197 |
-
initialize_gmaps(results[0].geometry.location.lat(), results[0].geometry.location.lng());
|
198 |
-
|
199 |
-
$('address').value = shipping.street;
|
200 |
-
$('town').value = shipping.city;
|
201 |
-
$('postcode').value = shipping.postcode;
|
202 |
-
var country = shipping.country_id;
|
203 |
-
if($('region_id').childElements('option').length){
|
204 |
-
$('region').hide();
|
205 |
-
$('region_id')[shipping.region_id].selected = true;
|
206 |
-
} else {
|
207 |
-
$('region_id').hide();
|
208 |
-
$('region').value = shipping.region;
|
209 |
}
|
210 |
-
|
211 |
-
data.forEach(function(element){
|
212 |
-
// if the data provided is premise level
|
213 |
-
if(typeof element.route !== "undefined" && typeof element.street_number !== "undefined"){
|
214 |
-
var address = '';
|
215 |
-
|
216 |
-
var region = '';
|
217 |
-
if(typeof element.administrative_area_level_1 !== "undefined"){
|
218 |
-
region = element.administrative_area_level_1.long_name;
|
219 |
-
}
|
220 |
-
|
221 |
-
var postal_code = '';
|
222 |
-
if(typeof element.postal_code !== "undefined"){
|
223 |
-
postal_code = element.postal_code.long_name;
|
224 |
-
}
|
225 |
-
|
226 |
-
var locality = '';
|
227 |
-
if(typeof element.locality !== "undefined"){
|
228 |
-
locality = element.locality.long_name;
|
229 |
-
}
|
230 |
-
|
231 |
-
var route = '';
|
232 |
-
if(typeof element.route !== "undefined"){
|
233 |
-
route = element.route.long_name;
|
234 |
-
}
|
235 |
|
236 |
-
|
237 |
-
if(typeof element.street_number !== "undefined"){
|
238 |
-
street_number = element.street_number.long_name;
|
239 |
-
}
|
240 |
-
if(element.formatted.indexOf(route) > element.formatted.indexOf(street_number))
|
241 |
-
address = street_number + " " + route;
|
242 |
-
else
|
243 |
-
address = route + " " + street_number;
|
244 |
|
|
|
|
|
245 |
|
246 |
-
|
247 |
-
if(combined_address != '' && locality != ''){
|
248 |
-
combined_address += ', '+locality;
|
249 |
-
}
|
250 |
-
if(combined_address != '' && postal_code != ''){
|
251 |
-
combined_address += ', '+postal_code;
|
252 |
-
}
|
253 |
-
if(combined_address != '' && region != ''){
|
254 |
-
combined_address += ', '+region;
|
255 |
-
}
|
256 |
|
257 |
-
|
258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
});
|
267 |
});
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
});
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
}
|
291 |
-
}
|
292 |
-
// pass all form values to an ajax request & update.
|
293 |
-
new Ajax.Request('<?php echo Mage::getUrl('craftyclicksvalidate/ajax/update');?>',
|
294 |
-
{
|
295 |
-
method:'get',
|
296 |
-
parameters: {
|
297 |
-
street: $('address').getValue(),
|
298 |
-
city: $('town').getValue(),
|
299 |
-
postcode: $('postcode').getValue(),
|
300 |
-
region: $('region').getValue()
|
301 |
-
},
|
302 |
-
onSuccess: function(transport){
|
303 |
-
$('correct_box').update('<?php echo $conf['craftyclicksvalidate']['finish_text']; ?>');
|
304 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
});
|
306 |
-
|
307 |
-
|
308 |
-
}
|
309 |
-
}
|
310 |
}
|
311 |
|
312 |
} );
|
72 |
|
73 |
</div>
|
74 |
</div>
|
75 |
+
<script src="//maps.google.com/maps/api/js?sensor=false"></script>
|
76 |
<script type="text/javascript">
|
77 |
|
78 |
<?php
|
119 |
}
|
120 |
$loading_image = $this->getSkinUrl('images/craftyclicksvalidate/'.$loading_image);
|
121 |
?>
|
122 |
+
// check if google CDN loaded properly
|
123 |
+
if(typeof google !== "undefined"){
|
124 |
|
125 |
+
var html = '<div class="buttons-set" id="correct_box"><img style="margin: auto;" src="<?php echo $loading_image; ?>"/></div>';
|
126 |
+
|
127 |
+
$$('.buttons-set')[0].insert({before :html});
|
|
|
|
|
|
|
128 |
|
|
|
129 |
|
130 |
+
var address = shipping.street+" "+shipping.postcode+" "+shipping.city+" "+shipping.country_id;
|
131 |
|
132 |
+
var geocoder = new google.maps.Geocoder();
|
|
|
|
|
133 |
|
134 |
+
var original = new Object();
|
135 |
|
136 |
+
original.street = shipping.street.toLowerCase();
|
137 |
+
original.postalcode = shipping.postcode.toLowerCase();
|
138 |
+
original.city = shipping.city.toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
|
|
|
|
|
140 |
|
141 |
+
var suggestions = new Array();
|
142 |
+
var data = new Array();
|
143 |
|
144 |
+
if (geocoder) {
|
145 |
+
geocoder.geocode({ 'address': address }, function (results, status) {
|
146 |
+
var doCheck = false;
|
147 |
+
//if gmaps fails to locate, then we have some super bogus address.
|
148 |
+
if (status == google.maps.GeocoderStatus.OK) {
|
149 |
+
//parse gmaps data into some more useable format.
|
150 |
+
for(var i = 0; i< results.length; i++ ){
|
151 |
+
data.push(getDataFromMaps(results[i]));
|
152 |
+
}
|
153 |
|
154 |
+
//first hit on gmaps is the best find; check if it's premise level.
|
155 |
+
if(typeof data[0].country !== "undefined" && typeof data[0].locality !== "undefined" && typeof data[0].postal_code !== "undefined" && typeof data[0].route !== "undefined" && typeof data[0].street_number !== "undefined"){
|
156 |
|
157 |
+
var mapsaddress = new Object();
|
158 |
|
159 |
+
//figure out the correct order of housenumber / street.
|
160 |
+
if(data[0].formatted.indexOf(data[0].route) > data[0].formatted.indexOf(data[0].street_number))
|
161 |
+
mapsaddress.street = data[0].street_number.long_name.toLowerCase() + " " + data[0].route.long_name.toLowerCase();
|
162 |
+
else
|
163 |
+
mapsaddress.street = data[0].route.long_name.toLowerCase() + " " + data[0].street_number.long_name.toLowerCase();
|
164 |
+
|
165 |
+
mapsaddress.postalcode = data[0].postal_code.long_name.toLowerCase();
|
166 |
+
mapsaddress.city = data[0].locality.long_name.toLowerCase();
|
167 |
+
|
168 |
+
var old_country_id = shipping.country_id.toLowerCase();
|
169 |
+
|
170 |
+
if(old_country_id == data[0].country.long_name.toLowerCase() || old_country_id == data[0].country.short_name.toLowerCase()){
|
171 |
+
//if countries match AND premise level do not match:
|
172 |
+
if(JSON.stringify(mapsaddress) != JSON.stringify(original)){
|
173 |
+
doCheck = true;
|
174 |
+
}
|
175 |
+
else {
|
176 |
+
//everything matches, remove the validation div. (valid address)
|
177 |
+
$('correct_box').remove();
|
178 |
+
}
|
179 |
+
} else {
|
180 |
doCheck = true;
|
181 |
}
|
182 |
+
|
|
|
|
|
|
|
183 |
} else {
|
184 |
doCheck = true;
|
185 |
+
//not premise level
|
186 |
}
|
187 |
|
|
|
|
|
|
|
188 |
}
|
189 |
+
else {
|
190 |
+
//super bogus data
|
191 |
+
doCheck = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
+
if(doCheck){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
|
196 |
+
$('correct_box').update($('hidden-correction').innerHTML);
|
197 |
+
$('hidden-correction').remove();
|
198 |
|
199 |
+
initialize_gmaps(results[0].geometry.location.lat(), results[0].geometry.location.lng());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
|
201 |
+
$('address').value = shipping.street;
|
202 |
+
$('town').value = shipping.city;
|
203 |
+
$('postcode').value = shipping.postcode;
|
204 |
+
var country = shipping.country_id;
|
205 |
+
if($('region_id').childElements('option').length){
|
206 |
+
$('region').hide();
|
207 |
+
$('region_id')[shipping.region_id].selected = true;
|
208 |
+
} else {
|
209 |
+
$('region_id').hide();
|
210 |
+
$('region').value = shipping.region;
|
211 |
}
|
212 |
+
|
213 |
+
data.forEach(function(element){
|
214 |
+
// if the data provided is premise level
|
215 |
+
if(typeof element.route !== "undefined" && typeof element.street_number !== "undefined"){
|
216 |
+
var address = '';
|
217 |
+
|
218 |
+
var region = '';
|
219 |
+
if(typeof element.administrative_area_level_1 !== "undefined"){
|
220 |
+
region = element.administrative_area_level_1.long_name;
|
221 |
+
}
|
222 |
+
|
223 |
+
var postal_code = '';
|
224 |
+
if(typeof element.postal_code !== "undefined"){
|
225 |
+
postal_code = element.postal_code.long_name;
|
226 |
+
}
|
227 |
+
|
228 |
+
var locality = '';
|
229 |
+
if(typeof element.locality !== "undefined"){
|
230 |
+
locality = element.locality.long_name;
|
231 |
+
}
|
232 |
+
|
233 |
+
var route = '';
|
234 |
+
if(typeof element.route !== "undefined"){
|
235 |
+
route = element.route.long_name;
|
236 |
+
}
|
237 |
+
|
238 |
+
var street_number = '';
|
239 |
+
if(typeof element.street_number !== "undefined"){
|
240 |
+
street_number = element.street_number.long_name;
|
241 |
+
}
|
242 |
+
if(element.formatted.indexOf(route) > element.formatted.indexOf(street_number))
|
243 |
+
address = street_number + " " + route;
|
244 |
+
else
|
245 |
+
address = route + " " + street_number;
|
246 |
+
|
247 |
+
|
248 |
+
var combined_address = address;
|
249 |
+
if(combined_address != '' && locality != ''){
|
250 |
+
combined_address += ', '+locality;
|
251 |
+
}
|
252 |
+
if(combined_address != '' && postal_code != ''){
|
253 |
+
combined_address += ', '+postal_code;
|
254 |
+
}
|
255 |
+
if(combined_address != '' && region != ''){
|
256 |
+
combined_address += ', '+region;
|
257 |
+
}
|
258 |
+
|
259 |
+
var html = '<li data-region="'+region+'" data-postcode="'+postal_code+'" data-town="'+locality+'" data-street="'+ address +'"><input type="radio" class="" name="option"><span>' + combined_address +'</span></li>';
|
260 |
+
$('crafty-correct').down('ul').insert({top : html});
|
261 |
+
}
|
262 |
+
});
|
263 |
+
//if we click on any suggestion, disable manual input
|
264 |
+
$$('#crafty-correct li:not(.manual) input').each(function(elem){
|
265 |
+
elem.observe('click',function(){
|
266 |
+
$$('.crafty-input').each(function(elem){
|
267 |
+
elem.disable();
|
268 |
+
});
|
269 |
});
|
270 |
});
|
271 |
+
//if we click on manual correct, enable manual input
|
272 |
+
$$('#crafty-correct li.manual input')[0].observe('click',function(){
|
273 |
+
$$('.crafty-input').each(function(elem){
|
274 |
+
elem.enable();
|
275 |
+
});
|
276 |
});
|
277 |
+
//when we press the update button
|
278 |
+
$('button-crafty-modify').observe('click',function(){
|
279 |
+
//check if a suggestion is selected
|
280 |
+
var elem = $$('#crafty-correct li:not(.manual) input[type=radio]:checked');
|
281 |
+
if(elem.length == 1){
|
282 |
+
//gather all data and copy it to the form.
|
283 |
+
var li = elem[0].up('li');
|
284 |
+
$('address').value = li.readAttribute('data-street');
|
285 |
+
$('town').value = li.readAttribute('data-town');
|
286 |
+
$('postcode').value = li.readAttribute('data-postcode');
|
287 |
+
$('region').value = li.readAttribute('data-region');
|
288 |
+
} else {
|
289 |
+
//if it's manual & region dropdown is provided, copy the selected region value to the region form element.
|
290 |
+
if($('region_id').childElements('option').length){
|
291 |
+
$('region').value = $('region_id').options[$('region_id').selectedIndex].innerHTML;
|
292 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
}
|
294 |
+
// pass all form values to an ajax request & update.
|
295 |
+
new Ajax.Request('<?php echo Mage::getUrl('craftyclicksvalidate/ajax/update');?>',
|
296 |
+
{
|
297 |
+
method:'get',
|
298 |
+
parameters: {
|
299 |
+
street: $('address').getValue(),
|
300 |
+
city: $('town').getValue(),
|
301 |
+
postcode: $('postcode').getValue(),
|
302 |
+
region: $('region').getValue()
|
303 |
+
},
|
304 |
+
onSuccess: function(transport){
|
305 |
+
$('correct_box').update('<?php echo $conf['craftyclicksvalidate']['finish_text']; ?>');
|
306 |
+
}
|
307 |
+
});
|
308 |
});
|
309 |
+
|
310 |
+
}
|
311 |
+
});
|
312 |
+
}
|
313 |
}
|
314 |
|
315 |
} );
|
app/etc/modules/CraftyClicksValidate.xml
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
<CraftyClicksValidate>
|
5 |
<active>true</active>
|
6 |
<codePool>local</codePool>
|
7 |
-
<version>0.1.
|
8 |
</CraftyClicksValidate>
|
9 |
</modules>
|
10 |
</config>
|
4 |
<CraftyClicksValidate>
|
5 |
<active>true</active>
|
6 |
<codePool>local</codePool>
|
7 |
+
<version>0.1.3</version>
|
8 |
</CraftyClicksValidate>
|
9 |
</modules>
|
10 |
</config>
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Crafty_Clicks_International_Address_Validation</name>
|
4 |
-
<version>0.1.
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
<channel>community</channel>
|
@@ -11,6 +11,8 @@
|
|
11 |

|
12 |
Upon completing a checkout, the shipping address gets validated, to ensure the existence of the location. In case the address cannot be confirmed, suggestions to fix the address will be shown, with the option to manually check and fix the address.</description>
|
13 |
<notes>Release History
|
|
|
|
|
14 |
v0.1.2
|
15 |
* Stable release
|
16 |
v0.1.1
|
@@ -19,8 +21,8 @@ v0.1.0
|
|
19 |
* Initial Release</notes>
|
20 |
<authors><author><name>Crafty Clicks</name><user>styloa</user><email>support@craftyclicks.co.uk</email></author></authors>
|
21 |
<date>2014-08-21</date>
|
22 |
-
<time>11:
|
23 |
-
<contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="CraftyClicksValidate.xml" hash="
|
24 |
<compatible/>
|
25 |
<dependencies><required><php><min>4.0.0</min><max>6.0.0</max></php></required></dependencies>
|
26 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Crafty_Clicks_International_Address_Validation</name>
|
4 |
+
<version>0.1.3</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
<channel>community</channel>
|
11 |

|
12 |
Upon completing a checkout, the shipping address gets validated, to ensure the existence of the location. In case the address cannot be confirmed, suggestions to fix the address will be shown, with the option to manually check and fix the address.</description>
|
13 |
<notes>Release History
|
14 |
+
v0.1.3
|
15 |
+
* Fix: added check for google CDN state.
|
16 |
v0.1.2
|
17 |
* Stable release
|
18 |
v0.1.1
|
21 |
* Initial Release</notes>
|
22 |
<authors><author><name>Crafty Clicks</name><user>styloa</user><email>support@craftyclicks.co.uk</email></author></authors>
|
23 |
<date>2014-08-21</date>
|
24 |
+
<time>11:45:46</time>
|
25 |
+
<contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="CraftyClicksValidate.xml" hash="6c87a1144f53c07a38d74f68cad2a089"/></dir></dir><dir name="code"><dir name="local"><dir name="CraftyClicksValidate"><dir><dir name="Helper"><file name="Data.php" hash="a96df9efe70446493039881397aa37bf"/></dir><dir name="controllers"><file name="AjaxController.php" hash="cde744ab853107c3c3eb520b1421e5fa"/></dir><dir name="etc"><file name="config.xml" hash="0aca3ef0609b88d3076842eac9aa7635"/><file name="system.xml" hash="e0932e8c5838d5a8855ffb4dd33560cd"/></dir></dir></dir></dir></dir><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="craftyclicks_validate.xml" hash="20bb120782c6b81b71538acf2e2840ff"/></dir><dir name="template"><dir name="craftyclicksvalidate"><file name="post_checkout.phtml" hash="42747c98605c58752cf9ffcb1ba5c326"/></dir></dir></dir></dir></dir></dir></dir><dir name="skin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="craftyclicksvalidate"><file name="validate.css" hash="353e6e8267ce0a7fccad15bc1d1418cd"/><file name="validate_old.css" hash="3a4dd9986bdf93462afb0c6a20ac838e"/></dir></dir><dir name="images"><dir name="craftyclicksvalidate"><file name="crafty_validate_busy.gif" hash="7660c91e294e91f80219d3c8f6512dca"/></dir></dir></dir></dir></dir></dir></target></contents>
|
26 |
<compatible/>
|
27 |
<dependencies><required><php><min>4.0.0</min><max>6.0.0</max></php></required></dependencies>
|
28 |
</package>
|