Newsgroup: it.comp.www.php
Titolo: Framework PHP

Ciao a tutti,
riprendo il discorso fatto diversi giorni fa in quanto l'ho letto solo 
recentemente e non ho potuto dare il mio contributo.
Sono alla ricerca di un ambiente in php4 sulla quale basare progetti 
futuri di piccole/medie dimensioni.
Il supporto ai css e codice validato sono requisiti minimi.
Mi piacerebbe che avesse un engine template, Smarty sarebbe interessante.
Ho provato anche a verificare qualche CMS, ma spesso non hanno delle API 
con la quale sviluppare in modo fluido.
Ho avuto un'esperienza con Xoops, ma non sono soddisfatto al 100%.
Ho approcciato Drupal, ma ho dei dubbi sulla gestione dei "nodi", non mi 
piace come vengono *indirizzati* i contenuti (
www.miosito.it/?q=node/759
)
Ho verificato al volo e senza approfondire Seagull, che sulla carta 
sembra interessante, ma forse un poco giovane come progetto.
Avete altre alternative da valutare? In caso di progetti con 
amministrazione di contenuti da parte del cliente o di più utenti, su 
cosa basare i vostri progetti?
Tutto questo ovviamente IMO e con rispetto di tutti i progetti menzionati.
Grazie
Paolo

 cosa basare i vostri progetti?
io ho sviluppato un framework da me... molto meno completo dei cms che 
trovi in giro ma che ha le caratteristiche che volevo
il mio consiglio è quello di modificare qualcosa di esistente o di fare 
da zero... all'inizio è un gran lavoro ma in futuro risparmierai un 
sacco di tempo

 piace come vengono *indirizzati* i contenuti (
www.miosito.it/?q=node/759
)
Faccio questo appunto a titolo di chiarezza e senza polemica :-) e chiudo...
Infatti non usi i nodi ma solo le api sulle tue tabelle, che nulla hanno
a che vedere con i nodi. Un record in una tua tabella diventa una cosa
COMPLETAMENTE svincolata dal nodo e l'inserimento di un record NON
comporta l'inserimento di un nodo.
Il tipo di url presentato dipende dipende da apache e da drupal stesso,
quindi può essere: 
www.miosito.it/?q=cliente/inserisci
 come
