Entity case study

1 contenuto / 0 new
Entity case study
AllegatoDimensione
Package icon usato.zip3.42 KB

Ciao ragazzi,
sto smanettando da qualche giorno con le entities di drupal 7 e vorrei condividere con voi lo sviluppo di un modulo così da lasciare anche uno strumento ai postumi vista la mancanza in tutorial in italiano.

Ho letto più di qualche tutorial su come etendere il modulo Entity API al fine di creare una nuova entity.

Partendo da quest' ultimo ho provato a sviluppare un piccolo modulo chiamato "usato" per gestire veicoli usati.
Lo scopo è quello di creare una entity (finita, senza sottotipi) che invece di chiamarsi Lawmakers, come nell'esempio citato è appunto "usato" alla quale è associata una piccola tabella del DB con i seguenti campi: usato_id | marca | modello | created

Quello che non riesco a fare è organizzare il codice in modo da semplificarco al massimo per poter ottenere un semplice CRUD che puntino a questi url:

  • /admin/content/usato | Pagina di amministrazione dell'usato simile a quella di default admin/content/comment o quella admin/content/lawmakers dell'esempio
  • /usato | Pagina con la lista dell'usato visualizzabile da tutti (magari da gestire col modulo views).
  • /usato/1 | come node/1 visualizza la pagina relativa al singolo record
  • /usato/1/edit | pagina col form di modifica del record
  • /usato/1/delete | pagina con richiesta di conferma per eliminare il record

Quello che finora ho realizzato, snellendo il modulo Lawmakers dell'esempio è stato questo:

usato.info

name = Usato
description = "Gestisce le entity Usato"
core = 7.x
package = Altro
dependencies[] = entity

usato.module

// 50 items per page.
define('TOTAL_ITEMS_PER_PAGE', 50);
// Admin uri links.
define('ADMIN_CONTENT_USATO_MANAGE_URI', 'admin/content/usato/manage/');
define('ADMIN_CONTENT_USATO_URI', 'admin/content/usato');
/**
* Implements hook_entity_info().
*/
function usato_entity_info() {
  $entity_info['usato'] = array(
    'label' => t('Usato'),
    'label callback' => 'usato_label_callback',
    'entity class' => 'Usato',
    'controller class' => 'UsatoController',
    'base table' => 'usato',
    'uri callback' => 'usato_uri',
    'fieldable' => TRUE,
    'entity keys' => array(
      'id' => 'usato_id',
    ),
    'static cache' => TRUE,
    'admin ui' => array(
      'path' => 'admin/content/usato',
      'controller class' => 'UsatoUIController',
    ),
    'module' => 'usato',
    'access callback' => 'usato_access_callback',
    'bundles' => array(
      'usato' => array(
        'label' => 'Usato',
        'admin' => array(
          'path' => 'admin/structure/usato/manage',
          'access arguments' => array('administer usato'),
        ),
      ),
    ),
    'views controller class' => 'EntityDefaultViewsController',
  );
  return $entity_info;
}
/**
* Implements hook_menu().
*/
function usato_menu() {
  $items = array();
  $items['usato/%usato'] = array(
    'title' => 'Usato',
    'page callback' => 'usato_view_entity',
    'page arguments' => array(1),
    'access callback' => 'usato_access_menu_callback',
    'access arguments' => array('view', 1),
  );
  return $items;
}
/**
* Implements hook_permission().
*/
function usato_permission() {
  return array(
    'administer usato entities' => array(
      'title' => t('Administer Usato Entities'),
      'description' => t('Allows a user to administer usato entities'),
    ),
    'view usato entities' => array(
      'title' => t('View Usato Entity'),
      'description' => t('Allows a user to view the usato entities.'),
    ),
    'create usato entities' => array(
      'title' => t('Create Usato Entities'),
      'description' => t('Allows a user to create usato entities.'),
    ),
    'edit usato entities' => array(
      'title' => t('Edit Usato Entities'),
      'description' => t('Allows a user to edit usato entities.'),
    ),
    'delete usato entities' => array(
      'title' => t('Delete Usato Entities'),
      'description' => t('Allows a user to delete usato entities.'),
    ),
  );
}
/**
* Check access permission for Usato Entity UI.
*/
function usato_access_menu_callback($op, $usato = NULL, $account = NULL) {
  switch ($op) {
    case 'view':
      return user_access('view usato entities', $account);
    case 'create':
      return user_access('create usato entities', $account);
    case 'update':
      return user_access('edit usato entities', $account);
    case 'delete':
      return user_access('delete usato entities', $account);
  }
  return FALSE;
}
/**
* Usato access callback.
*/
function usato_access_callback() {
  if (user_is_anonymous() && !user_access('administer usato entities')) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}
