Skip to content
This repository was archived by the owner on Dec 11, 2018. It is now read-only.

Commit 850bfa3

Browse files
committed
Working on proposal editing
Made some progress on adding a new proposal.
1 parent ec03828 commit 850bfa3

File tree

5 files changed

+71
-20
lines changed

5 files changed

+71
-20
lines changed

data/db/schema.mysql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ CREATE TABLE IF NOT EXISTS proposals (
2727
, title VARCHAR(255) BINARY NOT NULL
2828
, description BLOB
2929
, url VARCHAR(1023) BINARY
30+
, amount INT(11) UNSIGNED
31+
, theme VARCHAR(32)
32+
, notes BLOB
3033
, status ENUM('open','rejected','approved','abandoned') NOT NULL
3134
, created_by INT(11)
3235
, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

data/templates/inc/forms.html

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
{% macro label( ctx, mesg, name, opts = {} ) %}
1616
{% set opts = { 'required':false, 'escape':true }|merge( opts ) %}
1717
{% set tran = mesg|message %}
18-
<label for="{{ name }}" class="control-label {{ opts['required'] ? 'required' }}">{% if
19-
opts['escape'] == false %}{{ tran|raw }}{% else %}{{ tran }}{% endif %}</label>
18+
<label for="{{ name }}" class="control-label {{ opts['required'] ? 'required' }}">{% if opts['escape'] == false %}{{ tran|raw }}{% else %}{{ tran }}{% endif %}</label>
2019
{% endmacro %}
2120

2221
{% macro startElement( ctx, mesg, name, opts = {} ) %}
@@ -33,21 +32,56 @@
3332
</div>
3433
{% endmacro %}
3534

36-
{% macro text( ctx, mesg, name, opts = {} ) %}
35+
{% macro input( ctx, type, mesg, name, opts = {} ) %}
3736
{% import _self as forms %}
3837
{% set opts = { 'required':false }|merge( opts ) %}
3938
{% set value = ctx.form.get( name ) %}
4039
{{ forms.startElement( ctx, mesg, name, opts ) }}
41-
<input type="text" class="form-control" id="{{ name }}" name="{{ name }}" value="{{ value ?: '' }}" {{ opts['required'] ? 'required' }}/>
40+
<input type="{{ type }}" class="form-control" id="{{ name }}" name="{{ name }}" value="{{ value ?: '' }}" {{ opts['required'] ? 'required' }}/>
4241
{{ forms.endElement( ctx, name, mesg ) }}
4342
{% endmacro %}
4443

44+
{% macro text( ctx, mesg, name, opts = {} ) %}
45+
{% import _self as forms %}
46+
{{ forms.input( ctx, 'text', mesg, name, opts ) }}
47+
{% endmacro %}
48+
49+
{% macro number( ctx, mesg, name, opts = {} ) %}
50+
{% import _self as forms %}
51+
{{ forms.input( ctx, 'number', mesg, name, opts ) }}
52+
{% endmacro %}
53+
54+
{% macro url( ctx, mesg, name, opts = {} ) %}
55+
{% import _self as forms %}
56+
{{ forms.input( ctx, 'url', mesg, name, opts ) }}
57+
{% endmacro %}
58+
4559
{% macro textArea( ctx, mesg, name, opts = {} ) %}
4660
{% import _self as forms %}
4761
{% set opts = { 'required':false }|merge( opts ) %}
4862
{% set value = ctx.form.get( name ) %}
4963
{{ forms.startElement( ctx, mesg, name, opts ) }}
50-
<textarea class="form-control" id="{{ name }}" name="{{ name }}" cols="80" rows="3" {{ opts['required'] ? 'required' }}>{{ value ?: '' }}</textarea>
64+
<textarea class="form-control" id="{{ name }}" name="{{ name }}" cols="80" rows="3" {{ opts['required'] ? 'required' }}>{{ value ?: '' }}</textarea>
65+
{{ forms.endElement( ctx, name, mesg ) }}
66+
{% endmacro %}
67+
68+
{##
69+
# @param Twig_Context ctx
70+
# @param string mesg Message key for element label
71+
# @param array options Array of value => label options to display
72+
# @param array opts Additional element options
73+
#}
74+
{% macro select( ctx, mesg, name, options, opts = {} ) %}
75+
{% import _self as forms %}
76+
{% set opts = { 'required':false }|merge( opts ) %}
77+
{% set value = ctx.form.get( name ) %}
78+
{{ forms.startElement( ctx, mesg, name, opts ) }}
79+
<select id="{{ name }}" name="{{ name }}" class="form-control" {{ opts['required'] ? 'required' }}>
80+
<option value="">{{ ( mesg ~ '-empty' )|message }}</option>
81+
{% for val, label in options %}
82+
<option value="{{ val }}" {{ val == value ? 'selected="selected"' }}>{{ label }}</option>
83+
{% endfor %}
84+
</select>
5185
{{ forms.endElement( ctx, name, mesg ) }}
5286
{% endmacro %}
5387

data/templates/proposals/add.html

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
{% import "inc/forms.html" as forms %}
33
{% set ctx = _context %}
44

5-
{% set errors = flash.form_errors|default([]) %}
6-
{% if flash.form_defaults|default(false) %}
7-
{% set u = flash.form_defaults %}
8-
{% endif %}
9-
105
{% block content %}
116
{% spaceless %}
127
<ol class="breadcrumb">
@@ -24,7 +19,9 @@
2419
<form class="form-horizontal" method="post" action="{{ urlFor( 'proposals_add_post' ) }}">
2520
<input type="hidden" name="{{ csrf_param }}" value="{{ csrf_token }}" />
2621
{{ forms.text( ctx, 'proposals-add-title', 'title', { 'required':true } ) }}
27-
{{ forms.text( ctx, 'proposals-add-url', 'url', { 'required':true } ) }}
22+
{{ forms.url( ctx, 'proposals-add-url', 'url', { 'required':true } ) }}
23+
{{ forms.select( ctx, 'proposals-add-theme', 'theme', { 'online':'online', 'offline':'offline', 'tool':'tool', 'research':'research' }, { 'required':true } ) }}
24+
{{ forms.number( ctx, 'proposals-add-amount', 'amount' ) }}
2825
{{ forms.textArea( ctx, 'proposals-add-description', 'description' ) }}
2926
<input type="submit" class="btn btn-primary" id="submit" name="submit" value="{{ 'proposals-add-submit'|message }}" />
3027
</form>

src/Controllers/Proposals/Add.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ protected function setupForm() {
3939
$this->setForm( $saved );
4040
} else {
4141
$this->form->expectString( 'title', array( 'required' => true ) );
42-
$this->form->expectString( 'description' );
4342
$this->form->expectUrl( 'url', array( 'required' => true ) );
43+
$this->form->expectString( 'description' );
44+
$this->form->expectInt( 'amount' );
45+
// TODO: themes from db?
46+
$this->form->expectInArray( 'theme',
47+
array( 'online', 'offline', 'tool', 'research' ),
48+
array( 'required' => true )
49+
);
4450
}
4551
$this->view->setData( 'form', $this->form );
4652
}

src/Dao/Proposals.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public function createProposal( array $data ) {
7979
public function search( array $params ) {
8080
$defaults = array(
8181
'proposals' => '',
82+
'sort' => 'id',
83+
'order' => 'asc',
8284
'items' => 20,
8385
'page' => 0,
8486
);
@@ -88,6 +90,14 @@ public function search( array $params ) {
8890
$crit = array();
8991
$crit['int_userid'] = $this->userId ?: 0;
9092

93+
$validSorts = array(
94+
'id', 'title', 'amount', 'theme', 'status',
95+
'review_count', 'my_review_count',
96+
);
97+
$sortby = in_array( $params['sort'], $validSorts ) ?
98+
$params['sort'] : $defaults['sort'];
99+
$order = $params['order'] === 'desc' ? 'DESC' : 'ASC';
100+
91101
if ( $params['items'] == 'all' ) {
92102
$limit = '';
93103
$offset = '';
@@ -99,12 +109,14 @@ public function search( array $params ) {
99109
}
100110

101111
$fields = array(
102-
'p.id',
103-
'p.title',
104-
'p.url',
105-
'p.status',
106-
'COALESCE(review_count, 0) as review_count',
107-
'COALESCE(my_review_count, 0) as my_review_count',
112+
'p.id as id',
113+
'p.title as title',
114+
'p.url as url',
115+
'p.amount as amount',
116+
'p.theme as theme',
117+
'p.status as status',
118+
'COALESCE(rc.review_count, 0) as review_count',
119+
'COALESCE(mc.my_review_count, 0) as my_review_count',
108120
);
109121

110122
switch( $params['proposals'] ) {
@@ -139,8 +151,7 @@ public function search( array $params ) {
139151
'FROM proposals p',
140152
$joins,
141153
self::buildWhere( $where ),
142-
// TODO: add sorting
143-
'ORDER BY p.id',
154+
"ORDER BY {$sortby}, id {$order}",
144155
$limit, $offset
145156
);
146157
return $this->fetchAllWithFound( $sql, $crit );

0 commit comments

Comments
 (0)