Skip to content

Commit

Permalink
Merge pull request #9 from BookStackApp/master
Browse files Browse the repository at this point in the history
Get the latest changes.
  • Loading branch information
Abijeet authored Apr 18, 2017
2 parents 4e71a5a + fde970b commit 9de8528
Show file tree
Hide file tree
Showing 60 changed files with 2,343 additions and 634 deletions.
9 changes: 9 additions & 0 deletions app/Book.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,13 @@ public function getExcerpt($length = 100)
return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
}

/**
* Return a generalised, common raw query that can be 'unioned' across entities.
* @return string
*/
public function entityRawQuery()
{
return "'BookStack\\\\Book' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
}

}
9 changes: 9 additions & 0 deletions app/Chapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,13 @@ public function getExcerpt($length = 100)
return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
}

/**
* Return a generalised, common raw query that can be 'unioned' across entities.
* @return string
*/
public function entityRawQuery()
{
return "'BookStack\\\\Chapter' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, '' as html, book_id, priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
}

}
9 changes: 8 additions & 1 deletion app/Console/Commands/RegeneratePermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class RegeneratePermissions extends Command
*
* @var string
*/
protected $signature = 'bookstack:regenerate-permissions';
protected $signature = 'bookstack:regenerate-permissions {--database= : The database connection to use.}';

/**
* The console command description.
Expand Down Expand Up @@ -46,7 +46,14 @@ public function __construct(PermissionService $permissionService)
*/
public function handle()
{
$connection = \DB::getDefaultConnection();
if ($this->option('database') !== null) {
\DB::setDefaultConnection($this->option('database'));
}

$this->permissionService->buildJointPermissions();

\DB::setDefaultConnection($connection);
$this->comment('Permissions regenerated');
}
}
53 changes: 53 additions & 0 deletions app/Console/Commands/RegenerateSearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace BookStack\Console\Commands;

use BookStack\Services\SearchService;
use Illuminate\Console\Command;

class RegenerateSearch extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bookstack:regenerate-search {--database= : The database connection to use.}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';

protected $searchService;

/**
* Create a new command instance.
*
* @param SearchService $searchService
*/
public function __construct(SearchService $searchService)
{
parent::__construct();
$this->searchService = $searchService;
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$connection = \DB::getDefaultConnection();
if ($this->option('database') !== null) {
\DB::setDefaultConnection($this->option('database'));
}

$this->searchService->indexAllEntities();
\DB::setDefaultConnection($connection);
$this->comment('Search index regenerated');
}
}
13 changes: 6 additions & 7 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<?php

namespace BookStack\Console;
<?php namespace BookStack\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
Expand All @@ -13,10 +11,11 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
\BookStack\Console\Commands\ClearViews::class,
\BookStack\Console\Commands\ClearActivity::class,
\BookStack\Console\Commands\ClearRevisions::class,
\BookStack\Console\Commands\RegeneratePermissions::class,
Commands\ClearViews::class,
Commands\ClearActivity::class,
Commands\ClearRevisions::class,
Commands\RegeneratePermissions::class,
Commands\RegenerateSearch::class
];

/**
Expand Down
77 changes: 19 additions & 58 deletions app/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class Entity extends Ownable
{

protected $fieldsToSearch = ['name', 'description'];
public $textField = 'description';

/**
* Compares this entity to another given entity.
Expand Down Expand Up @@ -65,6 +65,15 @@ public function tags()
return $this->morphMany(Tag::class, 'entity')->orderBy('order', 'asc');
}

/**
* Get the related search terms.
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function searchTerms()
{
return $this->morphMany(SearchTerm::class, 'entity');
}

/**
* Get this entities restrictions.
*/
Expand Down Expand Up @@ -153,67 +162,19 @@ public function getShortName($length = 25)
}

/**
* Perform a full-text search on this entity.
* @param string[] $fieldsToSearch
* @param string[] $terms
* @param string[] array $wheres
* Get the body text of this entity.
* @return mixed
*/
public function fullTextSearchQuery($terms, $wheres = [])
public function getText()
{
$exactTerms = [];
$fuzzyTerms = [];
$search = static::newQuery();

foreach ($terms as $key => $term) {
$term = htmlentities($term, ENT_QUOTES);
$term = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $term);
if (preg_match('/&quot;.*?&quot;/', $term) || is_numeric($term)) {
$term = str_replace('&quot;', '', $term);
$exactTerms[] = '%' . $term . '%';
} else {
$term = '' . $term . '*';
if ($term !== '*') $fuzzyTerms[] = $term;
}
}

$isFuzzy = count($exactTerms) === 0 && count($fuzzyTerms) > 0;


// Perform fulltext search if relevant terms exist.
if ($isFuzzy) {
$termString = implode(' ', $fuzzyTerms);
$fields = implode(',', $this->fieldsToSearch);
$search = $search->selectRaw('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance', [$termString]);
$search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
}

// Ensure at least one exact term matches if in search
if (count($exactTerms) > 0) {
$search = $search->where(function ($query) use ($exactTerms) {
foreach ($exactTerms as $exactTerm) {
foreach ($this->fieldsToSearch as $field) {
$query->orWhere($field, 'like', $exactTerm);
}
}
});
}

$orderBy = $isFuzzy ? 'title_relevance' : 'updated_at';

// Add additional where terms
foreach ($wheres as $whereTerm) {
$search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
}
return $this->{$this->textField};
}

// Load in relations
if ($this->isA('page')) {
$search = $search->with('book', 'chapter', 'createdBy', 'updatedBy');
} else if ($this->isA('chapter')) {
$search = $search->with('book');
}
/**
* Return a generalised, common raw query that can be 'unioned' across entities.
* @return string
*/
public function entityRawQuery(){return '';}

return $search->orderBy($orderBy, 'desc');
}

}
Loading

0 comments on commit 9de8528

Please sign in to comment.