/**
* Implements hook_theme().
*/
function usato_theme() {
  return array(
    'usato_full' => array(
      'variables' => array('usato' => NULL),
      'file' => 'usato.theme.inc',
    ),
  );
}
/**
* Helper function for custom queries.
*/
function usato_entity_query($conditions = array()) {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'usato');
  // Apply conditions.
  foreach ($conditions as $key => $value) {
    $query->propertyCondition($key, $value);
  }
  $result = $query->execute();
  if (isset($result['usato'])) {
    $usato = array_keys($result['usato']);
  }
  else {
    $usato = array();
  }
  return $usato;
}
/**
* Label callback for usato entities, for menu router, etc.
*/
function usato_label_callback($usato, $type) {
  return empty($usato->marca) ? 'Untitled Usato' : $usato->marca;
}
/**
* Saves Usato to database.
*/
function usato_save(usato $usato) {
  return $usato->save();
}
/**
* View for /usato/<usato_id> page.
*/
function usato_view_entity($usato) {
  drupal_set_title($usato->marca);
  // Path not entity.
  $usato_output = theme('usato_full', array('usato' => $usato));
  return $usato_output;
}
/**
* Usato custom entity class.
*/
class Usato extends Entity {
  /**
   * Override defaultUri().
   */
  protected function defaultUri() {
    return array('path' => 'usato/' . $this->identifier());
  }
}
/**
* Menu autoloader for /usato.
*/
function usato_load($usato_id, $reset = FALSE) {
  $usato = usato_load_multiple(array($usato_id), array(), $reset);
  return reset($usato);
}
/**
* Load multiple usato based on certain conditions.
*/
function usato_load_multiple($usato_ids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('usato', $usato_ids, $conditions, $reset);
}
/**
* Deletes a usato.
*/
function usato_delete(usato $usato) {
  $usato->delete();
}
/**
* Delete multiple usato.
*/
function usato_delete_multiple(array $usato_ids) {
  entity_get_controller('usato')->delete($usato_ids);
}
/**
* Custom controller for the usato entity.
*/
class UsatoController extends EntityAPIController {
  /**
   * Override the save method.
   */
  public function save($entity, DatabaseTransaction $transaction = NULL) {
    if (isset($entity->is_new)) {
      $entity->created = REQUEST_TIME;
    }
    return parent::save($entity, $transaction);
  }
}
/**
* Custom controller for the administrator UI.
*/
class UsatoUIController extends EntityDefaultUIController {
  /**
   * Override the menu hook for default ui controller.
   */
  public function hook_menu() {
    $items = parent::hook_menu();
    $items[$this->path]['title'] = t('Usato');
    $items[$this->path]['description'] = t('Manage usato, including fields.');
    $items[$this->path]['access callback'] = 'usato_access_callback';
    $items[$this->path]['access arguments'] = array('administer usato entities');
    $items[$this->path]['type'] = MENU_LOCAL_TASK;
    return $items;
  }
}
function usato_form($form, &$form_state, $usato = NULL) {
  $form = array();
  $form['marca'] = array(
    '#title' => t('Marca'),
    '#type' => 'textfield',
    '#default_value' => isset($usato->marca) ? $usato->marca : '',
    '#maxlength' => 255,
  );
  $form['modello'] = array(
    '#title' => t('Modello'),
    '#type' => 'textfield',
    '#default_value' => isset($usato->modello) ? $usato->modello : '',
    '#maxlength' => 255,
  );
  field_attach_form('usato', $usato, $form, $form_state);
  $form['actions'] = array(
    '#type' => 'actions',
    'submit' => array(
      '#type' => 'submit',
      '#value' => isset($usato->usato_id) ? t('Update Usato') : t('Save Usato'),
    ),
    'delete_link' => array(
      '#markup' => isset($usato->usato_id) ? l(t('Delete'), 'admin/content/usato/manage/' . $usato->usato_id . '/delete', array('attributes' => array('id' => array('usato-delete-' . $usato->usato_id), 'class' => array('button remove')), 'query' => array('destination' => 'admin/content/usato'))) : ''));
  return $form;
}
/**
* Implements hook_form_validate().
*/
function usato_form_validate($form, &$form_state) {
}
/**
* Implements hook_form_submit().
*/
function usato_form_submit($form, &$form_state) {
  $usato = entity_ui_form_submit_build_entity($form, $form_state);
  $usato->save();
  drupal_set_message(t('Record saved!'));
  $form_state['redirect'] = 'usato/' . $usato->usato_id;
}


/**
* Implements hook_schema().
*/
function usato_schema() {
  $schema = array();
  $schema['usato'] = array(
      'fields' => array(
      'usato_id' => array(
        'description' => 'Primary Key: Identifier for a usato.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'marca' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'modello' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the model was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array('usato_id'),
  );
  return $schema;
}

usato.theme.inc

/**
* Theme usato full page.
*/
function theme_usato_full($variables) {
  $output = '<div class="usato-dif">';
  if (!empty($usato->marca)) {
    $output .= '<div class="marca"> ' . $usato->marca . '</div>';
  }
  $output .= '</div>';
  return $output;
}

ho allegato il modulo che potete provare... purtroppo non capisco come snellire il codice e riorganizzare le uri come indicato sopra...

Drupal Version: