Статьи

AngularJS и Laravel: начните строить CRM

При создании одностраничного приложения мы должны использовать какую-то платформу, чтобы выполнить часть работы за нас, чтобы мы могли сосредоточиться на реальной функциональности. AngularJS идеально подходит здесь, потому что такие функции, как динамическое внедрение зависимостей и двунаправленное связывание данных, просто великолепны. Иногда нам также требуется какой-то сервер. Если вы выбрали PHP, тогда Laravel может быть вашим лучшим вариантом, так как с ним легко работать и он довольно мощный.

В этом руководстве вы создадите простую систему управления клиентами / транзакциями с возможностью добавления и удаления транзакций и клиентов. Вероятно, это не та вещь, которую вы делаете очень часто, но она показывает, как использовать функции обеих платформ.

Перед тем, как мы начнем, вы должны настроить базу данных MySQL, которую мы будем использовать (Laravel поддерживает гораздо больше из них, но она все еще остается самой популярной). Вам не нужен какой-либо веб-сервер, так как мы будем использовать встроенный PHP (но имейте в виду, что это решение предназначено только для разработки и никогда не должно использоваться в производстве — в нем отсутствуют многие функции, необходимые для вашего приложение для правильной работы в общественных местах). Для этого нам понадобится хотя бы версия PHP 5.4.0.

Первое, что нам нужно сделать, это установить Laravel. Полный процесс описан на веб-сайте Laravel . После этого вы должны создать каталог вашего проекта со всеми файлами Laravel. Перейдите к этому каталогу в командной строке и выполните эту команду там:

Если все идет хорошо, вы должны увидеть, что локальный сервер разработки запущен на locahost:8000 . Откройте браузер и перейдите туда , вы должны увидеть страницу приветствия Laravel:

первый забег

Теперь мы можем перейти к фактическому применению.

Модели в Laravel такие же, как и в любой другой среде MVC. Он использует Eloquent ORM, чтобы упростить вам работу — вам, вероятно, больше никогда не придется писать SQL-запрос (если только вам не понадобится то, что Eloquent не поддерживает). Используя миграции, вы можете изменить структуру базы данных с возможностью отката изменений, если что-то пойдет не так. Вы можете прочитать больше о миграции в документации .

В нашем приложении мы будем использовать две модели:

  • Customer — будет хранить данные клиента
  • Transaction — будет содержать информацию о транзакции

Давайте начнем с создания миграций для них. Если вы этого еще не сделали, выключите сервер, который мы запускали ранее ( Ctrl + C ).

Сначала вызовите эту команду:

Это создаст файл миграции с базовой структурой для вас. Теперь перейдите к app/database/migrations . Должен быть файл с именем, начинающимся с метки времени и заканчивающимся « create_customers_table ». Laravel автоматически создал эту базовую структуру для вас. Метод up() вызывается, когда применяется миграция, и down() когда выполняется откат.

Сначала вызовите метод Schema::create() . Он принимает два аргумента — имя схемы и функцию обратного вызова:

1
Schema::create(‘customers’, function ($table) {

Обратный вызов выполняется при создании таблицы. Объект таблицы передается как переменная $table и мы манипулируем структурой таблицы, используя ее. Давайте добавим поле id автоинкрементом:

1
$table->increments(‘id’);

Далее будут три строковых поля для имени, фамилии и адреса клиента:

1
2
3
$table->string(‘first_name’);
   $table->string(‘last_name’);
   $table->string(’email’)->unique();

Мы делаем поле email уникальным, вызывая для него метод unique() .

Последний метод для отметок времени:

1
2
$table->timestamps();
});

Это создаст два поля даты в схеме: created_at и updated_at . Они будут использоваться Eloquent для хранения времени, когда элемент был создан и обновлен.

Наконец, код должен выглядеть следующим образом:

1
2
3
4
5
6
7
8
9
public function up() {
    Schema::create(‘customers’, function ($table) {
        $table->increments(‘id’);
        $table->string(‘first_name’);
        $table->string(‘last_name’);
        $table->string(’email’)->unique();
        $table->timestamps();
    });
}

Метод down() намного проще — он просто удаляет схему:

1
2
3
public function down() {
    Schema::drop(‘customers’);
}

Код здесь будет похож на код клиента. Сначала вызовите эту команду:

Теперь найдите соответствующий файл в app/database/migrations и откройте его. Как и раньше, начните с создания схемы:

1
Schema::create(‘transactions’, function ($table) {

Теперь добавьте поля для идентификатора, названия транзакции, ее стоимости и идентификатора клиента, которому она принадлежит:

1
2
3
4
$table->increments(‘id’);
   $table->string(‘name’);
   $table->float(‘amount’);
   $table->integer(‘customer_id’);

И, конечно же, отметки времени:

1
2
$table->timestamps();
});

Окончательный код должен выглядеть так:

