{"id":28919246,"url":"https://github.com/esmond-m/em-daily-posts-queue","last_synced_at":"2026-04-30T07:37:21.176Z","repository":{"id":298234685,"uuid":"996990184","full_name":"Esmond-M/em-daily-posts-queue","owner":"Esmond-M","description":"This plugin allows for daily posts to be displayed on the front-end.","archived":false,"fork":false,"pushed_at":"2025-06-10T03:51:26.000Z","size":357,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-10T04:32:20.151Z","etag":null,"topics":["cronjob-scheduler","customposttype","wordpress","wordpress-plugin"],"latest_commit_sha":null,"homepage":"https://esmondmccain.com/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Esmond-M.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-05T19:20:34.000Z","updated_at":"2025-06-10T03:51:29.000Z","dependencies_parsed_at":"2025-06-10T04:32:29.164Z","dependency_job_id":"a44e52ea-2999-4fc4-b948-d78284f587ac","html_url":"https://github.com/Esmond-M/em-daily-posts-queue","commit_stats":null,"previous_names":["esmond-m/em-daily-posts-queue"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Esmond-M/em-daily-posts-queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esmond-M%2Fem-daily-posts-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esmond-M%2Fem-daily-posts-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esmond-M%2Fem-daily-posts-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esmond-M%2Fem-daily-posts-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Esmond-M","download_url":"https://codeload.github.com/Esmond-M/em-daily-posts-queue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esmond-M%2Fem-daily-posts-queue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261229077,"owners_count":23127552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cronjob-scheduler","customposttype","wordpress","wordpress-plugin"],"created_at":"2025-06-22T03:04:19.216Z","updated_at":"2026-04-30T07:37:21.170Z","avatar_url":"https://github.com/Esmond-M.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Esmond Daily Posts Queue\n\n**Project:** [https://github.com/Esmond-M/em-daily-posts-queue](https://github.com/Esmond-M/em-daily-posts-queue)  \n**Author:** [esmondmccain.com](https://esmondmccain.com/)  \n**Version:** 0.1.2\n\n## Summary\n\nOriginally made for an intranet website. Packaged as a reusable plugin. Allows daily posts to be displayed on the front end via shortcode. Visitors submit photos through a front-end form; a custom admin role can then review, reorder, and manage the queue. The top post in the queue is automatically rotated out on a weekday schedule using Action Scheduler.\n\n## Requirements\n\n- **WordPress:** 6.1+\n- **PHP:** 7.4+\n- **Required Plugin:** [Action Scheduler](https://actionscheduler.org/)\n\n## Quick Start — Shortcodes\n\nAfter activation, go to **Net Submissions → 📋 Shortcodes** in the WP admin sidebar, or check the **Daily Posts Queue** widget on the main dashboard. Both show copy buttons for each shortcode.\n\n| Shortcode | Where to use |\n|---|---|\n| `[EmDailyPostsQueueForm]` | Any page where visitors submit photos |\n| `[EmDailyPostsQueueDisplayPost]` | Any page/widget area to show today's post |\n\nBoth shortcodes accept an optional `class` attribute:\n```\n[EmDailyPostsQueueForm class=\"my-wrapper\"]\n[EmDailyPostsQueueDisplayPost class=\"my-wrapper\"]\n```\n\n## Features\n\n- **Photo submission form** — front-end shortcode form; visitors upload a photo, headline, and caption (max 8 MB, JPG/PNG)\n- **Daily post display** — shortcode that renders the current first-in-queue post (image, headline, caption)\n- **Drag-and-drop queue management** — admin sub-menu to reorder or remove submissions\n- **Automatic daily rotation** — Action Scheduler advances the queue every weekday; admins can customise the trigger time from the WP timezone settings\n- **Demo content import** — one-click button on the queue edit page to seed 4 sample posts\n- **Custom post type** `net_submission` — separate from regular posts; supports title and featured image\n- **Custom role** `Net Submitter` — limited access; can submit and view own submissions only\n- **Shortcode reference** — dedicated admin sub-menu page + dashboard widget so shortcodes are always visible\n- **Optimistic concurrency** — queue edits check for stale data and warn before overwriting\n- **JSON queue storage** — queue stored as JSON (migrated transparently from legacy serialize+base64)\n\n## Installation\n\n1. Download the latest zip from [build/em-daily-posts-queue.zip](https://github.com/Esmond-M/em-daily-posts-queue/blob/main/build/em-daily-posts-queue.zip).\n2. In WordPress admin go to **Plugins → Add New → Upload Plugin**.\n3. Upload the zip and activate.\n4. Install and activate the **Action Scheduler** plugin.\n5. Find your shortcodes under **Net Submissions → 📋 Shortcodes**.\n\n![Queue List](/docs/imgs/queue-list.png \"Queue List\")\n\n## Usage\n\n### 1. Add the submission form to a page\n```\n[EmDailyPostsQueueForm]\n```\nVisitors fill in a headline, caption, and photo. On submission an email is sent to the site admin.\n\n### 2. Display the current daily post\n```\n[EmDailyPostsQueueDisplayPost]\n```\nShows the featured image, headline, and caption of the first item in the queue.\n\n### 3. Manage the queue\n1. Go to **Net Submissions → Edit Photo Queue**\n2. Reorder items by changing the queue number fields and saving\n3. Delete individual items with the remove button\n4. Import demo content with the **Import Demo** button\n5. Adjust the daily rotation time under the cron settings panel\n\n### 4. Review submissions\nGo to **Net Submissions** to see all submitted posts. Publishing a post automatically appends it to the end of the queue.\n\n## Technical Details\n\n### Database\n| Table | Purpose |\n|---|---|\n| `{prefix}edpq_net_photos_queue_order` | Stores queue order as a JSON array of `{postid, queueNumber}` objects |\n\n### Meta Fields\n| Key | Description |\n|---|---|\n| `topic_headline_value` | Submission headline |\n| `topic_caption_value` | Submission caption |\n\n### Custom Post Type\n- **Slug:** `net_submission`\n- **Supports:** title, thumbnail\n- **Custom capabilities:** `edit_net_submission`, `read_net_submission`, `delete_net_submission`, etc.\n\n### User Roles\n- **Net Submitter** — can create/read own `net_submission` posts and upload files; no access to queue management\n- **Administrator** — full access including queue edit, wipe, and cron controls\n\n### Shortcodes\n| Shortcode | Class | Description |\n|---|---|---|\n| `[EmDailyPostsQueueForm]` | `EmDailyPostsQueue\\init_plugin\\Classes\\Shortcodes` | Renders the photo submission form |\n| `[EmDailyPostsQueueDisplayPost]` | `EmDailyPostsQueue\\init_plugin\\Classes\\Shortcodes` | Renders the current daily post |\n\n## API Hooks\n\n### Actions\n| Hook | Description |\n|---|---|\n| `init` | CPT registration, role setup, cron scheduling |\n| `add_meta_boxes` | Custom meta box registration |\n| `save_post` | Saves headline/caption meta |\n| `publish_net_submission` | Appends post to queue on first publish |\n| `trashed_post` | Force-deletes instead of trashing |\n| `eg_1_weekdays_log` | Action Scheduler hook that advances the queue |\n\n### Filters\n| Hook | Description |\n|---|---|\n| `post_row_actions` | Removes Quick Edit and Trash from submission list |\n| `bulk_actions-edit-net_submission` | Removes bulk edit action |\n| `template_include` | Loads plugin template for single `net_submission` view |\n\n## Development Setup\n\n### Prerequisites\n- WordPress local environment with database access\n- Composer\n- PHPUnit (included via composer)\n- Node.js + npm (for `plugin-zip` build script)\n\n### Setup\n\n```bash\ngit clone https://github.com/Esmond-M/em-daily-posts-queue.git\ncd em-daily-posts-queue\ncomposer install\n```\n\nConfigure `tests/wp-config.php`:\n```php\ndefine( 'DB_NAME',     'wordpress_test' );\ndefine( 'DB_USER',     'your_username' );\ndefine( 'DB_PASSWORD', 'your_password' );\ndefine( 'DB_HOST',     'localhost' );\n```\n\n### Build zip\n\n```bash\nnpm run plugin-zip\n# Output: build/em-daily-posts-queue.zip\n```\n\n### File Structure\n```\nem-daily-posts-queue/\n├── admin/assets/           # Admin-only CSS and JS\n├── assets/                 # Frontend CSS, JS, images\n├── classes/\n│   ├── class-cpt-net-submission.php          # CPT registration + roles\n│   ├── class-cpt-net-submission-meta.php     # Meta box (headline, caption)\n│   ├── class-cron-event-timer.php            # Action Scheduler scheduling\n│   ├── class-cron-events.php                 # Weekly queue rotation logic\n│   ├── class-photo-submission-ajax.php       # All AJAX handlers\n│   ├── class-photo-submission-queue-manager.php  # Main admin controller\n│   ├── class-photo-submission-utils.php      # DB helpers, queue encode/decode\n│   └── class-shortcodes.php                  # Frontend shortcode renderers\n├── templates/\n│   ├── options-page-admin-queue-edit.php     # Queue reorder UI\n│   ├── options-page-admin-queue-list.php     # Queue read-only list\n│   ├── shortcode-reference.php               # Shortcode reference card\n│   └── single-net-submission.php             # Single post template\n├── tests/\n│   ├── bootstrap.php\n│   ├── EmDailyPostsQueueUIManagerTest.php\n│   └── wp-config.php\n├── docs/\n├── vendor/\n├── composer.json\n├── phpunit.xml\n├── package.json\n├── em-daily-posts-queue.php   # Plugin entry point\n└── readme.md\n```\n\n## Testing\n\n```bash\n# Run all tests\n.\\vendor\\bin\\phpunit --bootstrap tests/bootstrap.php tests\n\n# Run with verbose output\n.\\vendor\\bin\\phpunit --bootstrap tests/bootstrap.php tests --verbose\n```\n\n### Coverage areas\n- CPT registration, roles, capabilities\n- Meta box rendering and save\n- Queue array comparison and conflict detection\n- Cron scheduling and queue rotation\n- Shortcode registration\n- AJAX handler security (nonce, capability checks)\n\n## Changelog\n\n### Version 0.1.2\n- **Security:** Replaced `serialize`/`base64` queue storage with `json_encode`; eliminates PHP object injection risk\n- **Security:** `net_photo_deletion_info_ajax` no longer registered as `nopriv`; added nonce and capability checks to AJAX handlers\n- **Security:** Sanitised all `$_POST` inputs (`sanitize_text_field`, `sanitize_textarea_field`, `(int)` casts)\n- **Security:** `$wpdb-\u003eprepare()` used consistently; removed one unparameterised `UPDATE` query\n- **Feature:** Added **Shortcodes** submenu page (📋) under Net Submissions CPT menu\n- **Feature:** Added dashboard widget showing both shortcodes with copy-to-clipboard buttons\n- **Bug fix:** Fatal `TypeError: Cannot access offset on string` on queue list page when DB contained the install greeting row\n- **Bug fix:** `get_queue_list_from_db` and `get_queue_list` were identical; unified via `decode_queue()` helper with legacy migration\n- **Bug fix:** `new CronEvents` at file scope removed; instantiation moved to plugin bootstrap only\n- **Bug fix:** `wp_set_current_user()` hack replaced with direct `admin_url()` call for edit links\n\n### Version 0.1.1\n- Queue system now guarantees sequential queue numbers (no gaps)\n- Changed admin queue container class name for uniqueness\n- Removed bulk edit options for net_submission post type\n- Added demo content import button to admin queue edit page\n- Added cron event time update and display using WordPress timezone\n- Added stubs for Action Scheduler functions to prevent IDE warnings\n- Disabled submit buttons during form submission for better UX\n\n### Version 0.1.0\n- Initial release\n- Custom post type and user role creation\n- Frontend form and display shortcodes\n- Queue management system\n- Cron-based automatic posting\n- Comprehensive test suite\n\n## Support\n\nFor issues and feature requests, please visit the [GitHub repository](https://github.com/Esmond-M/em-daily-posts-queue/issues).\n\n## License\n\nThis plugin is licensed under GPL","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesmond-m%2Fem-daily-posts-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesmond-m%2Fem-daily-posts-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesmond-m%2Fem-daily-posts-queue/lists"}