Skip to content

Commit

Permalink
Release v3.6.4 (#1707)
Browse files Browse the repository at this point in the history
**New Features**
- Added Field Level Locking to Surveys
- Improved Survey UX
- Added Task Level Visibility
- Added Webhook Support
- Added Webhook UX
- Added Webhook events fro Create, Update of Post
- Added Survey Duplication 
- Added Task Duplication
- Added Support for OSS deployment with Ushahidi Mobile
- Added Deeplinking for iOS and Android
- Added Banner ads for iOS and Android
- Adding Location Search Picker for Maps in Posts
- Added reply to twitter via Post feature
- Added support for hierarchical categories
- Added Category field type to Survey
- Added Markdown field type to Survey
- Add tags dynamically directly from Posts
- Added language switching for all users


**Minor improvements and fixes**
- Adding uglify-friendly code to colors
- Confirming on delete for unsaved surveys, tasks and fields
- Upgrade node to v6
- Resolved twitter duplication bug
- Display number of unmapped posts to timeline
- Moved Savedsearches to Modal
- Moved Filter to Modal
  • Loading branch information
willdoran authored Apr 21, 2017
1 parent 7a27fcd commit 995ee2c
Show file tree
Hide file tree
Showing 57 changed files with 1,739 additions and 348 deletions.
14 changes: 3 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
sudo: false
notifications:
hipchat:
rooms:
secure: fb2eYR4DVBestPl/DSG7lnUWT46Rmr9BfRsZFe4dhrS3ZetkZ1XZueF6SCtB4yukaJoDlA7y98FgQ7eGx6OGToc4ALnPpwd3BdfJ5RV/PK/6LG7u5Mp4+DfB4lG1q9IjuHF7dhBPSk2sRd8ewtwV5JR4SHKYfHxSR9Ekwmn1Xyo=
template:
- '<a href="%{build_url}">%{repository}#%{build_number}</a> (%{branch} - <a href="%{compare_url}">%{commit}</a>
: %{author}): %{message}'
format: html
notify: true
slack:
secure: NxhzhKGYnZYZiWVZM4w1PlZpTy9bbmNlvbqjL+9d4PvK4hFzPwQU12CchhBPeXNGLWBHg/ti6Scn/t5XIS3YJrkk4ydWmJBht5UId8uFZ1A7GCUnNNPTt2RG55lbJJdZSj01rOGZjEQbE5RyckEjgRzhZjdZ+HsjoPaRzWIBrvE=
#notifications:
# slack:
# secure: NxhzhKGYnZYZiWVZM4w1PlZpTy9bbmNlvbqjL+9d4PvK4hFzPwQU12CchhBPeXNGLWBHg/ti6Scn/t5XIS3YJrkk4ydWmJBht5UId8uFZ1A7GCUnNNPTt2RG55lbJJdZSj01rOGZjEQbE5RyckEjgRzhZjdZ+HsjoPaRzWIBrvE=
language: php
php:
- '5.5'
Expand Down
2 changes: 1 addition & 1 deletion application/classes/Ushahidi/Console/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private function generateRequest($webhook_request)

