Added description field to items

A description field has been added to items in the database, form fields
have been added to both item creation and modification. Removed some
French text that was still around.
This commit is contained in:
Emmanuel BENOîT 2012-02-05 23:04:41 +01:00
parent 55438e6661
commit b6b5cd982e
8 changed files with 102 additions and 41 deletions

2
arse

@ -1 +1 @@
Subproject commit b80ac7ee91df3c6aa935e38515907c6f3a0ab63c Subproject commit f80d739f5d7b6241c154e2e38e0b1d5b6325142b

View file

@ -30,9 +30,10 @@ GRANT SELECT,UPDATE ON task_dependencies_taskdep_id_seq TO :webapp_user;
-- Table items -- Table items
CREATE TABLE items ( CREATE TABLE items (
item_id INT NOT NULL DEFAULT NEXTVAL('items_item_id_seq'::TEXT), item_id INT NOT NULL DEFAULT NEXTVAL('items_item_id_seq'::TEXT),
item_name VARCHAR(128) NOT NULL, item_name VARCHAR(128) NOT NULL,
item_id_parent INT, item_id_parent INT,
item_ordering INT NOT NULL, item_ordering INT NOT NULL,
item_description TEXT ,
PRIMARY KEY(item_id) PRIMARY KEY(item_id)
); );

View file

@ -50,7 +50,7 @@ $$ LANGUAGE plpgsql;
-- Insert a item before another -- Insert a item before another
CREATE OR REPLACE FUNCTION insert_item_before( i_name TEXT , i_before INT ) CREATE OR REPLACE FUNCTION insert_item_before( i_name TEXT , i_before INT , i_description TEXT )
RETURNS INT RETURNS INT
STRICT VOLATILE STRICT VOLATILE
SECURITY DEFINER SECURITY DEFINER
@ -68,9 +68,13 @@ BEGIN
RETURN 2; RETURN 2;
END IF; END IF;
IF i_description = '' THEN
i_description := NULL;
END IF;
BEGIN BEGIN
INSERT INTO items ( item_name , item_id_parent , item_ordering ) INSERT INTO items ( item_name , item_id_parent , item_ordering , item_description )
VALUES ( i_name , i_parent , i_ordering ); VALUES ( i_name , i_parent , i_ordering , i_description );
EXCEPTION EXCEPTION
WHEN unique_violation THEN WHEN unique_violation THEN
RETURN 1; RETURN 1;
@ -80,9 +84,12 @@ BEGIN
END; END;
$insert_item_before$ LANGUAGE plpgsql; $insert_item_before$ LANGUAGE plpgsql;
REVOKE EXECUTE ON FUNCTION insert_item_before( TEXT , INT , TEXT ) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION insert_item_before( TEXT , INT , TEXT ) TO :webapp_user;
-- Insert item as the last child of another -- Insert item as the last child of another
CREATE OR REPLACE FUNCTION insert_item_under( i_name TEXT , i_parent INT ) CREATE OR REPLACE FUNCTION insert_item_under( i_name TEXT , i_parent INT , i_description TEXT )
RETURNS INT RETURNS INT
STRICT VOLATILE STRICT VOLATILE
SECURITY DEFINER SECURITY DEFINER
@ -92,10 +99,14 @@ DECLARE
BEGIN BEGIN
PERFORM 1 FROM items FOR UPDATE; PERFORM 1 FROM items FOR UPDATE;
IF i_description = '' THEN
i_description := NULL;
END IF;
SELECT INTO i_ordering max( item_ordering ) + 1 FROM items; SELECT INTO i_ordering max( item_ordering ) + 1 FROM items;
BEGIN BEGIN
INSERT INTO items ( item_name , item_id_parent , item_ordering ) INSERT INTO items ( item_name , item_id_parent , item_ordering , item_description )
VALUES ( i_name , i_parent , i_ordering ); VALUES ( i_name , i_parent , i_ordering , i_description );
EXCEPTION EXCEPTION
WHEN unique_violation THEN WHEN unique_violation THEN
RETURN 1; RETURN 1;
@ -107,9 +118,12 @@ BEGIN
END; END;
$insert_item_under$ LANGUAGE plpgsql; $insert_item_under$ LANGUAGE plpgsql;
REVOKE EXECUTE ON FUNCTION insert_item_under( TEXT , INT , TEXT ) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION insert_item_under( TEXT , INT , TEXT ) TO :webapp_user;
-- Add a item as the last root element -- Add a item as the last root element
CREATE OR REPLACE FUNCTION insert_item_last( i_name TEXT ) CREATE OR REPLACE FUNCTION insert_item_last( i_name TEXT , i_description TEXT )
RETURNS INT RETURNS INT
STRICT VOLATILE STRICT VOLATILE
SECURITY DEFINER SECURITY DEFINER
@ -123,9 +137,14 @@ BEGIN
IF i_ordering IS NULL THEN IF i_ordering IS NULL THEN
i_ordering := 0; i_ordering := 0;
END IF; END IF;
IF i_description = '' THEN
i_description := NULL;
END IF;
BEGIN BEGIN
INSERT INTO items ( item_name , item_ordering ) INSERT INTO items ( item_name , item_ordering , item_description )
VALUES ( i_name , i_ordering ); VALUES ( i_name , i_ordering , i_description );
EXCEPTION EXCEPTION
WHEN unique_violation THEN WHEN unique_violation THEN
RETURN 1; RETURN 1;
@ -135,21 +154,34 @@ BEGIN
END; END;
$insert_item_last$ LANGUAGE plpgsql; $insert_item_last$ LANGUAGE plpgsql;
REVOKE EXECUTE ON FUNCTION insert_item_last( TEXT , TEXT ) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION insert_item_last( TEXT , TEXT ) TO :webapp_user;
-- Rename a item -- Rename a item
CREATE OR REPLACE FUNCTION rename_item( i_id INT , i_name TEXT ) CREATE OR REPLACE FUNCTION update_item( i_id INT , i_name TEXT , i_description TEXT )
RETURNS INT RETURNS INT
STRICT VOLATILE STRICT VOLATILE
SECURITY DEFINER SECURITY DEFINER
AS $rename_item$ AS $update_item$
BEGIN BEGIN
UPDATE items SET item_name = $2 WHERE item_id = $1; IF i_description = '' THEN
i_description := NULL;
END IF;
UPDATE items
SET item_name = i_name ,
item_description = i_description
WHERE item_id = i_id;
RETURN 0; RETURN 0;
EXCEPTION EXCEPTION
WHEN unique_violation THEN WHEN unique_violation THEN
RETURN 1; RETURN 1;
END END
$rename_item$ LANGUAGE plpgsql; $update_item$ LANGUAGE plpgsql;
REVOKE EXECUTE ON FUNCTION update_item( INT , TEXT , TEXT ) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION update_item( INT , TEXT , TEXT ) TO :webapp_user;