www.miosito.it/cliente/inserisci
per farti un idea di come funziona drupal framework (progetto in fase di
lavorazione quindi con diversi errori):
www.computerando.it
login: demo
password: demo
Esempio di gestione ricambi auto visibile all'url sopra (inserimento,
ricerca, modifica, cancellazione con due combo di tabelle collegate....
comprensivo di menu, gestione dei permessi, help per la descrizione del
modulo per l'amministratore, pager per "spezzare" i risultati delle
ricerche, verifica dati nel form, evidenziatura dati form errati,
restituzione messaggi di errore, temizzazione completa, assegnazione di
id univoci per ogni tag dei form, query parametrizzate "anti query
insertion").... il codice (necessita qualche ritocchino ma è
funzionante) è tutto quì:
<?php
/* ---------------------------------------------------------------------
*         MODULO PER LA GESTIONE DEI ARTICOLI (RICAMBI)
*						
*               	   Licenza Modulo GPL
* ---------------------------------------------------------------------- */
/*
----------------- FUNZIONI DI BASE PER IL MODULO -----------------------
*/
function articolo_help($section='') {
$output = '';
switch ($section) {
	case "admin/modules#description":
	$output = t("Amministrazione (inserimento/ricerca/modifica) degli
ARTICOLI (RICAMBI)");
	break;
	}
return $output;
} // function onthisdate_help
// Determiniamo gli accessi al modulo (dando poi i giusti permessi
nell'amministrazione)
function articolo_perm() {
return array('access content', 'access articolo', 'administer articolo');
}
// Collega la funzione sopra all' url 
http://localhost/drupal/articolo
function articolo_menu() {
	$items = array();
 
	// Principale (operazioni principali)
	$items[] = array(
			'path' => 'articolo',
			'title' => t('Articoli/Ricambi'),
			'callback' => 'articolo_inserisci',
			'access' => user_access('access articolo'),
			'type' => MENU_NORMAL_ITEM );
 
	// Inserimento
	$items[] = array(
			'path' => 'articolo/inserisci',
			'title' => t('Inserimento'),
			'callback' => 'articolo_inserisci',
			'access' => user_access('access articolo'),
			'type' => MENU_NORMAL_ITEM );
 
	// Ricerca (operazioni di ricerca)
	$items[] = array(
			'path' => 'articolo/ricerca',
			'title' => t('Ricerca'),
			'callback' => 'articolo_ricerca',
			'access' => user_access('access articolo'),
			'type' => MENU_NORMAL_ITEM );
 
	// Modifica (non visibile nei menu)
	$items[] = array(
			'path' => 'articolo/modifica',
			'title' => t('Modifica'),
			'callback' => 'articolo_modifica',
			'access' => user_access('access articolo'),
			'type' => MENU_CALLBACK );
 
	// Cancella (non visibile nei menu)
	$items[] = array(
			'path' => 'articolo/cancella',
			'title' => t('Cancella'),
			'callback' => 'articolo_cancella',
			'access' => user_access('access articolo'),
			'type' => MENU_CALLBACK );
 
	// Inserisci popup (non visibile nei menu)
	$items[] = array(
			'path' => 'articolo/inserisci_popup',
			'title' => t('Inserimento articolo'),
			'callback' => 'articolo_inserisci_popup',
			'access' => user_access('access articolo'),
			'type' => MENU_CALLBACK );	 								
	return $items;
}
/*
--------- FUNZIONI DI MODIFICA articolo -----------
*/
// FUNZIONE ELIMINAZIONE DEL articolo
function articolo_cancella() {
	// Mostra quel articolo
	$result = db_query("
			SELECT
			id,
			name,
			code,
			id_type,
			price_list,
			id_iva,
			price,
			supply,
			quantity,
			um
			FROM {gest_auto_part}
			WHERE
			id = %d
			",
			$_GET['id']
			);
	$field = db_fetch_object($result);
 
	// Mostra il form di cancellazione (conferma). Se non cancelli torna al
form
	// Campo ID (Nascosto) - contiene l'id del record da cancellare	
	$form['id'] = array(
	  '#type' => 'hidden',
	  '#size' => 10,
	  '#maxlength' => 10,
	  '#required' => TRUE,
	  '#value' => $field->id,
	);
	// Campo dati del articolo da cancellare 	
	$form['description'] = array(
	  '#type' => 'hidden',
	  '#size' => 100,
	  '#maxlength' => 100,
	  '#required' => FALSE,
	  '#value' => $field->name.' - Codice:'.$field->code,
	);
 
	$output .= confirm_form(
						'form_cancella_articolo',
						$form,
	                   	t('ATTENZIONE!!! Confermi la cancellazione? '),
	                   	'articolo/inserisci',
						   	'NOME: '.$field->name.' - '.
					   		'CODICE: '.$field->code.' - '
							.'<p></p>',
	                   	t('Delete'),
					   	t('Cancel')							
						);	
 
 
  	// Visualizza la pagina	
  	print theme('page', $output);
}
// ESECUZIONE DOPO AVER VERIFICATO I DATI DEL FORM delete_form
function form_cancella_articolo_submit($form_id, $form_values) {
 
	// Cancella il articolo
	db_query("
			DELETE FROM
			{gest_auto_part}
			WHERE
			id = %d
			",
			$form_values['id']
			);
 
	drupal_set_message(t('Articolo').' '.$form_values['name'].'
'.t('CANCELLATO!!'),'error');
	drupal_goto('articolo/inserisci');	
}
/*
--------- FUNZIONI DI MODIFICA articolo -----------
*/
// FUNZIONE di modifica lanciata da soggett/modifica
function articolo_modifica() {
	// Mostra quel Articolo
	$result = db_query("
			SELECT
			id,
			name,
			code,
			id_type,
			price_list,
			id_iva,	
			price,
			supply,
			quantity,
			um
			FROM {gest_auto_part}
			WHERE
			id = %d
			",
			$_GET['id']
			);
	$field = db_fetch_object($result);
	$value['id'] = $field->id;
	$value['name'] = $field->name;
	$value['code'] = $field->code;
	$value['id_type'] = $field->id_type;
	$value['price_list'] = $field->price_list;
	$value['id_iva'] = $field->id_iva;
	$value['price'] = $field->price;
	$value['supply'] = $field->supply;
	$value['quantity'] = $field->quantity;
	$value['um'] = $field->um;
 
  	// Visualizza la pagina	
  	$output .= form_articolo($value);
  	print theme('page', $output);
}
/*
--------- FUNZIONI PER L'INSERIMENTO DEL articolo -----------
*/
// FUNZIONE PRINCIALE LANCIATA SU 
www.example.com/articolo
function articolo_inserisci() {
 
	// Imposta l'url di invio dati del post
	$value['action'] = 'articolo/inserisci';
 
  	// Visualizza la pagina	
  	$output .= form_articolo($value);
  	print theme('page', $output);
}
// FORM DA MOSTRARE PER INSERIMENTO/MODIFICA
function form_articolo($value = NULL)
{
    // Proprietà del form
    $form['#method'] = 'post';
    $form['#action'] = url($value['action']);
  	// );
	// Campo ID (Nascosto)	
	$form['id'] = array(
	  '#type' => 'hidden',
	  '#size' => 10,
	  '#maxlength' => 10,
	  '#required' => FALSE,
	  '#value' => $value['id'],
	);
	// Campo Codice Articolo	
	$form['code'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Codice'),
	  '#size' => 30,
	  '#maxlength' => 30,
	  '#required' => TRUE,
	  '#default_value' => $value['code'],
	  '#prefix' => '<table><tr><td><table><tr><td>',
  	  '#suffix' => '</td>',
	);	
	// Lista Tipologie
	$result = db_query('SELECT
						id,
						name
						FROM
						{gest_type_auto_part}
						ORDER BY
						name
						');
	unset($markarray);
	while ($field = db_fetch_object($result)) {
		$markarray [$field->id] = $field->name;
	}
	// if (unset($markarray)) $markarray = '';
 
	// Campo Tipologia	
	$form['id_type'] = array(
	  '#type' => 'select',
	  '#title' => t('Tipologia'),
	  '#options' => $markarray,	
	  '#default_value' => $value['id_type'],
	  '#prefix' => '<td>',
  	  '#suffix' => '</td></tr></table></tr>',
	);
	// Campo nome	
	$form['name'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Nome'),
	  '#size' => 50,
	  '#maxlength' => 50,
	  '#required' => TRUE,
	  '#default_value' => $value['name'],
	  '#prefix' => '<tr><td>',
  	  '#suffix' => '</td></tr>',
	);	
	// Unità di Misura
	$form['um'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Unit&agrave di Misura'),
	  '#size' => 30,
	  '#maxlength' => 30,
	  '#required' => FALSE,
	  '#default_value' => $value['um'],
	  '#prefix' => '<td><tr><table><tr><td>',
  	  '#suffix' => '</td>',
	);
	// Campo quantità
	$form['quantity'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Quantit&agrave;'),
	  '#size' => 11,
	  '#maxlength' => 11,
	  '#required' => FALSE,	
	  '#default_value' => $value['quantity'],
	  '#prefix' => '<td>',
  	  '#suffix' => '</td>',
	);
 
	// Campo supplye sotto scorta
	$form['supply'] = array(
	  '#type' => 'textfield',
	  '#title' => t('supplye Scorta'),
	  '#size' => 11,
	  '#maxlength' => 11,
	  '#required' => TRUE,
	  '#default_value' => $value['supply'],
	  '#prefix' => '<td>',
  	  '#suffix' => '</td></tr></table></td></tr>',
	);
	// Campo Prezzo Listino
	$form['price_list'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Listino'),
	  '#size' => 11,
	  '#maxlength' => 11,
	  '#required' => TRUE,	
	  '#default_value' => $value['price_list'],
	  '#prefix' => '<tr><td><table><tr><td>',
  	  '#suffix' => '</td>',
	);
 
	// Campo Prezzo Al Pubblico
	$form['price'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Prezzo'),
	  '#size' => 11,
	  '#maxlength' => 11,
	  '#required' => TRUE,
	  '#default_value' => $value['price'],
	  '#prefix' => '<td>',
  	  '#suffix' => '</td>',
	);
	// Aliquote IVA
	$result = db_query('SELECT
						id,
						name
						FROM
						{gest_tax}
						ORDER BY
						name
						');
	unset($markarray);
	while ($field = db_fetch_object($result)) {
		$markarray [$field->id] = $field->name;
	}
	// Campo Codice Iva
	$form['id_iva'] = array(
	  '#type' => 'select',
	  '#title' => t('IVA'),
	  '#options' => $markarray,	
	  '#default_value' => $value['id_iva'],
	  '#prefix' => '<td>',
  	  '#suffix' => '</td></tr></table></td></tr></table>',	
	);
  // pulsante conferma
  $form['submit'] = array('#type' => 'submit', '#value' => t('confirm'));
  // price_listvede a controllare il form completando eventuali valori
omessi, costruisce e stampa il form
  $output = drupal_get_form('form_articolo', $form);
  return $output;
}
// VALIDAZIONE DEI DATI IMMESSI NEL FORM CLIENTI
function form_articolo_validate($form_id, $form_values) {
 
	// Imposta l'array dei dati
    $errors = array();
 
	// Verifica che siano inseriti i dati essenziali (NOT NULL)
    if ($form_values['name'] == '') {
   	  $errors['name'] = t('Inserire il Nome dell\'Articolo');
    }
    if ($form_values['code'] == '') {
   	  $errors['code'] = t('Inserire il Codice');
    }
    if ($form_values['supply'] == '') {
   	  $errors['supply'] = t('Inserire il supplye Minimo');
    }
    if ($form_values['quantity'] == '') {
   	  $errors['quantity'] = t('Inserire la quantità presente');
    }
	// Imposta l'array degli errori trovati	
    foreach ($errors as $name => $message) {    	
      form_set_error($name, $message);
    }
    // Ritorna il numero degli errori trovati
    return count($errors) == 0;
 
}
// ESECUZIONE DOPO AVER VERIFICATO I DATI DEL FORM
function form_articolo_submit($form_id, $form_values) {
	// Se è impostato l'id modifica, altrimenti inserisci
	if (!$form_values['id']) {
 
		// Recupera l'ultimo id inserito
		$um = db_next_id('gest_auto_part_id');		
 
		// inserisci
		db_query("INSERT INTO {gest_auto_part}
				(
				id,
				name,
				code,
				id_type,
				price_list,
				id_iva,	
				price,
				supply,
				quantity,
				um
				) VALUES (
				%d, '%s', '%s', %d, %f, %d, %f, %f, %f, '%s'
				)",
				$um,
				$form_values['name'],
				$form_values['code'],
				$form_values['id_type'],
				$form_values['price_list'],
				$form_values['id_iva'],		
				$form_values['price'],
				$form_values['supply'],
				$form_values['quantity'],
				$form_values['um']
				);
		// Imposta il messaggio di avvenuto inserimento
		drupal_set_message(t('Articolo').' '.$form_values['name'].'
'.t('Inserito'));		
 
	}
	else
		{
		//aggiorna
		printf("UPDATE {gest_auto_part} SET 	
				name = '%s',
				code = '%s',
				id_type = %d,
				price_list = %f,
				id_iva = %d,	
				price = %f,
				supply = %f,
				quantity = %f,
				um = '%s'
				WHERE
				id = %d
				",
				$form_values['name'],
				$form_values['code'],
				$form_values['id_type'],
				$form_values['price_list'],
				$form_values['id_iva'],				
				$form_values['price'],
				$form_values['supply'],
				$form_values['quantity'],
				$form_values['um'],
				$form_values['id']
				);		
 
		db_query("UPDATE {gest_auto_part} SET 	
				name = '%s',
				code = '%s',
				id_type = %d,
				price_list = %f,
				id_iva = %d,	
				price = %f,
				supply = %f,
				quantity = %f,
				um = '%s'
				WHERE
				id = %d
				",
				$form_values['name'],
				$form_values['code'],
				$form_values['id_type'],
				$form_values['price_list'],
				$form_values['id_iva'],				
				$form_values['price'],
				$form_values['supply'],
				$form_values['quantity'],
				$form_values['um'],
				$form_values['id']
				);
		drupal_set_message(t('Articolo').' '.$form_values['name'].'
'.t('Aggiornato'));	
 
		}
		// Mostra form vuoto
		// drupal_goto($form_values['action']);
 
}
/*
---------------- FUNZIONI DI RICERCA
---------------------------------------
*/
/*
* Funzione lanciata dall' url 
http://localhost/articolo/ricerca
*/
function articolo_ricerca() {
	// RECUPERA L'array dei valori
	$form_values = $_POST[edit];
 
	// Costruisci la condizione
    $condition = '';
    if ($form_values['name']) {
		if ($condition == '') $condition = ' name like
\'%'.$form_values['name'].'%\'';
						else  $condition .= ' AND name like \'%'.$form_values['name'].'%\'';
		}
    if ($form_values['code']) {
		if ($condition == '') $condition = ' code like
\'%'.$form_values['code'].'%\'';
						else  $condition .= ' AND code like \'%'.$form_values['code'].'%\'';
		}
	// Aggiunge l'eventuale where
	if ($condition != '') $condition = ' WHERE '.$condition;
 
	// Costruisci i titoli da mostrare
	$header = array(
	   array('data' => t('Articolo'), 'field' => 'name', 'sort' => 'desc'),
	   array('data' => t('Codice'), 'field' => 'code'),
	   array('data' => t('Prezzo'), 'field' => 'price'),
	   array('data' => t('Quantita\''), 'field' => 'quantity'),
	   t('Mostra'),
	   t('Elimina'),	
	);	
 
	// Costruisci la query
	$sql = 'SELECT
			id,
			name,
			code,
			price,
			quantity
			FROM {gest_auto_part}
			'.$condition.tablesort_sql($header); 	
	// Applica la query (paginata)
	$result = pager_query($sql, 50);
 
	while ($account = db_fetch_object($result)) {
	  $rows[] = array(
	                  $account->name,
	                  $account->code,
	                  $account->price,
	                  $account->quantity,
	                  l(t('Dettaglio'), "/articolo/modifica/", NULL ,
'&op=view&id='.$account->id),
	                  l(t('Cancella'), "/articolo/cancella/", NULL ,
'&id='.$account->id),
					  );
	}
 
	// Mostra il form di ricerca
    $output .= form_ricerca_articolo();
 
	// Temizzazione della tabella e titoli
	$output .= theme('table', $header, $rows);
	// Temizzazione della pagina
	$output .= theme('pager', NULL, 10, 0, tablesort_pager());	
	print theme('page', $output);
 
}
/*
* Function search subject
*
*/
function form_ricerca_articolo()
{
    // Proprietà del form
    $form['#method'] = 'post';
    $form['#action'] = url('articolo/ricerca');
  	// );
	// Campo Nome/Ragione Sociale	
	$form['name'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Nome'),
	  '#size' => 50,
	  '#maxlength' => 50,
	  '#prefix' => '<table><tr><td colspan=2>',
  	  '#suffix' => '</td>',
	);	
	// Campo Partita Iva
	$form['code'] = array(
	  '#type' => 'textfield',
	  '#title' => t('Codice'),
	  '#size' => 16,
	  '#maxlength' => 16,
	  '#prefix' => '<td>',
  	  '#suffix' => '</td></tr></table>',
	);
 
	// Pulsante Ricerca
  	$form['search'] = array('#type' => 'submit', '#value' => t('search'));
 
	// Pulsante Stampa
  	$form['print'] = array('#type' => 'submit', '#value' => t('print'));  	
  	// price_listvede a controllare il form completando eventuali valori
omessi, costruisce e stampa il form
  	$output = drupal_get_form('form_ricerca_articolo', $form);
  	return $output;
}				 		
?>

 
www.miosito.it/cliente/inserisci
Grazie Gianni per la precisazione,
ribadisco che Drupal l'ho solo intravisto, che mi sembra abbia 
buonissime potenzialità, ma che mi lasciava perpresso per questo aspetto.
Quindi mi vuoi dire che il codice che mi hai inviato gestisce tutto 
l'esempio che si trova nel sito?! Interessante.
Le API sono ben documentate se non sbaglio e come template si può 
utilizzare Smarty, giusto?!
Ti ringrazio per l'esempio e la spiegazione.
Paolo

 sacco di tempo
Anche questa è una strada, senza dubbio l'ambiente che si verrebbe a 
creare sarebbe proprio quello di cui uno ha bisogno, ma il dubbio è da 
cosa partire, senza riscoprire l'acqua calda.
Tu cosa hai utilizzato come base?
Grazie per la risposta
Paolo

 Ti ringrazio per l'esempio e la spiegazione.
Niente
Ciao
Gianni

 Tu cosa hai utilizzato come base?
il mio pc ;)

 No, quello postato è il solo modulo che gestisce SOLO i ricambi auto :-)
Si, il codice che hai postato era semplicemente un modulo, che va 
inserito nel core di drupal, questo lo avevo capito.
Bene, bene mi sa che prossimamente ti disturbo ancora sul forum di Drupal.
Grazie ancora

 il mio pc ;)
LOL
:-)
Poi ? e non mi dire notepad.. dai.. :-)

 Bene, bene mi sa che prossimamente ti disturbo ancora sul forum di Drupal.
Oddio, se intendi il forum ufficiale di drupal.org.... non ti assicuro
di darti risposte perchè il mio inglese è maccheronico: capisco ciò che
leggo ma la grammatica inglese non è il mio forte e quindi scrivo da far
schifo... quindi evito di scriverci (salvo rarissime occasioni) e mi
limito a leggere :-)
Se intendi DrupalItalia,org, più che volentieri visto che si parla in
italiano :-)
Ciao
Gianni

 Poi ? e non mi dire notepad.. dai.. :-)
no texpad :)
sul serio... riga dopo riga mi sono fatto un cms che mi soddisfa...
alla fine con un po' di funzioni faccio diverse cosine ;)
-- 
http://josh.pixael.com

 alla fine con un po' di funzioni faccio diverse cosine ;)
Ok,
Grazie per l'intervento.
Paolo