====== Classified ====== This is a rebuild of the original http://drupal.org/project/ed_classified module for Drupal 6 (and later), dropping any 4.x/5.x remnants. Download or clone from http://bit.ly/cIBtcN ===== Battle plan for multiple node types =====

Node types

As per #195494, the goal is to support multiple node types.

Extra fields to Field

The module defines two form extra fields, expires_fs on forms and expires for display

Custom lists to Views

The module has inner knowledge of the specifics of the expiration extra fields.

Lists are built either using custom built lists including it, or using the new custom view mode introduced in 7.3. With multiple node types, this is no longer doable so we replace these lists by taxonomy-filtered views.

With the extra field gone, its Views field handler no longer works.

Configuration

Custom logic

Most of the module complexity lies in the expiration handling: automatic expires generation and update. This needs to be adapted for the additional complexity of a field over an extra field. Existing node form hooks and handlers must be replaced by field hooks since we no longer know which forms to intercept.

i18n

A number of users have expressed frustration at the lack of i18n support in the module. Switching the extra fields to a field and the custom lists to Views will help with this. New code should be i18n-compatible, so that later changes can bring full i18n compliance

Testing

The code currently has 100% S0 test coverage. This should not go down, but increase towards 100% C0.

Drupal 8

Any significant work should take into account the directions taken by D8. The move from an extra field to a normal field is in the right direction. Other significant changes regard code placement outside the module file and the use of autoloaded namespaced classes, one per file.