// This is an asynchronous request, we don't expect a result
// this can be extended to allow for handling of the returned promise
$promise = $this->client->requestAsync('POST', $webhook->url, [
$promise = $this->client->request('POST', $webhook->url, [
'headers' => [
'X-Platform-Signature' => $signature,
'Accept' => 'application/json'
Expand Down
131 changes: 14 additions & 117 deletions application/classes/Ushahidi/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,53 +351,8 @@ public static function init()
// Set Formatter factory
$di->params['Ushahidi\Factory\FormatterFactory']['factory'] = $di->newFactory('Ushahidi_Formatter_Collection');

// Helpers, tools, etc
$di->set('tool.hasher.password', $di->lazyNew('Ushahidi_Hasher_Password'));
$di->set('tool.signer', $di->lazyNew('Ushahidi\Core\Tool\Signer'));
$di->set('tool.authenticator.password', $di->lazyNew('Ushahidi_Authenticator_Password'));

$di->set('tool.validation', $di->lazyNew('Ushahidi_ValidationEngine'));
$di->set('tool.jsontranscode', $di->lazyNew('Ushahidi\Core\Tool\JsonTranscode'));
$di->set('tool.acl', $di->lazyNew('Ushahidi_Acl'));
$di->setter['Ushahidi_Acl']['setRoleRepo'] = $di->lazyGet('repository.role');

// Register filesystem adpater types
// Currently supported: Local filesysten, AWS S3 v3, Rackspace
// the naming scheme must match the cdn type set in config/cdn
$di->set('adapter.local', $di->lazyNew(
'Ushahidi_FilesystemAdapter_Local',
[
'config' => $di->lazyGet('cdn.config')
]
)
);
$di->set('adapter.aws', $di->lazyNew(
'Ushahidi_FilesystemAdapter_AWS',
[
'config' => $di->lazyGet('cdn.config')
]
)
);
$di->set('adapter.rackspace', $di->lazyNew(
'Ushahidi_FilesystemAdapter_Rackspace',
[
'config' => $di->lazyGet('cdn.config')
]
)
);

// Media Filesystem
// The Ushahidi filesystem adapter returns a flysystem adapter for a given
// cdn type based on the provided configuration
$di->set('tool.filesystem', $di->lazyNew('Ushahidi_Filesystem'));
$di->params['Ushahidi_Filesystem'] = [
'adapter' => $di->lazy(function () use ($di) {
$adapter_type = $di->get('cdn.config');
$fsa = $di->get('adapter.' . $adapter_type['type']);

return $fsa->getAdapter();
})
];

// Formatters
$di->set('formatter.entity.api', $di->lazyNew('Ushahidi_Formatter_API'));
Expand Down Expand Up @@ -472,6 +427,17 @@ public static function init()
'upload' => $di->lazyGet('tool.uploader'),
];

// Form Stage repository parameters
$di->params['Ushahidi_Repository_Form_Stage'] = [
'form_repo' => $di->lazyGet('repository.form')
];

// Form Attribute repository parameters
$di->params['Ushahidi_Repository_Form_Attribute'] = [
'form_stage_repo' => $di->lazyGet('repository.form_stage'),
'form_repo' => $di->lazyGet('repository.form')
];

// Post repository parameters
$di->params['Ushahidi_Repository_Post'] = [
'form_attribute_repo' => $di->lazyGet('repository.form_attribute'),
Expand Down Expand Up @@ -572,7 +538,8 @@ public static function init()
'user_repo' => $di->lazyGet('repository.user'),
'collection_repo' => $di->lazyGet('repository.set'),
'savedsearch_repo' => $di->lazyGet('repository.savedsearch'),
];$di->params['Ushahidi_Validator_Webhook_Update'] = [
];
$di->params['Ushahidi_Validator_Webhook_Update'] = [
'user_repo' => $di->lazyGet('repository.user'),
];
$di->params['Ushahidi_Validator_SavedSearch_Create'] = [
Expand Down Expand Up @@ -663,7 +630,7 @@ public static function init()
'point' => $di->lazyGet('validator.post.point'),
'relation' => $di->lazyGet('validator.post.relation'),
'varchar' => $di->lazyGet('validator.post.varchar'),
'markdown' => $di->lazyGet('validator.post.markdown'),
'markdown' => $di->lazyGet('validator.post.markdown'),
'title' => $di->lazyGet('validator.post.title'),
'media' => $di->lazyGet('validator.post.media'),
'video' => $di->lazyGet('validator.post.video'),
Expand All @@ -680,12 +647,6 @@ public static function init()
$di->setter['Ushahidi_Transformer_CSVPostTransformer']['setRepo'] =
$di->lazyGet('repository.post');

$di->set('filereader.csv', $di->lazyNew('Ushahidi_FileReader_CSV'));
$di->setter['Ushahidi_FileReader_CSV']['setReaderFactory'] =
$di->lazyGet('csv.reader_factory');

$di->set('csv.reader_factory', $di->lazyNew('Ushahidi_CSVReaderFactory'));

$di->set('tool.mailer', $di->lazyNew('Ushahidi_Mailer'));

// Event listener for the Set repo
Expand All @@ -711,70 +672,6 @@ public static function init()
$di->setter['Ushahidi_Listener_PostListener']['setWebhookRepo'] =
$di->lazyGet('repository.webhook');

// Defined memcached
$di->set('memcached', $di->lazy(function () use ($di) {
$config = $di->get('ratelimiter.config');

$memcached = new Memcached();
$memcached->addServer($config['memcached']['host'], $config['memcached']['port']);

return $memcached;
}));

// Set up login rate limiter
$di->set('ratelimiter.login.flap', $di->lazyNew('BehEh\Flaps\Flap'));

$di->params['BehEh\Flaps\Flap'] = [
'storage' => $di->lazyNew('BehEh\Flaps\Storage\DoctrineCacheAdapter'),
'name' => 'login'
];

$di->set('ratelimiter.login.strategy', $di->lazyNew('BehEh\Flaps\Throttling\LeakyBucketStrategy'));

// 3 requests every 1 minute by default
$di->params['BehEh\Flaps\Throttling\LeakyBucketStrategy'] = [
'requests' => 3,
'timeSpan' => '1m'
];

$di->set('ratelimiter.login', $di->lazyNew('Ushahidi_RateLimiter'));

$di->params['Ushahidi_RateLimiter'] = [
'flap' => $di->lazyGet('ratelimiter.login.flap'),
'throttlingStrategy' => $di->lazyGet('ratelimiter.login.strategy'),
];

$di->params['BehEh\Flaps\Storage\DoctrineCacheAdapter'] = [
'cache' => $di->lazyGet('ratelimiter.cache')
];

// Rate limit storage cache
$di->set('ratelimiter.cache', function() use ($di) {
$config = $di->get('ratelimiter.config');
$cache = $config['cache'];

if ($cache === 'memcached') {
$di->setter['Doctrine\Common\Cache\MemcachedCache']['setMemcached'] =
$di->lazyGet('memcached');

return $di->newInstance('Doctrine\Common\Cache\MemcachedCache');
}
elseif ($cache === 'filesystem') {
$di->params['Doctrine\Common\Cache\FilesystemCache'] = [
'directory' => $config['filesystem']['directory'],
];

return $di->newInstance('Doctrine\Common\Cache\FilesystemCache');
}

// Fall back to using in-memory cache if none is configured
return $di->newInstance('Doctrine\Common\Cache\ArrayCache');
});

// Rate limiter violation handler
$di->setter['BehEh\Flaps\Flap']['setViolationHandler'] =
$di->lazyNew('Ushahidi_ThrottlingViolationHandler');

/**
* 1. Load the plugins
*/
Expand Down
1 change: 0 additions & 1 deletion application/classes/Ushahidi/Formatter/Post/CSV.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ protected function generateCSVRecords($records)

// Sort the keys so that they match with columns from the CSV heading
ksort($record);
Kohana::$log->add(Log::ERROR, print_r($record, true));

fputcsv($fp, $record);
}
Expand Down
11 changes: 11 additions & 0 deletions application/classes/Ushahidi/Formatter/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,15 @@ protected function format_color($value)
$value = ltrim($value, '#');
return $value ? '#' . $value : null;
}

protected function format_forms($forms)
{
$output = [];
foreach ($forms as $formid)
{
$output[] = $this->get_relation('forms', $formid);
}

return $output;
}
}
122 changes: 122 additions & 0 deletions application/classes/Ushahidi/FormsTagsTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php defined('SYSPATH') OR die('No direct script access.');

/**
* Ushahidi FormsTags Repo Trait
* Helps Forms and Tags-repository use the same methods
** @author Ushahidi Team <team@ushahidi.com>
* @package Ushahidi\Application\Controllers
* @copyright 2013 Ushahidi
* @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License Version 3 (AGPL3)
*/

trait Ushahidi_FormsTagsTrait
{
//returning forms for a specific Tag-id
private function getFormsForTag($id)
{
$result = DB::select('form_id')
->from('forms_tags')
->where('tag_id', '=', $id)
->execute($this->db);
return $result->as_array(NULL, 'form_id');
}
//returning tags for a specific Form-id
private function getTagsForForm($id)
{
$result = DB::select('tag_id')
->from('forms_tags')
->where('form_id', '=', $id)
->execute($this->db);
return $result->as_array(NULL, 'tag_id');
}

// updating/adding tags to a form
private function updateFormsTags($form_id, $tags)
{
if (!$tags) {
DB::delete('forms_tags')
->where('form_id', '=', $form_id)
->execute($this->db);
} else if ($tags) {
$existing = $this->getTagsForForm($form_id);
$insert = DB::insert('forms_tags', ['form_id', 'tag_id']);
$tag_ids = [];
$new_tags = FALSE;
foreach ($tags as $tag) {
if (!in_array($tag, $existing)) {
$insert->values([$form_id, $tag]);
$new_tags = TRUE;
}
$tag_ids[] = $tag;
}
if ($new_tags) {
$insert->execute($this->db);
}
if (!empty($tag_ids)) {
DB::delete('forms_tags')
->where('tag_id', 'NOT IN', $tag_ids)
->and_where('form_id', '=', $form_id)
->execute($this->db);
}
}
}

//updating/adding forms to a tag
private function updateTagForms($tag_id, $forms)
{
if (empty($forms)) {
DB::delete('forms_tags')
->where('tag_id', '=', $tag_id)
->execute($this->db);
} else {
$existing = $this->getFormsForTag($tag_id);
$insert = DB::insert('forms_tags', ['form_id', 'tag_id']);
$form_ids = [];
$new_forms = FALSE;
foreach ($forms as $form) {
if (isset($form['id'])) {
$id = $form['id'];
} else {
$id = $form;
}
if (!in_array($form, $existing)) {
$insert->values([$id, $tag_id]);
$new_forms = TRUE;
}
$form_ids[] = $id;
}

if ($new_forms) {
$insert->execute($this->db);
}

if (!empty($form_ids)) {
DB::delete('forms_tags')
->where('form_id', 'NOT IN', $form_ids)
->and_where('tag_id', '=', $tag_id)
->execute($this->db);
}
}
}

private function updateFormAttributes($id)
{
$attr = DB::select('id', 'options')
->from('form_attributes')
->where('input', '=', 'tags')
->execute($this->db)
->as_array('id', 'options');
foreach ($attr as $attr_id => $value) {
$value = json_decode($value);
if (in_array($id, $value)) {
$index = array_search($id, $value);
array_splice($value, $index, 1);
$value = json_encode($value);
DB::update('form_attributes')
->set(array('options' => $value))
->where('id', '=', $attr_id)
->execute($this->db);
}
}
}
}
Loading

0 comments on commit 995ee2c

Please sign in to comment.