4 * This file is (c) Copyright 2009 by Olivier BERGER, Institut
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * This program has been developed in the frame of the HELIOS
22 * project with financial support of its funders.
28 require_once 'cql.php';
31 * OSLC-CM connector module
33 * This implements the application's controller. It is distinct from the Zend controller
34 * to try and become more independant from Zend (think reuse).
36 * @author Olivier Berger <olivier.berger@it-sudparis.eu
42 * OSLC-CM controler base class
49 * Holds a database of OSLC-CM ChangeRequest elements (the model)
53 protected $changerequests;
56 * @param array $params unused in base class
58 public function __construct($params=null) {
59 $this->changerequests = null;
62 public function getChangeRequests() {
63 return $this->changerequests;
67 * Initialize the model with appropriate parameters (project, etc.)
69 * Performs the checks on the parameters provided by Zend and invokes the model as needed.
71 * @param array $params parameters as passed by Zend
72 * @return unknown_type
74 public function init($params=null) {
76 $modelparams = $this->filterRequestParams($params);
78 // take into account the filtering on certain constraints
79 //the oslc_cm query parameters need to be url encoded for the params to be correct
81 $modelparams['filter'] = array();
82 if(array_key_exists('oslc_where', $params)) {
83 //print_r($params['oslc_cm_query']);
84 $filter=parse_cql(urldecode($params['oslc_where']));
86 $modelparams['filter']['where']=$filter;
90 else if(array_key_exists('oslc_cm_query', $params)) {
91 $filter=parse_cql(urldecode($params['oslc_cm_query']));
93 $modelparams['filter']['where']=$filter;
97 if(array_key_exists('oslc_orderBy', $params))
99 $tok = strtok($params['oslc_orderBy'], ",");
100 while ($tok !== false) {
102 if(preg_match("/^[+-][a-zA_Z:_]+$/", $tok)) {
103 if(substr($tok, 0, 1)=="+") {
105 }elseif(substr($tok, 0, 1)=="-") {
108 $attr = substr($tok, 1);
109 $modelparams['filter']['orderBy'][] = array($dir, $attr);
112 throw new BadRequestException("Error in oslc_orderBy syntax");
120 if(array_key_exists('oslc_limit', $params))
122 //converting to type int or float depending on the value of the value of the param
123 $temp_limit = $params['oslc_limit']+0;
124 //checking for a positive integer
125 if((is_int($temp_limit))&&($temp_limit>0)) {
126 $modelparams['filter']['limit']=$params['oslc_limit'];
128 throw new BadRequestException("The value for oslc_limit is not a positive integer!");
132 if(array_key_exists('oslc_offset', $params))
134 //converting to type int or float depending on the value of the value of the param
135 $temp_offset = $params['oslc_offset']+0;
136 //checking for a positive integer
137 if((is_int($temp_offset))&&($temp_offset>0)) {
138 //checking that oslc_limit has also been correctly defined
139 if(array_key_exists('limit', $modelparams['filter'])) {
140 //offset should be a multiple of limit
141 if($temp_offset%$temp_limit==0) {
142 $modelparams['filter']['offset']= ($temp_offset/$temp_limit)+1;
144 throw new ConflictException("oslc_offset should be a multiple of oslc_limit");
147 throw new ConflictException("oslc_offset cannot work without oslc_limit being defined");
150 throw new BadRequestException("The value for oslc_limit is not a positive integer!");
154 // take into account the restriction on values to be returned
155 if(array_key_exists('oslc_properties', $params)) {
156 $modelparams['fields'] = $params['oslc_properties'];
159 if(array_key_exists('oslc_searchTerms', $params)) {
160 $tok = strtok($params['oslc_searchTerms'], ",");
162 $tok = str_replace("\"", "", $tok);
163 $modelparams['filter']['searchTerms'][] = $tok;
165 }while ($tok !== false);
168 if(array_key_exists('filter', $modelparams) || array_key_exists('fields', $modelparams))
170 $this->changeRequestsQuery($modelparams);
174 $this->fetchChangeRequests($modelparams);
176 //print_r($this->changerequests);
181 * Instantiate a Zend Auth adapter for HTTP Basic auth
183 * It will be responsible of the validation of username and passwords provided
185 * By default, use a file containing usernames, realms and passwords
186 * (see docs of Zend_Auth_Adapter_Http_Resolver_File)
188 * $login and $password are only there to allow subclassing
190 * @param string $login transmitted in request
191 * @param string $password transmitted in request (clear text)
192 * @return Zend_Auth_Adapter_Http_Resolver_Interface
194 public function getHttpAuthBasicResolver($login, $password) {
195 // authenticate to .htpasswd-like file
196 $basicResolver = new Zend_Auth_Adapter_Http_Resolver_File();
197 $basicResolver->setFile(APPLICATION_PATH.'/basic-pwd.txt');
199 return $basicResolver;
204 * Retrieves ChangeRequest resources to be sent to the view
206 * The format returned is array( 'id' => identifier,
207 * 'resource' => array (
208 * 'fieldname' => value,
210 * This format should suit all needs of every views
212 * @param string $identifier of the ChangeRequest to be retrieved
213 * @param string $uri to be defined as its id
216 public function getResource($identifier, $uri=null) {
219 $changerequest = $this->changerequests[$identifier];
221 if (isset($changerequest)) {
222 $returned = $this->prepareChangeRequest($changerequest, $uri);
229 * Retrieves a list of ChangeRequest resources to be sent to the view
233 * @TODO: change function name to something like 'formatRessourceCollection'
235 public function getResourceCollection($uri=null)
239 // construct a list of all entries of the feed
240 foreach ($this->changerequests as $identifier => $changerequest) {
242 $feedentry = $this->prepareChangeRequest($changerequest);
244 $feedentry['title'] = 'changerequest '.$identifier.' : '.$feedentry['resource']['dcterms:title'];
245 $feedentry['id']= $uri.'/bug/'.$identifier;
247 $returned[] = $feedentry;
253 * Prepare a ChangeRequest to the format expected by the views
255 * It will do any necessary conversions, such as adding proper
258 * The format returned is array( 'id' => identifier,
259 * 'resource' => array (
260 * 'fieldname' => value,
262 * This format should suit all needs of every views
264 * @param unknown_type $changerequest
265 * @param unknown_type $uri
268 protected function prepareChangeRequest($changerequest, $uri=null) {
269 $preparedChangeRequest = array('resource' => array());
270 $dc_attr = array("title", "identifier", "type", "description","subject","creator","modified","name","created");
272 foreach ($changerequest as $fieldname => $value) {
274 // here, may do some conversions betw model and view
275 switch ($fieldname) {
278 $feedentry['author'] = $value;
282 // construct values with ontology prefix for the OSLC-CM DC fields
283 // TODO : use real RDF triples ?
284 $tokens = explode(':', $fieldname);
285 if( (count($tokens) == 1) && (in_array($fieldname,$dc_attr))) {
286 $fieldname = 'dcterms:'.$fieldname;
288 $preparedChangeRequest['resource'][$fieldname] = $value;
296 $preparedChangeRequest['id'] = $uri;
298 return $preparedChangeRequest;
303 * Create a new bug in the model
304 * @param ChangeRequest $cm_request
305 * @return unknown_type
307 /*public function createChangeRequest($cm_request)
310 $cm_request['identifier'] = $identifier;
312 $this->changerequests[$identifier] = $cm_request;
317 public function modifyChangeRequest()
324 * For demo DB using a CSV file
326 * @package CsvControler
330 * Concrete Demo OslcControler controler for CSV file support
333 class OslcCsvDemoConnector extends OslcConnector {
335 protected $csvFilename;
338 * @param array $params optional 'csvfilename' path to CSV file
340 public function __construct($params = null) {
341 parent::__construct($params);
343 if(is_array($params) && array_key_exists('csvfilename',$params)) {
344 $csvFilename = $params['csvfilename'];
346 $this->csvFilename = $csvFilename;
351 * Initialize a ChangeRequestsCsv DB
353 * It is passed in $params the 'id' => identifier if only one resource requested
355 * @param array $params
357 protected function fetchChangeRequests($params=null) {
359 // TODO : allow a configurable location for the test file outside of the code ?
361 $filename = $this->csvFilename;
364 $filename = APPLICATION_PATH."/test.csv";
367 $this->changerequests = new ChangeRequestsCsv($filename);
369 if(array_key_exists('project', $params)) {
370 $this->changerequests->setFilter(array('project' => $params['project']));