1
2
3
4
5
6
7
8
9
public function up() {
    Schema::create(‘transactions’, function ($table) {
        $table->increments(‘id’);
        $table->string(‘name’);
        $table->float(‘amount’);
        $table->integer(‘customer_id’);
        $table->timestamps();
    });
}

А теперь метод down() :

1
2
3
public function down() {
    Schema::drop(‘transactions’);
}

Теперь, прежде чем применять миграцию, вам нужно настроить соединение с вашей базой данных. Откройте файл app/config/database.php и перейдите к строке 55 . Вот данные конфигурации для MySQL (там немного других, например, вы можете использовать SQLite или Postgres):

01
02
03
04
05
06
07
08
09
10
‘mysql’ => array(
    ‘driver’ => ‘mysql’, // database driver, don’t touch
    ‘host’ => ‘localhost’, // host of the database, usually localhost unless you have your db on some server
    ‘database’ => ‘database’, // name of the database you will be using, it must be created earlier
    ‘username’ => ‘root’, // username that the script will use to connect, I strongly advice against using root user for this
    ‘password’ => », // password for the user above, it’s better not to use a blank one
    ‘charset’ => ‘utf8’, // encoding of the db
    ‘collation’ => ‘utf8_unicode_ci’, // db’s collation setting
    ‘prefix’ => », // prefix of the database tables, useful if you have multiple scripts using the same database
),

После того, как вы заполнили это, вы можете идти. Убедитесь, что вы сохранили файл и вызовите эту команду из основного каталога вашего приложения (тот, в котором находится файл artisan ):

Вот и все. Если ошибок не было, это означает, что таблицы были созданы успешно. Вы можете подключиться к вашей базе данных, используя, например, phpMyAdmin, чтобы проверить, хотите ли вы вручную.

В Laravel создание модели после того, как вы настроили базу данных с помощью миграций, действительно быстро. Перейдите в app/models и удалите пример файла User.php который там находится. Теперь создайте два файла с именами Customer.php и Transaction.php .

Давайте начнем с Customer.php . Каждая модель в Laravel должна расширять класс Eloquent :

1
class Customer extends Eloquent {

Теперь мы определим отношения между клиентом и его транзакциями. Это делается путем определения открытого метода в модели с именем свойства, которое мы хотели бы иметь в нем (в данном случае transactions ):

1
public function transactions() {

Теперь в теле функции будет только одна строка:

1
2
3
return $this->hasMany(‘Transaction’);
    }
}

Это говорит Eloquent, что он должен предоставлять все транзакции с customer_id клиента в свойстве с именем transactions .

Теперь мы будем делать то же самое для транзакций, но мы изменим отношение, чтобы сделать владельца транзакции доступным через свойство customer :

1
2
3
4
5
class Transaction extends Eloquent {
    public function customer() {
        return $this->belongsTo(‘Customer’);
    }
}

Это делается с помощью метода $this->belongsTo() модели.

Теперь, чтобы реально использовать модели, мы должны создать для них контроллеры. BaseController.php каталог app/controllers , удалите только HomeController.phpBaseController.php важен, поскольку наши контроллеры его расширят. Теперь создайте два файла: CustomerController.php и TransactionController.php .

Этот контроллер будет обрабатывать все, что связано с клиентами — добавление, удаление и показ их списка. Начните с определения класса:

