Sending a plugin to the Wordpress Plugin Directory
Tags: wordpress, plugins, php, pushnotifications
Published: 2020-12-22 01:58:54

I'm the creator of the [Perfecty Push Notifications](https://github.com/rwngallego/perfecty-push-wp/) plugin. This is a Wordpress Plugin that has a built-in [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API) notification integration. You can send push notifications for free, without any third-party dependencies and you retain the data in your server.

![Perfecty Push WP](https://raw.githubusercontent.com/rwngallego/perfecty-push-wp/master/.github/assets/perfecty.gif)

## Publish time! 🤞

Once I decided it was the right time to publish it in the Wordpress Plugin Directory, I reviewed it again using the [detailed plugin guidelines](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/), bundled it and finally uploaded the .zip file to [https://wordpress.org/plugins/developers/add/](https://wordpress.org/plugins/developers/add/)

This was the first step towards publishing the side project I've been recently working on, so I was excited and panicked at the same time. Would it work? What would they complain about the plugin? Would it never take off?

One day later I got an email with a considerable list of recommendations from them:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4a1h7c7scqq29ryleovo.png)

I will list what those issues were. You can take a quick look at the MR that addresses them here:

[https://github.com/rwngallego/perfecty-push-wp/commit/0c9f4e6b7aed12ff0a81b20896f9235663066a4f](https://github.com/rwngallego/perfecty-push-wp/commit/0c9f4e6b7aed12ff0a81b20896f9235663066a4f)

### Calling files remotely

For the admin area, I'm drawing a simple stat chart using [Chart.js](https://www.chartjs.org/).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/biem5mu4pr7xaez9wftn.png)

I initially thought it was not necessary to include it as an enqueued javascript but as a simple direct inline import in the HTML.

```html
<script  
 src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"
 integrity="sha512-SuxO9djzjML6b9w9/I07IWnLnQhgyYVSpHZx0JV97kGBfTIsUYlWflyuW4ypnvhBrslz1yJ3R+S14fdCWmSmSA=="
 crossorigin="anonymous">
</script>
```

However, that's not what is suggested in the [plugin guidelines, calling third-party systems](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#8-plugins-may-not-send-executable-code-via-third-party-systems), so I had to bundle the min.js file with the plugin and mention it in the README.txt:

```php
wp_enqueue_script(
  'chartjs',
  plugin_dir_url( __FILE__ ) . 'js/chart.bundle.min.js',
  array( 'jquery' ),
  $this->version,
  false );
```

```
This plugin uses the [Chart.js](https://www.chartjs.org/) library for the admin stats charts.
```

### Data Must be Sanitized, Escaped, and Validated

This is related to this admin page:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4tjuagf9iy5ttbays1dv.png)


I am relying on the well-known WP_List_Table API implementation and honestly didn't catch it, so it was a nice find from them:

```php
perfecty-push-wp/admin/class-perfecty-push-admin-notifications-table.php:118: $ids = is_array( $_REQUEST['id'] ) ? $_REQUEST['id'] : array( $_REQUEST['id'] );
perfecty-push-wp/admin/class-perfecty-push-admin-notifications-table.php:28: 'view' => sprintf( '<a href="?page=%s&action=%s&id=%s">%s</a>', $_REQUEST['page'], 'view', $item['id'], 'View' ),
perfecty-push-wp/admin/class-perfecty-push-admin-notifications-table.php:29: 'delete' => sprintf( '<a href="#" data-page="%s" data-action="%s" data-id="%d" data-nonce="%s">%s</a>', $_REQUEST['page'], 'delete', $item['id'], $action_nonce, 'Delete' ),

perfecty-push-wp/admin/partials/perfecty-push-admin-notifications.php:13: <input type="hidden" name="page" value="<?php echo $_REQUEST['page']; "/>
perfecty-push-wp/admin/partials/perfecty-push-admin-users.php:12: <input type="hidden" name="page" value="<?php echo $_REQUEST['page']; "/>
```

And it was very easy to fix:

```
$page = esc_html( sanitize_key( $_REQUEST['page'] ) );
```

For the issue in the `class-perfecty-push-admin-notifications-table.php:118` line, honestly I thought it was sufficient with the `intval()` filtering to each of the elements:

```php
		$ids = array_map(
			function( $item ) {	
				return intval( $item );	
			},	
			$ids	
		);
```

However, I decided to do the recommended sanitization:

```php
		$ids = array_map(
			function( $item ) {
				$item = sanitize_key( $item );
				return intval( $item );
			},
			$ids
		);
```

### Included Unneeded Folders

This was me not knowing how the final structure of the distributable .zip file should look like. I was including some unnecessary folders and files. With their suggestions and reading the guidelines again, I just created a new shell command that copies the required files and the optimized vendor folder:

```sh
bundle() {
  CMD=$(plugin_cmd 'rm -rf vendor && composer install --no-dev --optimize-autoloader')
  compose_exec "$CMD"
  cp index.php vendor/
  zip -v -r perfecty-push-wp.zip admin/ assets/ includes/ languages/ lib/ public/ vendor/ composer.json composer.lock index.php LICENSE.txt perfecty-push.php README.txt uninstall.php
}
```

The final folder structure looks like:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bn3wey1sj1av28yeutno.png)

### Please use wp_enqueue commands

This is tied to the first issue with Chart.js. As I was including it directly, I was not using `wp_enqueue`. Now that I'm bundling it, it is already addressed.

And that was it! ✅

## Extra

While reviewing their suggestions I noticed I didn't put the dummy `index.php` file in some of the folders having PHP files so I also did that.

## Let's reply to the email

Once I fixed those issues I got back to them and send the link to the distributable .zip file generated from the shell:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3zcgh73uc09vrei8ykld.png)

~~I'm still waiting for their comments and I expect more input from them, so I'll keep you posted!~~

I've received feedback even before posting this and apparently now I need to address some outdated dependencies from Composer, which ultimately affects the planned minimum PHP version I was intended to support. For that I will create a new post with further details. Thanks for reading!

## Photos

Cover: <span>Photo by <a href="https://unsplash.com/@spacex?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">SpaceX</a> on <a href="https://unsplash.com/s/photos/launch?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>