View file

@ -10,26 +10,26 @@ class DAO_Items
private $activeTasksCounted = false; private $activeTasksCounted = false;
public function createBefore( $name , $before ) public function createBefore( $name , $before , $description = '' )
{ {
$query = $this->query( 'SELECT insert_item_before( $1 , $2 ) AS error' ); $query = $this->query( 'SELECT insert_item_before( $1 , $2 , $3 ) AS error' );
$result = $query->execute( $name , $before ); $result = $query->execute( $name , $before , $description );
return $result[ 0 ]->error; return $result[ 0 ]->error;
} }
public function createUnder( $name , $under ) public function createUnder( $name , $under , $description = '' )
{ {
$query = $this->query( 'SELECT insert_item_under( $1 , $2 ) AS error' ); $query = $this->query( 'SELECT insert_item_under( $1 , $2 , $3 ) AS error' );
$result = $query->execute( $name , $under ); $result = $query->execute( $name , $under , $description );
return $result[ 0 ]->error; return $result[ 0 ]->error;
} }
public function createLast( $name ) public function createLast( $name , $description = '' )
{ {
$query = $this->query( 'SELECT insert_item_last( $1 ) AS error' ); $query = $this->query( 'SELECT insert_item_last( $1 , $2 ) AS error' );
$result = $query->execute( $name ); $result = $query->execute( $name , $description );
return $result[ 0 ]->error; return $result[ 0 ]->error;
} }
@ -41,12 +41,13 @@ class DAO_Items
return $this->loaded[ $identifier ]; return $this->loaded[ $identifier ];
} }
$getNameQuery = $this->query( 'SELECT item_name FROM items WHERE item_id = $1' , true ); $getNameQuery = $this->query( 'SELECT item_name , item_description FROM items WHERE item_id = $1' , true );
$result = $getNameQuery->execute( $identifier ); $result = $getNameQuery->execute( $identifier );
if ( empty( $result ) ) { if ( empty( $result ) ) {
$rObj = null; $rObj = null;
} else { } else {
$rObj = new Data_Item( $identifier , $result[ 0 ]->item_name ); $rObj = new Data_Item( $identifier , $result[ 0 ]->item_name );
$rObj->description = $result[ 0 ]->item_description;
} }
$this->loaded[ $identifier ] = $rObj; $this->loaded[ $identifier ] = $rObj;
@ -61,7 +62,7 @@ class DAO_Items
} }
$query = $this->query( $query = $this->query(
'SELECT p.item_id , p.item_name FROM items_tree pt ' 'SELECT p.item_id , p.item_name , p.item_description FROM items_tree pt '
. 'INNER JOIN items p ' . 'INNER JOIN items p '
. 'ON p.item_id = pt.item_id_parent ' . 'ON p.item_id = pt.item_id_parent '
. 'WHERE pt.item_id_child = $1 AND pt.pt_depth > 0 ' . 'WHERE pt.item_id_child = $1 AND pt.pt_depth > 0 '
@ -74,6 +75,7 @@ class DAO_Items
$object = $this->loaded[ $entry->item_id ]; $object = $this->loaded[ $entry->item_id ];
} else { } else {
$object = new Data_Item( $entry->item_id , $entry->item_name ); $object = new Data_Item( $entry->item_id , $entry->item_name );
$object->description = $entry->item_description;
$this->loaded[ $entry->item_id ] = $object; $this->loaded[ $entry->item_id ] = $object;
} }
$object->lineage = $stack; $object->lineage = $stack;
@ -87,7 +89,7 @@ class DAO_Items
private function loadTree( ) private function loadTree( )
{ {
$query = $this->query( $query = $this->query(
'SELECT p.item_id , p.item_name , MAX( t.pt_depth ) as depth ' 'SELECT p.item_id , p.item_name , p.item_description , MAX( t.pt_depth ) AS depth '
. 'FROM items p ' . 'FROM items p '
. 'INNER JOIN items_tree t ON t.item_id_child = p.item_id ' . 'INNER JOIN items_tree t ON t.item_id_child = p.item_id '
. 'GROUP BY p.item_id, p.item_name , p.item_ordering ' . 'GROUP BY p.item_id, p.item_name , p.item_ordering '
@ -114,6 +116,7 @@ class DAO_Items
$object = $this->loaded[ $entry->item_id ]; $object = $this->loaded[ $entry->item_id ];
} else { } else {
$object = new Data_Item( $entry->item_id , $entry->item_name ); $object = new Data_Item( $entry->item_id , $entry->item_name );
$object->description = $entry->item_description;
$this->loaded[ $entry->item_id ] = $object; $this->loaded[ $entry->item_id ] = $object;
} }
$object->children = array( ); $object->children = array( );
@ -172,7 +175,7 @@ class DAO_Items
} }
$query = $this->query( $query = $this->query(
'SELECT p.item_id , p.item_name , COUNT(*) AS t_count ' 'SELECT p.item_id , p.item_name , p.item_description , COUNT(*) AS t_count '
. 'FROM items p ' . 'FROM items p '
. 'INNER JOIN tasks t USING( item_id ) ' . 'INNER JOIN tasks t USING( item_id ) '
. 'LEFT OUTER JOIN completed_tasks c USING( task_id ) ' . 'LEFT OUTER JOIN completed_tasks c USING( task_id ) '
@ -185,6 +188,7 @@ class DAO_Items
$object = $this->loaded[ $entry->item_id ]; $object = $this->loaded[ $entry->item_id ];
} else { } else {
$object = new Data_Item( $entry->item_id , $entry->item_name ); $object = new Data_Item( $entry->item_id , $entry->item_name );
$object->description = $entry->item_description;
$this->loaded[ $entry->item_id ] = $object; $this->loaded[ $entry->item_id ] = $object;
} }
$object->activeTasks = $entry->t_count; $object->activeTasks = $entry->t_count;
@ -325,10 +329,10 @@ class DAO_Items
} }
public function rename( $item , $name ) public function modify( $item , $name , $description = '' )
{ {
$result = $this->query( 'SELECT rename_item( $1 , $2 ) AS error' ) $result = $this->query( 'SELECT update_item( $1 , $2 , $3 ) AS error' )
->execute( $item , $name ); ->execute( $item , $name , $description );
return $result[ 0 ]->error; return $result[ 0 ]->error;
} }
} }