1
class CustomerController extends BaseController {

Мы будем использовать функцию Laravel под названием RESTful-контроллеры. Это облегчает создание маршрутов, потому что нам нужно только определить базовый URI, и Laravel будет обрабатывать все за нас. Это требует, чтобы вы начинали имена своих функций с соответствующего HTTP-глагола, а затем продолжали с именем подчиненного маршрута (используя camelCase). Так, например, если бы у нас был метод с именем getNames а базовый URI был бы /customers getNames , тогда этот метод будет доступен в /customers/names .

getIndex() , postIndex() , deleteIndex() и т. Д. Будут сопоставлены с маршрутом по умолчанию (в данном случае для /customers ).

Теперь давайте определим наш первый маршрут — получение клиента по его идентификатору:

1
public function getIndex() {

Давайте получим идентификатор из параметров запроса (Laravel предоставляет хороший класс Input для решения этой $_FILES , поэтому вам не нужно использовать $_GET , $_POST и $_FILES ):

1
$id = Input::get(‘id’);

И искать пользователя в базе данных, используя этот идентификатор:

1
2
return Customer::find($id);
   }

Каждый метод контроллера должен возвращать значение, которое является строкой или имеет __toString() . В этом случае возвращаемая модель Customer будет преобразована в JSON перед отправкой.

Теперь давайте вернем список всех пользователей (это будет доступно в /customers/all ):

1
2
3
public function getAll() {
       return Customer::all();
   }

Как видите, мы можем получить всех клиентов, используя метод all() модели.

Теперь самая длинная часть, добавляющая нового клиента:

1
public function postIndex() {

Сначала давайте проверим, была ли предоставлена ​​вся необходимая информация. Мы можем сделать это используя метод Input::has() :

1
if (Input::has(‘first_name’, ‘last_name’, ’email’)) {

Давайте поместим все поля $input переменную $input чтобы избежать многократного вызова Input::get() . Это можно сделать с помощью Input::all() :

1
$input = Input::all();

Далее мы проверим, являются ли какие-либо из входов пустыми. Если это так, мы вернем ошибку HTTP 400 Bad Request с более подробным сообщением:

1
2
3
if ($input[‘first_name’] == » || $input[‘last_name’] == » || $input[’email’] == ») {
               return Response::make(‘You need to fill all of the input fields’, 400);
           }

Поскольку мы хотели вернуть код состояния, отличный от 200, а не просто возвращать сообщение в виде строки, мы использовали Response::make() , который принимает данные для отправки в качестве первого параметра, а код состояния — в качестве второго. Посмотрите документы, если вы хотите узнать больше об ответах.

Теперь мы наконец создаем новую модель Customer и добавляем в нее следующие данные:

1
2
3
4
$customer = new Customer;
           $customer->first_name = $input[‘first_name’];
           $customer->last_name = $input[‘last_name’];
           $customer->email = $input[’email’];

После этого мы можем сохранить вновь созданную модель и ответить ей на запрос:

1
2
3
$customer->save();
            
           return $customer;

Здесь мы обрабатываем случай, если не все входные данные были предоставлены:

1
2
3
4
} else {
           return Response::make(‘You need to fill all of the input fields’, 400);
       }
   }

Наконец, нам также нужна возможность удалять клиентов. Этот действительно короткий:

1
public function deleteIndex() {

Мы начинаем с получения идентификатора клиента для удаления:

1
$id = Input::get(‘id’);

Далее мы ищем и удаляем клиента:

1
2
$customer = Customer::find($id);
       $customer->delete();

После этого мы отвечаем на запрос с указанным идентификатором:

1
2
3
4
         
        return $id;
    }
}

Теперь, прежде чем можно будет получить доступ к маршрутам, мы должны подключить их. Откройте файл app/routes.php , удалите все, кроме комментария, и добавьте эту строку в конец файла:

1
Route::controller(‘/customers’, ‘CustomerController’);

Это скажет Laravel направить все запросы в /customers CustomerController к нашему CustomerController . Теперь вы можете использовать CURL для игры с ним. Сначала запустите сервер с помощью php artisan serve а затем вы можете, например, создать клиента:

Затем вы можете получить список всех клиентов:

Это, как и модель, очень похож на CustomerController . Сначала создайте класс:

1
class TransactionController extends BaseController {

Затем давайте определим метод для получения всех транзакций для пользователя:

1
2
3
4
public function getIndex() {
       $id = Input::get(‘id’);
       return User::find($id)->transactions;
   }

Как вы можете видеть, мы используем отношение, определенное ранее, для получения транзакций (теперь вспомните запрос, который вы должны были написать, чтобы добиться того же, используя обычный PHP и SQL).

Следующим будет создание транзакций:

1
public function postIndex() {

Как и ранее, мы проверяем, предоставлена ​​ли вся необходимая информация:

1
if (Input::has(‘name’, ‘amount’)) {

Если это так, присвойте его переменной $input :

1
$input = Input::all();

Проверьте, являются ли какие-либо из предоставленных значений пустыми, и если да, верните ошибку:

1
2
3
if ($input[‘name’] == » || $input[‘amount’] == ») {
               return Response::make(‘You need to fill all of the input fields’, 400);
           }

Теперь создайте транзакцию и предоставьте всю предоставленную информацию:

1
2
3
$transaction = new Transaction;
           $transaction->name = $input[‘name’];
           $transaction->amount = $input[‘amount’];

Теперь нам нужно добавить его к соответствующему клиенту. Давайте найдем их по предоставленному идентификатору и добавим $transaction в их список транзакций:

1
2
$id = $input[‘customer_id’];
           User::find($id)->transactions->save($transaction);

Это делается с помощью метода transactions->save() предоставленного Laravel. Теперь мы можем ответить созданной транзакцией:

1
return $transaction;

И обработать случай, когда не были предоставлены все или не все данные:

1
2
3
4
} else {
           return Response::make(‘You need to fill all of the input fields’, 400);
       }
   }

После этого также есть способ удалить транзакцию так же, как мы удалили клиента:

1
2
3
4
5
6
7
8
public function deleteIndex() {
        $id = Input::get(‘id’);
        $transaction = Transaction::find($id);
        $transaction->delete();
         
        return $id;
    }
}

Теперь просто добавьте маршрут, и вы можете проверить контроллер, используя CURL:

1
Route::controller(‘/transactions’, ‘TransactionController’);

Хорошо, это конец первой части — во второй части этого урока мы создадим внешний интерфейс с помощью AngularJS. Не стесняйтесь добавлять дополнительные функции в ваше приложение (например, редактирование клиентов или сортировку), если вы не нашли нужную информацию, ознакомьтесь с документацией Laravel .