Unicom360 SMS Notifications
Unicom360 SMS Notifications: send SMS from WordPress and order updates from WooCommerce
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/techrode-solution-limited/unicom360-wordpress/archive/refs/heads/main.zipUnicom360 SMS Notifications for WordPress
The official WordPress plugin for the Unicom360 messaging gateway:
a Send SMS screen, a log, and WooCommerce order status notifications for customers and the
store. This is the developer readme; readme.txt is what wordpress.org shows.
- Slug and text domain:
unicom360. Licence: GPL-2.0-or-later. - Requires WordPress 6.9+ and PHP 7.4+. WooCommerce is optional (9.0+ for order notifications).
- No runtime dependencies. The plugin has its own thin client on the WordPress HTTP API, tested
on the shared conformance fixtures for the operations it uses
(
sms.send,balance.get,balance.all).
Layout
| Path | Holds |
|---|---|
unicom360.php |
Plugin header, constants, includes |
uninstall.php |
Clean-up on delete |
includes/ |
Client, GSM-7, phones, templates, settings, log, WooCommerce, privacy |
includes/admin/ |
Menu, Send SMS and Log screens, Settings API page, list table |
assets/ |
Admin script (counter), GSM helpers, styles |
languages/unicom360.pot |
Translation template |
.wordpress-org/ |
Icons, banners and screenshots for the SVN assets directory (never in the zip) |
tests/unit |
Pure PHP tests with WordPress stand-ins |
tests/conformance-suite |
The fixtures; runs in both the unit and the integration suite |
tests/integration |
Real WordPress and WooCommerce in wp-env, including the Prism end-to-end test |
tests/js |
The browser counter on the same GSM vectors |
Set up
composer install
npm install
composer.json pins the platform to PHP 7.4, so the tools resolve to versions that run on 7.4
as well as on current PHP.
Check
composer validate --strict
vendor/bin/phpcs # WordPress-Extra, WordPress-Docs, PHPCompatibilityWP 7.4+
vendor/bin/phpstan analyse --memory-limit=1G
vendor/bin/phpunit # unit and conformance
npm run test:js # the counter
docker run --rm -v "$PWD":/repo -w /repo zricethezav/gitleaks:v8.21.2 detect --source=. --no-banner --redact
# On the minimum and the latest PHP.
docker run --rm -v "$PWD":/app -w /app php:7.4-cli vendor/bin/phpunit
docker run --rm -v "$PWD":/app -w /app php:8.4-cli vendor/bin/phpunit
Integration tests and Plugin Check (wp-env, needs Docker)
.wp-env.json maps two copies of the plugin. The tests environment gets the working tree
(with vendor/ and tests/); the development environment gets the built plugin, so Plugin
Check sees exactly what ships. Build first, because the mapping needs build/unicom360:
bin/build-zip
npx wp-env start # installs the latest stable WooCommerce and Plugin Check
# Integration suite (no Prism needed: HTTP is stubbed through pre_http_request).
npx wp-env run tests-cli --env-cwd=wp-content/plugins/unicom360 \
vendor/bin/phpunit -c phpunit-integration.xml.dist
# The same on post storage instead of High-Performance Order Storage.
npx wp-env run tests-cli --env-cwd=wp-content/plugins/unicom360 \
env UNICOM360_TEST_LEGACY_ORDERS=1 vendor/bin/phpunit -c phpunit-integration.xml.dist
# Plugin Check on the built plugin, runtime checks included.
npx wp-env run cli wp plugin activate unicom360
npx wp-env run cli wp plugin check unicom360 \
--require=./wp-content/plugins/plugin-check/cli.php --include-experimental
wp-env 12 warns that the env key in .wp-env.json is deprecated. package.json pins the
version, so it keeps working; moving to separate config files is a job for the next wp-env bump.
Both environments set UNICOM360_API_BASE_URL to Prism, so nothing in wp-env can reach the live
API by accident. Run bin/build-zip again after changing the plugin: the development environment
serves the build, and the script updates it in place.
The minimum versions
The floor stated in the plugin's headers is tested as one combination. .wp-env.override.json
is gitignored:
{
"core": "WordPress/WordPress#6.9",
"phpVersion": "7.4",
"lifecycleScripts": {
"afterStart": "npx wp-env run tests-cli wp plugin install https://downloads.wordpress.org/plugin/woocommerce.9.0.0.zip --force"
}
}
The zip URL is deliberate: wp-env run takes --version as its own flag and installs the latest
release instead. Delete the override and run npx wp-env start to return to the latest versions.
End-to-end against Prism
The e2e group changes a real order's status, lets Action Scheduler run the job, and sends real
HTTP to a Prism mock of openapi.yaml. Prism answers 200 only for a request that matches the
contract, so a green run proves the plugin's requests are valid.
docker run -d --rm --name unicom360-wp-prism -p 4019:4010 \
-v "$PWD/tests/fixtures:/spec:ro" stoplight/prism:5 \
mock --multiprocess=false --errors -h 0.0.0.0 /spec/openapi.yaml
npx wp-env run tests-cli --env-cwd=wp-content/plugins/unicom360 \
vendor/bin/phpunit -c phpunit-integration.xml.dist --group e2e
docker stop unicom360-wp-prism
npx wp-env stop
UNICOM360_API_BASE_URL
A constant for development: it points the plugin at another API base URL.
define( 'UNICOM360_API_BASE_URL', 'http://host.docker.internal:4019' );
https is accepted for any host. Plain http is accepted only for localhost, 127.0.0.0/8,
::1 and host.docker.internal, and only when wp_get_environment_type() is local or
development. A value outside those rules is ignored, the production URL is used, and the
plugin's screens say so. The tests environment sets it in .wp-env.json.
Fixtures
tests/fixtures/conformance is a vendored copy of unicom360-openapi/conformance, and
tests/fixtures/openapi.yaml of its spec; never edit them here. To update, from
unicom360-openapi:
scripts/sync-conformance ../unicom360-wordpress/tests/fixtures/conformance
cp openapi.yaml ../unicom360-wordpress/tests/fixtures/openapi.yaml
tests/conformance-suite/FixturesTest.php recomputes the tree hash against VERSION.
Translations
docker run --rm -v "$PWD":/app -w /app wordpress:cli wp i18n make-pot . languages/unicom360.pot \
--slug=unicom360 --domain=unicom360 --exclude=vendor,node_modules,tests,build,bin --allow-root
Assets
bin/build-banners regenerates .wordpress-org/ (icons from the portal icon, banners composed
from the website logo). From this monorepo it finds both by itself; otherwise pass LOGO= and
ICON=. Docker is needed for ImageMagick.
screenshot-1.png to screenshot-6.png were taken from the development environment against
Prism, with a made-up store, in the order readme.txt lists them. tests/unit/ReadmeTest.php
fails if a listed screenshot is missing.
Build
bin/build-zip # build/unicom360-<version>.zip, with build/unicom360/ beside it
The script copies the tree minus .distignore, and fails if a dev file got through or a required
file is missing. Check the result with unzip -l build/unicom360-*.zip.
Release
- Set the version in
unicom360.php(the header andUNICOM360_VERSION),includes/class-unicom360-client.php,readme.txt(Stable tag),package.jsonandCHANGELOG.md.tests/unit/VersionsTest.phpfails until they agree. - Update
Tested up toandWC tested up towhen newer versions have been tested. - Regenerate the
.pot, and commit. - Tag
vX.Y.Zand push the tag.
.github/workflows/release.yml checks the tag against the plugin's version, then deploys to
wordpress.org with 10up/action-wordpress-plugin-deploy and creates a GitHub Release with the
zip. It needs the SVN_USERNAME and SVN_PASSWORD secrets. release.yml also updates the SVN
assets directory, and any push to main that touches readme.txt or .wordpress-org/
refreshes them on their own (10up/action-wordpress-plugin-asset-update).
Manual SVN fallback
The first submission is by hand anyway: upload the zip at https://wordpress.org/plugins/developers/add/, and wait for the review. Once the plugin is approved, and any time Actions is unavailable:
bin/build-zip
svn checkout https://plugins.svn.wordpress.org/unicom360 svn-unicom360
cd svn-unicom360
rsync -a --delete ../build/unicom360/ trunk/
rsync -a --delete ../.wordpress-org/ assets/
svn add --force trunk assets
svn status | awk '/^!/ {print $2}' | xargs -r svn rm
svn propset svn:mime-type image/png assets/*.png
svn cp trunk tags/1.0.0
svn commit -m "Release 1.0.0" --username "$SVN_USERNAME"
svn is not installed everywhere; any image with Subversion works, for example
docker run --rm -it -v "$PWD":/w -w /w alpine sh -c 'apk add subversion rsync && sh'.
Licence
GPL-2.0-or-later. See LICENSE.