===== Services provided by the module ===== - 1 specific vocabulary: `classified_categories`, supplied with 2 sample terms (Wanted and For Sale) - 1 specific node type: `classified` equipped with - a taxonomy_term_reference field pointing to the module vocabulary - a body field - 3 blocks: - recent ads (public) - popular ads (public) - ad stars (admin) - 1 Context Condition plugin - 1 CTools "content type" plugin to expose the `expires` pseudo field - 2 permissions - `administer classified ads` - `reset classified ads expiration` - 2 extra fields - `expires_fs`: a form extra field allowing selection of an expiration type and optionally a manual expiration date for ad nodes - `expires`: a display extra field formatting the expiration date for ad nodes - 1 notifications submodule: send notifications - at half-life - before|on expiration - before|on purge - 3 drush commands - `classified-purge` to purge expired nodes - `classified-expire` to expire nodes - `classified-notify` to send notifications - 1 custom view mode for `node` - 2 menu loaders - notify kind - taxonomy term, only accepting terms from the module vocabulary - 3 user tokens - `[classified-ads]` themed list of user ads - `[classified-ads-plain]` raw list of user ads - `[classified-ads-url]` url of a user's ads list - 2 theme items - `classified_admin_lifetimes` - `classified_expires` for the `expires` extra field - 1 field formatter for term_reference fields, linking to the per-term ad list instead of the default term page, with an optional link title - node form logic - handle the extra field - provide fieldset-level access control for expiration type - maxlength JS - auto-hiding manual expiration date when irrelevant - node access logic - requirements logic - detect incompatible older version - detect missing Statistics module - detect misconfigured Statistics module - detect non-tree hierarchy in the module vocabulary - taxonomy change logic for terms and vocabularies - URL outbound rewriting logic to redirect term links to ad lists when applicable - Views integration logic - expose virtual fields: - `expires`: field, sort, filter - `purge`: field - 1 field handler for `purge` - default views logic scanning the `views/` folder, but no views provided - configuration variables - `classified-max-length` for the maxlength JS - `classified-list-body` List display format - `classified-edit-modr8` (obsolete) modr8 integration - `classified-lifetime-default` default lifetime - `classified-lifetime-` per-tid lifetime overrides - `classified-grace` grace delay before purge - 100% S0 Simpletest coverage - pages - an overview page - term pages listing ads and ad counts - per-user ads profile tab page - 7 advanced help pages - custom CSS - specific formatting for `expires` - advanced help improvements - ads list custom formats ===== OK Paths ===== * admin/content/node/ed-classified: ed_classified_admin_overview() = an admin page listing ads: redundant with admin/content * admin/content/ed-classified: ed_classified_admin_overview() = an admin page listing ads (duplicate): idem * ed-classified: ed_classified_page() = a page listing ads * user/%user/ed-classified: ed_classified_by_user() now at user/%user/classified = per-user ads list * admin/settings/ed-classified: dgf/ed_classified_admin_settings() = settings form * ad duration * default * per-ad_term override * grace period from expiration to purge * expiration notification * activation * pre-expiration period * message subject/body, with tokens * max body length * ad site contact link on posts: useless * In lists, show ad teaser OR body * rename field attachments: useless * New: activate modr8 on updates * admin/ed-classified/purge: _ed_classified_user_purge() = scheduled expiration: separated purge / expiration / notification * classified/scheduled/purge: purge expired node beyond the grace period * classified/scheduled/expire: unpublish nodes past their expiration date * classified/scheduled/notify/[half-life|pre-expire|pre-purge]: notify pre-expiration/purge * cron.php: * expire ads * purge expired ads * send pre-expiration mails * send expiration mails ==== New: Drush commands ==== * OK classified-purge / cl-p: trigger a purge * OK classified-expire / cl-e: trigger expiration * classified-notify [half-life|pre-expire|pre-purge] / cl-n (same): trigger notifications ===== OK Blocks ===== * popular: ed_classified_get_popular_ads_list() * latest: ed_classified_get_latest_ads_list() * statistics: ed_classified_get_ad_stats() ===== OK Alterations ===== * HFA classified node form: rename uploads as images.: doesn't seem worth keeping, imagefield/emfield is better * HF classified node form: * add JS ad size checker/blocker: non-jQuery => Reimplemented on jQuery * add hidden field to keep expire date: can be overriden in the browser, inserted in the submit handler instead * Add checkbox if user permissions allow it to reset expiration. Ignores administer ads: should be honored. Redone differently, with 3 update modes. * submit handler does validation job on expiration reset: moved to validation handler instead * classified node links: * HL add link to ad author page: redundant with author info on node * HL add link to ''contact'' : titled as a way to suggest new categories, duplicates the normal contact link * HLA replace ''taxonomy/term/'' links with ''ed_classified/'' when belongs in the module vocabulary, in order to have a specific page take over instead of the default taxonomy term page for these. Done with hook_term_path() instead, for more generality. * HV build breadcrumbs trail ==== New: jQuery ==== * jQuery for textarea content * jQuery to hide date selection unles forced expiration update is selected ===== OK Security ===== ==== Permissions ==== * 'create classified ads' * 'edit own classified ads' * 'reset classified ad expiration' * 'administer classified ads' * Missing, to match node.module * "edit any classified ad" * "delete any classified ad" * "delete own classified ad" Note that "administer" right should include "reset expiration" and all the other rights. ==== Access ==== * hook_access as a simple check on perms vs uid * administer classified ads does not grant read/update/delete rights on ads: contrary to standard Drupal practice ===== OK Views 2 integration ===== * default Views: 2 created, then replaced by custom code. Still in the repository, but nothing specific to learn from them. * 1 "time remaining" data definition, for field, argument, filter and sort, defining 2 distinct fields (date or duration) * add 1 field handler definition for purge date ==== Future features ==== * add "remaining" format to both fields * create a better display plugin, or style the existing one better ===== New features ===== * OK Active modr8 integration: resend updated nodes to moderation * -1 on grace means never delete * 0 on grace means delete upon expire ===== Themeing ===== * OK 'ed_classified_body' => array('arguments' => array('node')),: unneeded, use theme(node) * OK 'ed_classified_teaser' => array('arguments' => array('node')),: unneeded, use theme(node) * OK 'ed_classified_ending_date' => array('arguments' => array('ad_expiration_date')), => classified_expires($node) * 'ed_classified_ads_block' => array('arguments' => array('ads', 'display_timestamp' => TRUE, 'display_counter' => FALSE, 'display_ad_category' => FALSE)),: theme_item_list used instead * 'ed_classified_taxonomy' => array('arguments' => array('cats' => NULL, 'ads' => NULL)), * 'ed_classified_adcount' => array('arguments' => array('count' => NULL)), * 'ed_classified_taxonomy_catlist' => array('arguments' => array('cats' => NULL)), * 'ed_classified_category_list_row' => array('arguments' => array('cat' => NULL, 'row_count' => NULL)), * 'ed_classified_taxonomy_ads' => array('arguments' => array('ads' => NULL)), * 'ed_classified_category_list_ad_row' => array('arguments' => array('ad' => NULL, 'rowcount' => NULL)), * 'ed_classified_category_name' => array('arguments' => array('cat' => NULL)), * 'ed_classified_category_description' => array('arguments' => array('cat' => NULL)), * 'ed_classified_ads_stats' => array(): theme_table used instead All currently as themeable functions, redo as templates ==== New ==== * A "ad list" CCK build mode, used by lists generated by the module * Lifetimes in settings form formatted as a table