Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/Resources/views/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,8 @@
</div>
</div>
</footer>
<span class='hidden loader'>
<img src='{{ asset('static/images/loader.gif') }}' /> <span class="sr-only">Loading&hellip;</span>
</span>
</body>
</html>
4 changes: 3 additions & 1 deletion app/Resources/views/macros/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# @param string id - id of the section, defaults to the title
# @param bool notranslate - don't translate the 'title'
#}
{% macro content_block(title, content, description, id = null, notranslate = false) %}
{% macro content_block(title, content, description, id = null, notranslate = false, toggle = true) %}
{% if id is null %}
{% set id = title %}
{% endif %}
Expand All @@ -17,8 +17,10 @@
{% else %}
{{ msg(title) }}
{% endif %}
{% if toggle %}
<small class='xt-show'>[{{ msg('show') }}]</small>
<small class='xt-hide'>[{{ msg('hide') }}]</small>
{% endif %}
{% if description is defined %}
<span class='pull-right text-muted xt-panel-description'>{{ description }}</span>
{% endif %}
Expand Down
8 changes: 4 additions & 4 deletions app/Resources/views/topedits/result_namespace.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,23 @@
<tbody>
{% for edit in edits %}
<tr>
<td class="sort-entry--edits" data-value="{{ edit.count }}">{{ edit.count }}</td>
<td class="sort-entry--edits tdnum" data-value="{{ edit.count }}">{{ edit.count|number_format }}</td>
<td class="sort-entry--page" data-value="{{ edit.page_title }}">
{{ wiki_link(edit.page_title, project_url, edit.displaytitle) }}
</td>
<td>
{{ wiki_log_link(edit.page_title, project_url) }}
&middot;
<a href="{{ path('ArticleInfoResult', {project:project, article:edit.page_title}) }}">{{ msg('tool_articleinfo') }}</a>
<a href="{{ path('ArticleInfoResult', {project:project, article:edit.page_title|url_encode}) }}">{{ msg('tool_articleinfo') }}</a>
&middot;
<a href="{{ path('TopEditsResults', {project:project, username:username, namespace:namespace, article:edit.page_title}) }}" >{{ msg('tool_topedits') }}</a>
<a href="{{ path('TopEditsResults', {project:project, username:username, namespace:namespace, article:edit.page_title|url_encode}) }}" >{{ msg('tool_topedits') }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endset %}
{{ layout.content_block('mainspace', content) }}
{{ layout.content_block(content_title, content, '', null, false, false) }}
</div>
</div>
{% endblock %}
3 changes: 2 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"name": "Name",
"namespace": "Namespace",
"namespacetotals": "Namespace Totals",
"namespaces_all": "All namespaces",
"neutral": "Neutral",
"no_summary": "no summary",
"nocontribs": "No contributions found",
Expand Down Expand Up @@ -236,7 +237,7 @@
"tool_topedits_desc": "Get edits by a user, either top edits per namespace or edits per page",
"toomanyrevisions": "This article has over 50,000 revisions. Data for the first 50,000 are shown below.",
"topeditedpages": "Top edited pages",
"topedits_per_namespace": "TOP edits per namespace",
"topedits_per_namespace": "Top edits per namespace",
"topten": "Top 10%",
"toptenbyedits": "TOP 10 by edits",
"toptenbytext": "TOP 10 by added text",
Expand Down
28 changes: 23 additions & 5 deletions src/AppBundle/Controller/TopEditsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,30 +97,47 @@ public function resultAction($project, $username, $namespace = 0, $article = "")
*/
protected function namespaceTopEdits($username, $project, $namespace)
{
// Get list of namespaces.
/** @var ApiHelper $apiHelper */
$apiHelper = $this->get('app.api_helper');
$namespaces = $apiHelper->namespaces($project);

// Get the basic data about the pages edited by this user.
$params = ['username'=>$username];
$nsClause = '';
$namespaceMsg = 'namespaces_all';
if (is_numeric($namespace)) {
$nsClause = 'AND page_namespace = :namespace';
$params['namespace'] = $namespace;
$namespaceMsg = str_replace(' ', '_', strtolower($namespaces[$namespace]));
}
$query = "SELECT page_namespace, page_title, page_is_redirect, COUNT(page_title) AS count
FROM ".$this->lh->getTable('page')." JOIN ".$this->lh->getTable('revision')." ON page_id = rev_page
WHERE rev_user_text = :username AND page_namespace = :namespace
WHERE rev_user_text = :username $nsClause
GROUP BY page_namespace, page_title
ORDER BY count DESC
LIMIT 100";
$params = ['username'=>$username, 'namespace'=> $namespace];
$conn = $this->getDoctrine()->getManager('replicas')->getConnection();
$editData = $conn->executeQuery($query, $params)->fetchAll();

// Inform user if no revisions found.
if (count($editData) === 0) {
$this->addFlash("notice", ["nocontribs"]);
}

// Get page info about these 100 pages, so we can use their display title.
$titles = array_map(function ($e) {
return $e['page_title'];
}, $editData);
/** @var ApiHelper $apiHelper */
$apiHelper = $this->get('app.api_helper');
$displayTitles = $apiHelper->displayTitles($project, $titles);

// Put all together, and return the view.
$edits = [];
foreach ($editData as $editDatum) {
$pageTitle = $editDatum['page_title'];
$editDatum['displaytitle'] = $displayTitles[$pageTitle];
// If 'all' namespaces, prepend namespace to display title.
$nsTitle = !is_numeric($namespace) ? $namespaces[$editDatum['page_namespace']].':' : '';
$editDatum['displaytitle'] = $nsTitle.$displayTitles[$pageTitle];
$edits[] = $editDatum;
}
return $this->render('topedits/result_namespace.html.twig', [
Expand All @@ -130,6 +147,7 @@ protected function namespaceTopEdits($username, $project, $namespace)
'username' => $username,
'namespace' => $namespace,
'edits' => $edits,
'content_title' => $namespaceMsg,
]);
}

Expand Down
Binary file added web/static/images/loader.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 11 additions & 3 deletions web/static/js/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,20 +194,27 @@
var lastProject = $('#project_input').val();

$('#project_input').on('change', function () {
// disable the namespace selector while the data loads
// Disable the namespace selector and show a spinner while the data loads.
$('#namespace_select').prop('disabled', true);
$loader = $('span.loader');
$('label[for="namespace_select"]').append($loader);
$loader.removeClass('hidden');

var newProject = this.value;

$.get(xtBaseUrl + 'api/namespaces/' + newProject).done(function (namespaces) {
var $allOption = $('#namespace_select option').eq(0).clone();
// Clone the 'all' option (even if there isn't one),
// and replace the current option list with this.
var $allOption = $('#namespace_select option[value="all"]').eq(0).clone();
$("#namespace_select").html($allOption);
// Add all of the new namespace options.
for (var ns in namespaces) {
$('#namespace_select').append(
"<option value=" + ns + ">" + namespaces[ns] + "</option>"
);
}
$("#namespace_select").val(0); // default to mainspace
// Default to mainspace being selected.
$("#namespace_select").val(0);
lastProject = newProject;
}).fail(function () {
// revert back to last valid project
Expand All @@ -223,6 +230,7 @@
);
}).always(function () {
$('#namespace_select').prop('disabled', false);
$loader.addClass('hidden');
});
});
}
Expand Down