Wednesday, January 31, 2024

WordPress 6.4.3 MacOS Compressed Zip plugin archives "Incompatible Archive" on upload

 If I zip a plugin folder using MacOS right-click Compress command in the contextual menu, those archives are no longer accepted when using upload plugin ( WordPress 6.4.3  ). It returns "Incompatible Archive". This has worked up until now. The issue is related to the recent security updates for the plugin and theme uploader.

If I create a zip on the command line of the same folder that works correctly.


In short: The ZIPARCHIVE::CHECKCONS flag causes checks to use a "pedantic" mode, which Apple's Archive too fails.
(For some internals from an Apple dev, see https://wordpress.org/support/topic/macos-zip-files-made-with-the-built-in-archive-utility-arent-accepted/#post-15815401 ).

This has previously affected WordPress (#12637) and WP-CLI (https://github.com/wp-cli/extension-command/issues/362).

It looks like libzip has a solution already (https://github.com/nih-at/libzip/issues/341 and https://github.com/nih-at/libzip/commit/b3e3b19e2e4b7d4651d01148f123129429ecc69b) but that will probably still need to make its way to servers...

One solution for Core could be to just repeat the call to $archive->open( $file['file'] ) (but without the ZIPARCHIVE::CHECKCONS flag) or to try a fallback check with PclZip on failure as well (and not just if the ZipArchive class is not available).

Lowering the severity since there is currently a workaround on both the zip creation side ( use the command line) and the individual site side ( add_filter( 'unzip_file_use_ziparchive', '_return_false' ); ).


creating your zip file manually works.
(using terminal on MacOS, instead of right-click > compress in finder)

zip -vr theme.zip your_theme/

see: https://superuser.com/q/505034/415143

p.s. use the zip command, not ditto (since that is the same as compress in finder)


The workaround here where impacted plugin authors can STOP using the MacOS UI for generating ZIPs and START using the command line to do so. Like below

zip -r webtoffee-product-feed.zip webtoffee-product-feed

Thursday, December 31, 2015

Hook Drupal Ajax Function on Webform Submit

(function($) {

    Drupal.subscribeAjax = {
        form_id: 'webform-client-form-34'  // your webform id
    };

    Drupal.behaviors.subscribeAjax = {
        attach: function(context, settings) {
            // Extend Drupal.ajax object
            for (ajax_el in settings.ajax) {
                if (typeof Drupal.ajax[ajax_el] != 'undefined' && Drupal.ajax[ajax_el].element.form) {
                    if (Drupal.ajax[ajax_el].element.form.id === Drupal.subscribeAjax.form_id) {
                        Drupal.ajax[ajax_el].beforeSend = Drupal.subscribeAjax.beforeSend;
                        Drupal.ajax[ajax_el].success = Drupal.subscribeAjax.success;
                        Drupal.ajax[ajax_el].error = Drupal.subscribeAjax.error;
                    }
                }
            }
        }
    };

    Drupal.subscribeAjax.beforeSend = function(first, second) {
        console.log("before submit");
        Drupal.ajax.prototype.beforeSend.call(this, first, second);
    }
    Drupal.subscribeAjax.success = function(response, status) {
        console.log("on success");
        //console.log(JSON.stringify(response));
        Drupal.ajax.prototype.success.call(this, response, status);
    }
    Drupal.subscribeAjax.error = function(response, uri) {
        console.log("on error");
        Drupal.subscribeAjax.enableForm(this.element.form);
        Drupal.ajax.prototype.error.call(this, response, uri);
    }

})(jQuery);
// ajaxComplete
(function($) {
$(document).ajaxComplete(function(event, xhr, options) {
            var data = $.httpData(xhr,options.dataType);
            //console.log(JSON.stringify(data));
                $('#webform-ajax-wrapper-34 .error').delay(5000).fadeOut(400);
});
}(jQuery));

Wednesday, September 9, 2015

Programmatically Creating a new Content Type in Drupal7

To create a module, in the sites/all/modules directory of your Drupal installation create a new directory named mymodule.
 Create following three files in mymodule folder:
·         mymodule.info– will contain the information about the module so that Drupal will recognize it and show it in the list.
·         mymodule.install – will have details about things you are going to install or uninstall for the module.
·         mymodule.module – will contain code to implement the Drupal hooks used by the module.
Once you have made the directory, open mymodule.info and add the following code to it:
name = mymodule
description = A new custom content type creation by mujuonly
package = mymodule Custom node Type
version = "7.x-1.12"
core = 7.x
files[] = mymodule.install 
files[] = mymodule.module 
The above simply defines some parameters for our module (mymodule) so Drupal can use it and display the information about  mymodule. Once this is done we should see mymodule in the module list as shown below.

Installing and Uninstalling Content Type
Once we have the basic files for the module in place, we can start writing code for installing the custom node type. The first hook we need to implement is hook_node_info. Using this hook, a module can define one or more node types in Drupal. The hook implementation returns an array defining the new node type which the module is going to add.
To implement this hook, add the following code to mymodule.module
/**
 * Implements hook_node_info()
 */
function mymodule_node_info() {
    return array(
        'news' => array(
            'name' => t('News'),
            'base' => 'news',
            'description' => t('You can add  News here'),
            'has_title' => TRUE,
            'title_label' => t('News title')
         )
    );
}
The implementation returns an array defining a new node type news  along with some of its properties, such as its name, description, title, and base.
As we have defined that this node type has a title, we need to show the title text field when the form for this node is displayed to add content. To do this, we will have to implement the hook hook_form.
The hook_form is used to show the form for create/edit nodes. The hook is implemented in mymodule.module as follows:
/**
 * Implement hook_form()
 */
function mymodule_form($node, $form_state) {
    return node_content_form($node, $form_state);
}
We simply use the Drupal API which gives an implementation of hook_form and adds a title field provided the node definition has the has_title attribute set .Once we have got this done, we need to implement the hook_install hook to add the body field to the new node type.
Add the implementation to mymodule.install is as follows:
/**
 * Implements hook_install().
 */
function mymodule_install() {
    node_types_rebuild();
    $types = node_type_get_types();|
      node_add_body_field($types['news']);
}
We first save all of the new node types created by different modules by calling the Drupal API node_types_rebuild() function. Then we get all of the node types and call node_add_body_field() on our type to add the body field.
Once we have done this we can enable mymodule which will install our new node type. Then we should be able to see our new type when we click on add content as follows:

If we add a new news, it will also be seen on the Drupal front page.
All modules in Drupal should clean up any data they create in the database or any types they have added when it is uninstalled by the user. To support this, we have to implement the hook_uninstall in ou mymodule.install file as follows:
/**
 * Implements hook_uninstall().
 */
function mymodule_uninstall() {
    $customtype = 'news';
    $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
    $result = db_query($sql, array(':type' => $customtype));
    $nodeids = array();
    foreach ($result as $row) {
        $nodeids[] = $row->nid;
    }
    node_delete_multiple($nodeids);
    node_type_delete($customtype);
}
We first find out all of the node IDs which are nodes of our installed content type. Once we have collected the IDs, we use the API function node_delete_multiple() to delete multiple nodes. Then we use the node_type_delete() function to delete our node type.

Now if we uninstall our module, all of the nodes of our type and our type itself should be deleted.

Tuesday, September 8, 2015

Resetting the admin password of Drupal 7

Frequently we come across Drupal sites where admin  password is not known to the owner of the site. You can retrieve the password by changing the email address of user 1 to your email address and then use the forgot password option to reset your password. But if you don't want to change the user 1 email address but instead just want to change the password of user 1 there is an easier alternative

Use below PHP Code in index.php of drupa with URL paramas as  ?pass=PASSWORD and run. After that roll back to old index.php
 
It Will  set your admin password to PASSWORD

define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
require_once DRUPAL_ROOT . '/includes/password.inc';
if (isset($_GET['pass']) && !empty($_GET['pass'])) {
  $newhash user_hash_password($_GET['pass']);
}
else {
  die('Retry with ?pass=PASSWORD set in the URL');
}
$updatepass = db_update('users') 
  ->fields(array(
    'pass' => $newhash,//    'name' => 'admin',
//    'mail' => 'yourmail@example.com'
  ))
  ->condition('uid', '1', '=')
  ->execute();
print "Done. Please delete this file immediately!";drupal_exit();?>

Sunday, September 6, 2015

Simple SEO things with Google Webmaster Tools

Below are some points that makes your website indexed in google search results with help of google webmaster tools




Check Gzip compression enabled in website

Below is an online tool to test if Gzip compression is working on your webpage.

https://varvy.com/tools/gzip/

 

Use Google PageSpeed Insights to check speed of your website.


You can check your website speed here

https://developers.google.com/speed/pagespeed/insights/?url=

There is mobile and desktop view checking in one go.

CSS , JS and Image optimization tips are there , if not optimized.

Also Googlechrome plugin is available in chrome store