View file

@ -4,6 +4,7 @@ class Data_Item
{ {
public $id; public $id;
public $name; public $name;
public $description;
public $hasParent; public $hasParent;
public $parent; public $parent;
public $children; public $children;

View file

@ -98,15 +98,16 @@ class Ctrl_AddItem
{ {
$name = $this->form->field( 'name' ); $name = $this->form->field( 'name' );
$before = $this->form->field( 'before' ); $before = $this->form->field( 'before' );
$description = $this->form->field( 'description' );
list( $after , $id ) = explode( ':' , $before->value( ) ); list( $after , $id ) = explode( ':' , $before->value( ) );
$items = Loader::DAO( 'items' ); $items = Loader::DAO( 'items' );
if ( $id === '' ) { if ( $id === '' ) {
$error = $items->createLast( $name->value( ) ); $error = $items->createLast( $name->value( ) , $description->value( ) );
} elseif ( $after == 1 ) { } elseif ( $after == 1 ) {
$error = $items->createUnder( $name->value( ) , $id ); $error = $items->createUnder( $name->value( ) , $id , $description->value( ) );
} else { } else {
$error = $items->createBefore( $name->value( ) , $id ); $error = $items->createBefore( $name->value( ) , $id , $description->value( ) );
} }
switch ( $error ) { switch ( $error ) {
@ -234,22 +235,23 @@ class Ctrl_EditItem
$item = $items->get( $id ); $item = $items->get( $id );
$name = $this->form->field( 'name' ); $name = $this->form->field( 'name' );
if ( $name->value( ) === $item->name ) { $description = $this->form->field( 'description' )->value( );
if ( $name->value( ) === $item->name && $description == $item->description ) {
return true; return true;
} }
$error = $items->rename( $id , $name->value( ) ); $error = $items->modify( $id , $name->value( ) , $description );
switch ( $error ) { switch ( $error ) {
case 0: case 0:
return true; return true;
case 1: case 1:
$name->putError( 'Ce nom n\'est pas unique' ); $name->putError( 'This name is not unique.' );
break; break;
default: default:
$name->putError( 'Une erreur inconnue s\'est produite (' . $error . ')' ); $name->putError( 'An unknown error occurred (' . $error . ')' );
break; break;
} }

View file

@ -49,6 +49,12 @@ class Ctrl_AddItemForm
->setMandatory( false ) ->setMandatory( false )
->setModifier( $locationField ) ->setModifier( $locationField )
->setValidator( $locationField ) ) ->setValidator( $locationField ) )
->addField( Loader::Create( 'Field' , 'description' , 'textarea' )
->setDescription( 'Description:' )
->setMandatory( false )
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
->setValidator( Loader::Create( 'Validator_StringLength' ,
'This description' , 10 , null , true ) ) )
->addField( Loader::Create( 'Field' , 'from' , 'hidden' ) ) ->addField( Loader::Create( 'Field' , 'from' , 'hidden' ) )
->addController( Loader::Ctrl( 'add_item' ) ); ->addController( Loader::Ctrl( 'add_item' ) );
@ -269,6 +275,13 @@ class Ctrl_EditItemForm
->setModifier( Loader::Create( 'Modifier_TrimString' ) ) ->setModifier( Loader::Create( 'Modifier_TrimString' ) )
->setValidator( Loader::Create( 'Validator_StringLength' , 'This name' , 2 , 128 ) ) ->setValidator( Loader::Create( 'Validator_StringLength' , 'This name' , 2 , 128 ) )
->setDefaultValue( $item->name ) ) ->setDefaultValue( $item->name ) )
->addField( Loader::Create( 'Field' , 'description' , 'textarea' )
->setDescription( 'Description:' )
->setMandatory( false )
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
->setValidator( Loader::Create( 'Validator_StringLength' ,
'This description' , 10 , null , true ) )
->setDefaultValue( $item->description ) )
->addField( Loader::Create( 'Field' , 'id' , 'hidden' ) ->addField( Loader::Create( 'Field' , 'id' , 'hidden' )
->setDefaultValue( $item->id ) ) ->setDefaultValue( $item->id ) )
->addController( Loader::Ctrl( 'edit_item' ) ) ->addController( Loader::Ctrl( 'edit_item' ) )

View file

@ -87,10 +87,18 @@ class View_ItemDetails
} }
} }
return HTML::make( 'dl' ) $details = HTML::make( 'dl' )
->appendElement( HTML::make( 'dt' )->appendText( 'Path:' ) ) ->appendElement( HTML::make( 'dt' )->appendText( 'Path:' ) )
->appendElement( HTML::make( 'dd' ) ->appendElement( HTML::make( 'dd' )
->setAttribute( 'style' , 'font-size: 10pt' ) ->setAttribute( 'style' , 'font-size: 10pt' )
->append( $contents ) ); ->append( $contents ) );
if ( $this->item->description !== null ) {
$details->appendElement( HTML::make( 'dt' )->appendText( 'Description:' ) )
->appendElement( HTML::make( 'dd' )
->appendText( $this->item->description ) );
}
return $details;
} }
} }