Коллекция классов модели, позволяющая получать данные непосредственно из базы данных WordPress.
Corcel — это набор классов PHP, созданных на основе Eloquent ORM (из платформы Laravel), который обеспечивает удобный интерфейс для подключения и получения данных непосредственно из базы данных WordPress.
Вы можете использовать WordPress в качестве бэкэнда (панели администрирования) или CMS для вставки сообщений, пользовательских типов и т. д., а также любое другое приложение PHP на другой стороне, запрашивающее эти данные (в качестве уровня модели). Corcel проще использовать с Laravel, но вы можете использовать его с любым проектом PHP, использующим Composer.
Купи мне кофе | Следите за Корселем в Твиттере
| Ларавел | Корсель |
|---|---|
| 5.1.х | ~2.1.0 |
| 5.2.х | ~2.2.0 |
| 5.3.х | ~2.3.0 |
| 5.4.х | ~2.4.0 |
| 5.5.х | ~2.5.0 |
| 5.6.х | ~2.6.0 |
| 5.7.х | ~2.7.0 |
| 5.8.х | ~2.8.0 |
| 6.0.х | ^3.0.0 |
| 7.0.х | ^4.0.0 |
| 8.0.х | ^5.0.0 |
| 9.0.х | ^6.0.0 |
| 10.0.х | ^7.0.0 |
| 11.0.x | ^8.0.0 |
Вам нужно использовать Composer для установки Corcel в ваш проект:
composer require jgrossi/corcel
Corcel зарегистрируется с помощью функции Auto Discovery от Laravel.
Вам нужно будет включить CorcelServiceProvider в ваш config/app.php :
' providers ' => [
/*
* Package Service Providers...
*/
Corcel Laravel CorcelServiceProvider::class,
]Теперь настройте наш файл конфигурации, чтобы убедиться, что ваша база данных настроена правильно, и чтобы вы могли очень легко регистрировать собственные типы сообщений и шорткоды:
Запустите следующую команду Artisan в своем терминале:
php artisan vendor:publish --provider="CorcelLaravelCorcelServiceProvider"
Теперь у вас есть файл конфигурации config/corcel.php , в котором вы можете настроить подключение к базе данных с таблицами WordPress и многое другое.
Просто установите connection с базой данных, которое вы хотите использовать Corcel, в config/corcel.php .
Предположим, у вас есть следующие подключения к базе данных в вашем файле config/database.php :
// File: /config/database.php
' connections ' => [
' mysql ' => [ // for Laravel database
' driver ' => ' mysql ' ,
' host ' => ' localhost ' ,
' database ' => ' mydatabase ' ,
' username ' => ' admin '
'password' => 'secret',
' charset ' => ' utf8 ' ,
' collation ' => ' utf8_unicode_ci ' ,
' prefix ' => '' ,
' strict ' => false ,
' engine ' => null ,
],
' wordpress ' => [ // for WordPress database (used by Corcel)
' driver ' => ' mysql ' ,
' host ' => ' localhost ' ,
' database ' => ' mydatabase ' ,
' username ' => ' admin ' ,
' password ' => ' secret ' ,
' charset ' => ' utf8 ' ,
' collation ' => ' utf8_unicode_ci ' ,
' prefix ' => ' wp_ ' ,
' strict ' => false ,
' engine ' => null ,
],
], В этом случае вам следует использовать соединение wordpress для Corcel, поэтому просто установите его в файле конфигурации Corcel config/corcel.php :
' connection ' => ' wordpress ' , Здесь вам необходимо настроить базу данных в соответствии с требованиями Corcel. Во-первых, вам следует включить файл autoload Composer, если он еще не загружен:
require __DIR__ . ' /vendor/autoload.php ' ;Теперь вам необходимо установить параметры базы данных WordPress:
$ params = [
' database ' => ' database_name ' ,
' username ' => ' username ' ,
' password ' => ' pa$$word ' ,
' prefix ' => ' wp_ ' // default prefix is 'wp_', you can change to your own prefix
];
Corcel Database:: connect ( $ params );Вы можете указать все параметры Eloquent, но некоторые из них являются значениями по умолчанию (но вы можете их переопределить).
' driver ' => ' mysql ' ,
' host ' => ' localhost ' ,
' charset ' => ' utf8 ' ,
' collation ' => ' utf8_unicode_ci ' ,
' prefix ' => ' wp_ ' , // Specify the prefix for WordPress tables, default prefix is 'wp_'Каждый раз, когда вы видите
Post::method(), если вы используете свой собственный класс Post (где вы устанавливаете имя соединения), напримерAppPostвам следует использоватьAppPost::method(), а неPost::method(). Во всех примерах предполагается, что вы уже знаете эту разницу.
В примерах каждый раз, когда вы видите
Post::method()предполагается, чтоCorcelModelPost::method().
// All published posts
$ posts = Post:: published ()-> get ();
$ posts = Post:: status ( ' publish ' )-> get ();
// A specific post
$ post = Post:: find ( 31 );
echo $ post -> post_title ; При желании вы можете создать свою собственную модель Post (или Page или что-то еще), которая расширяет CorcelPost . Затем установите имя соединения (если вы хотите переопределить имя Corcel по умолчанию), которое вы используете, в данном случае foo-bar :
Расширение класса
CorcelModelPostможет повысить гибкость вашего проекта, если вы сможете добавлять собственные методы и логику в соответствии с тем, что вам нужно использовать из вашей базы данных WordPress.
<?php // File: app/Post.php
namespace App ;
use Corcel Model Post as Corcel ;
class Post extends Corcel
{
protected $ connection = ' foo-bar ' ;
public function customMethod () {
//
}
}Итак, теперь вы можете получать данные базы данных WP, используя свой собственный класс:
$ posts = App Post:: all (); // using the 'foo-bar' connectionПросто помните, что вам не нужно расширять наш класс
Post, вы можете без проблем использоватьCorcelModelPostи все остальные модели.
ПРИМЕЧАНИЕ. В Corcel v1 вы можете сохранять метаданные с помощью метода
Post::save(). Это больше не разрешено. Используйте методыsaveMeta()илиcreateMeta()(см. ниже), чтобы сохранить мета-мета поста.
Вы также можете получать метаданные из сообщений.
// Get a custom meta value (like 'link' or whatever) from a post (any type)
$ post = Post:: find ( 31 );
echo $ post -> meta -> link ; // OR
echo $ post -> fields -> link ;
echo $ post -> link ; // OR Чтобы создать или обновить метаданные пользователя, просто используйте методы saveMeta() или saveField() . Они возвращают bool , как метод Eloquent save() .
$ post = Post:: find ( 1 );
$ post -> saveMeta ( ' username ' , ' jgrossi ' );Вы также можете сохранить много метаданных одновременно:
$ post = Post:: find ( 1 );
$ post -> saveMeta ([
' username ' => ' jgrossi ' ,
' url ' => ' http://jgrossi.com ' ,
]); У вас также есть методы createMeta() и createField() , которые работают как методы saveX() , но они используются только для создания и возврата созданного экземпляра PostMeta , а не bool .
$ post = Post:: find ( 1 );
$ postMeta = $ post -> createMeta ( ' foo ' , ' bar ' ); // instance of PostMeta class
$ trueOrFalse = $ post -> saveMeta ( ' foo ' , ' baz ' ); // boolean Существует множество возможностей запроса сообщений по их настраиваемым полям (мета) с использованием областей действия класса Post (или другой модели, использующей признак HasMetaFields ):
Чтобы проверить, существует ли метаключ, используйте область hasMeta() :
// Finds a published post with a meta flag.
$post = Post::published()->hasMeta('featured_article')->first();
Если вы хотите точно сопоставить метаполе, вы можете использовать область hasMeta() со значением.
// Find a published post which matches both meta_key and meta_value.
$ post = Post:: published ()-> hasMeta ( ' username ' , ' jgrossi ' )-> first (); Если вам нужно сопоставить несколько метаполей, вы также можете использовать область действия hasMeta() передав массив в качестве параметра:
$ post = Post:: hasMeta ([ ' username ' => ' jgrossi ' ])-> first ();
$ post = Post:: hasMeta ([ ' username ' => ' jgrossi ' , ' url ' => ' jgrossi.com ' ])-> first ();
// Or just passing the keys
$ post = Post:: hasMeta ([ ' username ' , ' url ' ])-> first (); Если вам нужно сопоставить строку без учета регистра или сопоставить подстановочные знаки, вы можете использовать область действия hasMetaLike() со значением. Здесь используется оператор SQL LIKE , поэтому используйте «%» в качестве подстановочного оператора.
// Will match: 'J Grossi', 'J GROSSI', and 'j grossi'.
$ post = Post:: published ()-> hasMetaLike ( ' author ' , ' J GROSSI ' )-> first ();
// Using % as a wildcard will match: 'J Grossi', 'J GROSSI', 'j grossi', 'Junior Grossi' etc.
$ post = Post:: published ()-> hasMetaLike ( ' author ' , ' J%GROSSI ' )-> first (); Класс Post поддерживает «псевдонимы», поэтому, если вы проверите класс Post , вы должны обратить внимание на некоторые псевдонимы, определенные в статическом массиве $aliases , например title для post_title и content для post_content .
$ post = Post:: find ( 1 );
$ post -> title === $ post -> post_title ; // true Если вы расширяете класс Post для создания своего собственного класса, вы также можете использовать $aliases . Просто добавьте новые псевдонимы к этому статическому свойству внутри вашего собственного класса, и он автоматически унаследует все псевдонимы из родительского класса Post :
class A extends Corcel Post
{
protected static $ aliases = [
' foo ' => ' post_foo ' ,
];
}
$ a = A:: find ( 1 );
echo $ a -> foo ;
echo $ a -> title ; // from Post class Чтобы упорядочить сообщения, вы можете использовать области newest() и oldest() как для классов Post , так и для классов User :
$ newest = Post:: newest ()-> first ();
$ oldest = Post:: oldest ()-> first (); Чтобы упорядочить публикации, просто используйте метод Eloquent paginate() :
$ posts = Post:: published ()-> paginate ( 5 );
foreach ( $ posts as $ post ) {
// ...
} Чтобы отобразить ссылки на страницы, просто вызовите метод links() :
{{ $ posts -> links () }} Если вы хотите получить настраиваемое поле, созданное подключаемым модулем Advanced Custom Fields (ACF), вам необходимо установить подключаемый модуль corcel/acf (щелкните здесь для получения дополнительной информации) и вызвать настраиваемое поле следующим образом:
$ post = Post:: find ( 123 );
echo $ post -> acf -> some_radio_field ;
$ repeaterFields = $ post -> acf -> my_repeater_name ;Чтобы избежать ненужных запросов SQL, просто установите тип поля, которое вы запрашиваете. Обычно для получения типа поля необходимы два SQL-запроса, поэтому, если вы хотите указать его, вы пропускаете эти дополнительные запросы:
$ post = Post:: find ( 123 );
echo $ post -> acf -> text ( ' text_field_name ' );
echo $ post -> acf -> boolean ( ' boolean_field_name ' ); Вы также можете работать с произвольными типами сообщений. Вы можете использовать метод type(string) или создать свой собственный класс.
// using type() method
$ videos = Post:: type ( ' video ' )-> status ( ' publish ' )-> get ();
// using your own class
class Video extends Corcel Post
{
protected $ postType = ' video ' ;
}
$ videos = Video:: status ( ' publish ' )-> get (); Использование метода type() заставит Corcel вернуть все объекты как CorcelPost . Используя собственный класс, вы можете настраивать классы, включая собственные методы и свойства, например, возвращать все объекты как Video .
Пользовательские типы сообщений и метаданные:
// Get 3 posts with custom post type (store) and show its address
$ stores = Post:: type ( ' store ' )-> status ( ' publish ' )-> take ( 3 )-> get ();
foreach ( $ stores as $ store ) {
$ storeAddress = $ store -> address ; // option 1
$ storeAddress = $ store -> meta -> address ; // option 2
$ storeAddress = $ store -> fields -> address ; // option 3
} Каждый раз, когда вы вызываете что-то вроде Post::type('video)->first() или Video::first() вы получаете экземпляр CorcelModelPost .
Если вы решите создать новый класс для своего пользовательского типа записи, вы можете вернуть этот класс для всех экземпляров этого типа записи.
Вместо вызова метода Post::registerPostType() для всех пользовательских типов сообщений, которые вы хотите зарегистрировать, просто используйте файл конфигурации Corcel и сопоставьте все пользовательские сообщения и их классы. Они будут зарегистрированы для вас автоматически:
' post_types ' => [
' video ' => App Video::class,
' foo ' => App Foo::class,
]Таким образом, каждый раз, когда вы запрашиваете пользовательский тип сообщения, будет возвращен сопоставленный экземпляр.
Это особенно полезно, когда вы собираетесь получить коллекцию сообщений разных типов (например, при получении сообщений, определенных в меню).
//all objects in the $videos Collection will be instances of Post
$ videos = Post:: type ( ' video ' )-> status ( ' publish ' )-> get ();
// register the video custom post type and its particular class
Post:: registerPostType ( ' video ' , ' AppVideo ' )
//now all objects in the $videos Collection will be instances of Video
$ videos = Post:: type ( ' video ' )-> status ( ' publish ' )-> get ();Вы также можете сделать это для встроенных классов, таких как Page или Post. Просто зарегистрируйте класс Page или Post со связанной строкой типа записи, и этот объект будет возвращен вместо объекта по умолчанию.
Вы можете сопоставить все нужные вам короткие коды внутри файла config/corcel.php под ключом 'shortcodes' . В этом случае вам следует создать собственный класс, implements интерфейс CorcelShortcode , для которого требуется метод render() :
' shortcodes ' => [
' foo ' => App Shortcodes FooShortcode::class,
' bar ' => App Shortcodes BarShortcode::class,
],Это пример класса короткого кода:
class FakeShortcode implements Corcel Shortcode
{
/**
* @param ShortcodeInterface $shortcode
* @return string
*/
public function render ( ShortcodeInterface $ shortcode )
{
return sprintf (
' html-for-shortcode-%s-%s ' ,
$ shortcode -> getName (),
$ shortcode -> getParameter ( ' one ' )
);
}
} Вы можете добавить шорткоды, вызвав метод addShortcode модели Post :
// [gallery id="1"]
Post:: addShortcode ( ' gallery ' , function ( $ shortcode ) {
return $ shortcode -> getName () . ' . ' . $ shortcode -> getParameter ( ' id ' );
});
$ post = Post:: find ( 1 );
echo $ post -> content ;Laravel 5.5 использует автоматическое обнаружение пакетов, поэтому вам не требуется вручную добавлять ServiceProvider.
Если вы используете Laravel, мы предлагаем добавить обработчики коротких кодов в AppProvidersAppServiceProvider в методе boot .
Короткие коды анализируются с помощью библиотеки Thunderer/Shortcode .
Предоставляется несколько различных парсеров. RegularParser является наиболее технически правильным и предоставляется по умолчанию. Это подходит для большинства случаев. Однако, если вы обнаружите некоторые нарушения в анализе короткого кода, вам может потребоваться настроить Corcel для использования WordpressParser , который более точно соответствует регулярному выражению короткого кода WordPress. Для этого, если вы используете Laravel, отредактируйте файл config/corcel.php и раскомментируйте предпочитаемый парсер. Альтернативно, вы можете заменить это собственным синтаксическим анализатором.
' shortcode_parser ' => Thunder Shortcode Parser RegularParser::class,
// 'shortcode_parser' => ThunderShortcodeParserWordpressParser::class, Если вы не используете Laravel, вы можете сделать это во время выполнения, вызвав метод setShortcodeParser() из любого класса, который использует особенность Shortcodes , например Post .
$ post -> setShortcodeParser ( new WordpressParser ());
echo $ post -> content ; // content parsed with "WordpressParser" classДля получения дополнительной информации о пакете шорткодов нажмите здесь.
Вы можете получить таксономии для конкретной публикации, например:
$ post = Post:: find ( 1 );
$ taxonomy = $ post -> taxonomies ()-> first ();
echo $ taxonomy -> taxonomy ;Или вы можете искать сообщения, используя его таксономию:
$ post = Post:: taxonomy ( ' category ' , ' php ' )-> first (); Вы также можете получить формат сообщения, например, с помощью функции WordPress get_post_format() :
echo $ post -> getFormat (); // should return something like 'video', etc Страницы похожи на пользовательские типы сообщений. Вы можете использовать Post::type('page') или класс CorcelModelPage .
use Corcel Model Page ;
// Find a page by slug
$ page = Page:: slug ( ' about ' )-> first (); // OR
$ page = Post:: type ( ' page ' )-> slug ( ' about ' )-> first ();
echo $ page -> post_title ;Получите категорию или таксономию или загрузите сообщения из определенной категории. Есть несколько способов добиться этого.
// all categories
$ cat = Taxonomy:: category ()-> slug ( ' uncategorized ' )-> posts -> first ();
echo " <pre> " ; print_r ( $ cat -> name ); echo " </pre> " ;
// only all categories and posts connected with it
$ cat = Taxonomy:: where ( ' taxonomy ' , ' category ' )-> with ( ' posts ' )-> get ();
$ cat -> each ( function ( $ category ) {
echo $ category -> name ;
});
// clean and simple all posts from a category
$ cat = Category:: slug ( ' uncategorized ' )-> posts -> first ();
$ cat -> posts -> each ( function ( $ post ) {
echo $ post -> post_title ;
}); Получение вложения и/или редакции из Post или Page .
$ page = Page:: slug ( ' about ' )-> with ( ' attachment ' )-> first ();
// get feature image from page or post
print_r ( $ page -> attachment );
$ post = Post:: slug ( ' test ' )-> with ( ' revision ' )-> first ();
// get all revisions from a post or page
print_r ( $ post -> revision ); Получение миниатюры для Post или Page .
$ post = Post:: find ( 1 );
// Retrieve an instance of CorcelModelMetaThumbnailMeta.
print_r ( $ post -> thumbnail );
// For convenience you may also echo the thumbnail instance to get the URL of the original image.
echo $ post -> thumbnail ; Чтобы получить определенный размер миниатюры, вы можете вызвать метод ->size() объекта миниатюры и передать строковый параметр размера миниатюры (например, thumbnail или medium ). Если миниатюра была создана, этот метод возвращает массив метаданных изображения, в противном случае URL-адрес исходного изображения будет возвращен в качестве резервного варианта.
if ( $ post -> thumbnail !== null ) {
/**
* [
* 'file' => 'filename-300x300.jpg',
* 'width' => 300,
* 'height' => 300,
* 'mime-type' => 'image/jpeg',
* 'url' => 'http://localhost/wp-content/uploads/filename-300x300.jpg',
* ]
*/
print_r ( $ post -> thumbnail -> size ( Corcel Model Meta ThumbnailMeta:: SIZE_THUMBNAIL ));
// http://localhost/wp-content/uploads/filename.jpg
print_r ( $ post -> thumbnail -> size ( ' invalid_size ' ));
}В предыдущих версиях Corcel этот класс назывался
OptionsвместоOption(единственное число). Поэтому позаботьтесь о том, чтобы всегда использовать этот класс в единственном числе, начиная сv2.0.0.
Option::getAll()был удален в Corcel 2+ в пользуOption::asArray($keys []).
Вы можете использовать класс Option для получения данных из таблицы wp_options :
$ siteUrl = Option:: get ( ' siteurl ' );Вы также можете добавить новые опции:
Option:: add ( ' foo ' , ' bar ' ); // stored as string
Option:: add ( ' baz ' , [ ' one ' => ' two ' ]); // this will be serialized and savedВы можете получить все параметры в простом массиве:
$ options = Option:: asArray ();
echo $ options [ ' siteurl ' ];Или вы можете указать только те ключи, которые хотите получить:
$ options = Option:: asArray ([ ' siteurl ' , ' home ' , ' blogname ' ]);
echo $ options [ ' home ' ]; Чтобы получить меню по его ярлыку, используйте синтаксис ниже. Пункты меню будут загружены в переменную items (это коллекция объектов CorcelModelMenuItem ).
В настоящее время поддерживаются следующие пункты меню: Страницы, Публикации, Пользовательские ссылки и Категории.
Если у вас появятся экземпляры класса MenuItem , и вы хотите использовать исходный экземпляр (например, исходную страницу или термин), просто вызовите метод MenuItem::instance() . Объект MenuItem — это просто сообщение с post_type , равным nav_menu_item :
$ menu = Menu:: slug ( ' primary ' )-> first ();
foreach ( $ menu -> items as $ item ) {
echo $ item -> instance ()-> title ; // if it's a Post
echo $ item -> instance ()-> name ; // if it's a Term
echo $ item -> instance ()-> link_text ; // if it's a custom link
} Метод instance() вернет соответствующий объект:
Post для пункта меню post ;Page для пункта меню page ;CustomLink для custom пункта меню;Term для пункта меню category .Чтобы обрабатывать многоуровневые меню, пройдитесь по всем пунктам меню, например, чтобы разместить их на нужных уровнях.
Вы можете использовать метод MenuItem::parent() для получения родительского экземпляра этого пункта меню:
$ items = Menu:: slug ( ' foo ' )-> first ()-> items ;
$ parent = $ items -> first ()-> parent (); // Post, Page, CustomLink or Term (category) Чтобы сгруппировать пункты меню по их родителям, вы можете использовать метод ->groupBy() в коллекции $menu->items , группируя пункты меню по их $item->parent()->ID .
Чтобы узнать больше о методе groupBy() прочтите документацию Laravel.
Вы можете манипулировать пользователями так же, как вы работаете с публикациями:
// All users
$ users = User:: get ();
// A specific user
$ user = User:: find ( 1 );
echo $ user -> user_login ; Если вы используете Laravel 5.4 или более раннюю версию, убедитесь, что у вас зарегистрирован поставщик CorcelServiceProvider .
Затем определите поставщика пользователей в config/auth.php , чтобы позволить Laravel входить в систему с пользователями WordPress:
' providers ' => [
' users ' => [
' driver ' => ' corcel ' ,
' model ' => Corcel Model User::class,
],
], Теперь вы можете использовать фасад Auth для аутентификации пользователей:
Auth:: validate ([
' email ' => ' [email protected] ' , // or using 'username' too
' password ' => ' secret ' ,
]); Чтобы сброс пароля Laravel работал с Corcel, нам необходимо переопределить способ хранения паролей в базе данных. Для этого вам необходимо изменить Auth/PasswordController.php с:
use App Http Controllers Controller ;
use Illuminate Foundation Auth ResetsPasswords ;
class PasswordController extends Controller
{
use ResetsPasswords;к
use App Http Controllers Controller ;
use Illuminate Foundation Auth ResetsPasswords ;
use Corcel Laravel Auth ResetsPasswords as CorcelResetsPasswords ;
class PasswordController extends Controller
{
use ResetsPasswords, CorcelResetsPasswords {
CorcelResetsPasswords::resetPassword insteadof ResetsPasswords;
} Вы можете использовать класс AuthUserProvider для ручной аутентификации пользователя:
$ userProvider = new Corcel Laravel Auth AuthUserProvider ;
$ user = $ userProvider -> retrieveByCredentials ([ ' username ' => ' admin ' ]);
if (! is_null ( $ user ) && $ userProvider -> validateCredentials ( $ user , [ ' password ' => ' admin ' ])) {
// successfully login
}Помните, что вы можете использовать как
username, так и
Чтобы запустить тесты phpunit, выполните следующую команду:
./vendor/bin/phpunit
Если у вас установлена глобальная команда phpunit вы можете просто ввести:
phpunit
Все тесты были написаны с использованием Sqlite с базой данных :memory , поэтому они выполняются в вашей памяти. Все тесты используют factories и migrations . Для получения дополнительной информации просмотрите каталогиtests tests/database/factories tests/database/migrations .
Мы приветствуем любой вклад, который поможет улучшить Corcel.
Прежде чем отправить запрос на включение (PR), примите во внимание следующие рекомендации:
Форк https://github.com/corcel/corcel в Github;
Клонируйте свой раздвоенный репозиторий (не Corcel) локально и создайте собственную ветку на основе версии, которую вы хотите исправить ( 2.1 , 2.2 , 2.3 , 2.4 или 2.5 ): git checkout -b my-fix-branch 2.5 ;
Внесите все изменения в код. Не забудьте написать хотя бы один тестовый пример для каждой добавляемой вами функции или любого исправления ошибки (если она еще не протестирована). Наша цель — обеспечить 100% покрытия кода тестами, поэтому помогите нам написать лучший код ;-) Если у вас нет опыта работы с тестами, это хорошая возможность научиться. Просто взгляните на наши тестовые примеры, и вы увидите, насколько они просты.
Запустите модульные тесты локально, чтобы убедиться, что ваши изменения не нарушают работу других фрагментов кода;
Отправьте новую ветку в разветвленный репозиторий, обычно git push origin HEAD должен работать;
Снова в GitHub создайте запрос на включение (PR) из вашей пользовательской ветки my-fix-branch (из вашего разветвленного репозитория) в связанную ветку (например, corcel:2.5 , а не corcel:master , пожалуйста;
Ждем одобрения :-)
Лицензия MIT © Джуниор Гросси