Sequenzia/app/controllers/TagController.php
2013-10-26 23:29:33 -05:00

291 lines
11 KiB
PHP
Executable File

<?php
class TagController extends ApplicationController
{
protected function filters()
{
return [
'before' => [
'mod_only' => ['only' => ['mass_edit', 'edit_preview']],
'member_only' => ['only' => ['update', 'edit']]
]
];
}
public function cloud()
{
$this->tags = Tag::where("post_count > 0")->order("post_count DESC")->limit(100)->take()->sort(function ($a, $b) {
$a_name = strlen($a->name);
$b_name = strlen($b->name);
if ($a_name == $b_name)
return 0;
return ($a_name < $b_name) ? -1 : 1;
});
}
// # Generates list of tag names matching parameter term.
// # Used by jquery.ui.autocomplete.
// public function autocompleteName()
// {
// $this->tags = Tag.where(['name ILIKE ?', "*#{$this->params()->term}*".to_escaped_for_sql_like]).pluck(:name)
// $this->respondTo(array(
// format.json { $this->render(array('json' => $this->tags })
// ));
// }
public function summary()
{
if ($this->params()->version) {
# HTTP caching is unreliable for XHR. If a version is supplied, and the version
# hasn't changed since then, return; an empty response.
$version = Tag::get_summary_version();
if ((int)$this->params()->version == $version) {
$this->render(array('json' => array('version' => $version, 'unchanged' => true)));
return;
}
}
# This string is already JSON-encoded, so don't call toJson.
$this->render(array('json' => Tag::get_json_summary()));
}
public function index()
{
$this->set_title('Tags');
if ($this->params()->limit === "0")
$limit = null;
elseif (!$this->params()->limit)
$limit = 50;
else
$limit = (int)$this->params()->limit;
switch ($this->params()->order) {
case "name":
$order = "name";
break;
case "count":
$order = "post_count desc";
break;
case "date":
$order = "id desc";
break;
default:
$order = "name";
break;
}
$query = Tag::where("true");
// $cond_params = array();
if ($this->params()->name) {
// $conds[] = "name LIKE ?";
if (is_int(strpos($this->params()->name, '*')))
$query->where('name LIKE ?', str_replace('*', '%', $this->params()->name));
else
$query->where('name LIKE ?', '%' . str_replace('*', '%', $this->params()->name) . '%');
}
if (ctype_digit($this->params()->type)) {
$this->params()->type = (int)$this->params()->type;
$query->where('tag_type = ?', $this->params()->type);
}
if (!empty($this->params()->after_id)) {
$query->where('id >= ?', $this->params()->after_id);
}
if (!empty($this->params()->id)) {
$query->where('id = ?', $this->params()->id);
}
$query->order($order);
$this->respondTo(array(
'html' => function () use ($order, $query) {
$this->can_delete_tags = CONFIG()->enable_tag_deletion && current_user()->is_mod_or_higher();
$this->tags = $query->paginate($this->page_number(), 50);
},
'xml' => function () use ($order, $limit, $query) {
// $conds = implode(" AND ", $conds);
// if ($conds == "true" && CONFIG()->web_server == "nginx" && file_exists(Rails::publicPath()."/tags.xml")) {
// # Special case: instead of rebuilding a list of every tag every time, cache it locally and tell the web
// # server to stream it directly. This only works on Nginx.
// $this->response()->headers()->add("X-Accel-Redirect", Rails::publicPath() . "/tags.xml");
// $this->render(array('nothing' => true));
// } else {
$this->render(array('xml' => $query->limit($limit)->take(), 'root' => "tags"));
// }
},
'json' => function ($s) use ($order, $limit, $query) {
$tags = $query->limit($limit)->take();
$this->render(array('json' => $tags));
}
));
}
public function massEdit()
{
$this->set_title('Mass Edit Tags');
if ($this->request()->isPost()) {
if (!$this->params()->start) {
$this->respond_to_error("Start tag missing", ['#mass_edit'], ['status' => 424]);
return;
}
if (CONFIG()->is_job_task_active('mass_tag_edit')) {
$task = JobTask::create(['task_type' => "mass_tag_edit", 'status' => "pending", 'data' => ["start_tags" => $this->params()->start, "result_tags" => $this->params()->result, "updater_id" => $this->current_user->id, "updater_ip_addr" => $this->request()->remoteIp()]]);
$this->respond_to_success("Mass tag edit job created", 'job_task#index');
} else {
Tag::mass_edit($this->params()->start, $this->params()->result, current_user()->id, $this->request()->remoteIp());
}
}
}
public function editPreview()
{
list($sql, $params) = Post::generate_sql($this->params()->tags, ['order' => "p.id DESC", 'limit' => 500]);
$this->posts = Post::findBySql($sql, $params);
$this->setLayout(false);
}
public function edit()
{
if ($this->params()->id) {
$this->tag = Tag::where(['id' => $this->params()->id])->first() ?: new Tag();
} else {
$this->tag = Tag::where(['name' => $this->params()->name])->first() ?: new Tag();
}
}
public function update()
{
$tag = Tag::where(['name' => $this->params()->tag['name']])->first();
if ($tag)
$tag->updateAttributes($this->params()->tag);
$this->respond_to_success("Tag updated", '#index');
}
public function related()
{
if ($this->params()->type) {
$this->tags = Tag::scan_tags($this->params()->tags);
$this->tags = TagAlias::to_aliased($this->tags);
$all = [];
$tag_type = CONFIG()->tag_types[$this->params()->type];
foreach ($this->tags as $x) {
$all[$x] = array_map(function($y) use ($x) {
return [$y["name"], $y["post_count"]];
}, Tag::calculate_related_by_type($x, $tag_type));
}
$this->tags = $all;
} else {
$tags = Tag::scan_tags($this->params()->tags);
$this->patterns = $this->tags = [];
foreach ($tags as $tag) {
if (is_int(strpos($tag, "*")))
$this->patterns[] = $tag;
else
$this->tags[] = $tag;
}
unset($tags, $tag);
$this->tags = TagAlias::to_aliased($this->tags);
$all = [];
foreach ($this->tags as $x) {
$all[$x] = array_map(function($y) { return [$y[0], $y[1]]; }, Tag::find_related($x));
}
$this->tags = $all;
foreach ($this->patterns as $x) {
$this->tags[$x] = array_map(function($y) { return [$y->name, $y->post_count]; }, Tag::where("name LIKE ?", '%' . $x . '%')->first());
}
}
$this->respondTo([
// fmt.xml do
// # We basically have to do this by hand.
// builder = Builder::XmlMarkup.new('indent' => 2)
// builder.instruct!
// xml = builder.tag!("tags") do
// $this->tags.each do |parent, related|
// builder.tag!("tag", 'name' => parent) do
// related.each do |tag, count|
// builder.tag!("tag", 'name' => tag, 'count' => count)
// end
// end
// end
// end
// $this->render(array('xml' => xml)
// end
'json' => function() { $this->render(['json' => json_encode($this->tags)]); }
]);
}
public function popularByDay()
{
if (!$this->params()->year || !$this->params()->month || !$this->params()->day ||
!($this->day = @strtotime($this->params()->year . '-' . $this->params()->month . '-' . $this->params()->day))) {
$this->day = strtotime('this day');
}
$this->tags = Tag::count_by_period(date('Y-m-d', $this->day), date('Y-m-d', strtotime('+1 day', $this->day)));
}
public function popularByWeek()
{
if (!$this->params()->year || !$this->params()->month || !$this->params()->day ||
!($this->start = strtotime('this week', @strtotime($this->params()->year . '-' . $this->params()->month . '-' . $this->params()->day)))) {
$this->start = strtotime('this week');
}
$this->end = strtotime('next week', $this->start);
$this->tags = Tag::count_by_period(date('Y-m-d', $this->start), date('Y-m-d', $this->end));
}
public function popularByMonth()
{
if (!$this->params()->year || !$this->params()->month || !($this->start = @strtotime($this->params()->year . '-' . $this->params()->month . '-01'))) {
$this->start = strtotime('first day of this month');
}
$this->end = strtotime('+1 month', $this->start);
$this->tags = Tag::count_by_period(date('Y-m-d', $this->start), date('Y-m-d', $this->end));
}
// public function show()
// {
// begin
// name = Tag.find($this->params()->id, 'select' => :name).name
// rescue
// raise ActionController::RoutingError.new('Not Found') }
// redirectTo 'controller' => :wiki, 'action' => :show, 'title' => name
// }
public function delete()
{
if (!CONFIG()->enable_tag_deletion) {
$this->respond_to_error('Access denied', '#index');
return;
}
$tag = Tag::find($this->params()->id);
if ($tag)
$tag->destroy();
$opts = $this->params()->get();
unset($opts['id']);
array_unshift($opts, '#index');
$this->respond_to_success('Tag deleted', $opts);
}
}