Advertisement
  1. Code
  2. Yii

Cara Memprogram dengan Yii2: Validasi Khusus

Scroll to top
Read Time: 14 min
This post is part of a series called How to Program With Yii2.
How to Program With Yii2: Validations
How to Program With Yii2: AuthClient Integration With Twitter & Google

Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Jika Anda bertanya, "Apa itu Yii?" lihat tutorial saya sebelumnya: Perkenalan Kerangka Yii, yang mengulas manfaat Yii dan menyertakan gambaran tentang apa yang baru di Yii 2.0, yang dirilis pada Oktober 2014.

Dalam seri Pemrograman dengan Yii2 ini, saya membimbing pembaca untuk menggunakan Kerangka Yii2 yang baru ditingkatkan untuk PHP. Tutorial ini adalah bagian kedua kami, melihat validator Yii2. Validator menyederhanakan kode yang diperlukan untuk memvalidasi masukan, yaitu memverifikasi kesesuaian atau ketidaksesuaian masukan data, biasanya dari pengguna melalui formulir web. Secara khusus, kita akan menjelajahi beberapa validasi khusus bawaan yang umum untuk pengembangan web.

Berikut daftar validator Yii bawaan dan tautan ke dokumentasi yang akan kita jelajahi:

Saya akan memandu Anda melalui contoh masing-masing validasi ini menggunakan basis kode aplikasi Hello dari tutorial sebelumnya dan beberapa dari Seri Membangun Startup Anda yang juga menggunakan Yii2. Gunakan tautan GitHub di halaman ini untuk mendapatkan kodenya.

Sekadar mengingatkan, saya ikut dalam thread komentar di bawah ini. Saya tertarik jika Anda memiliki ide tambahan atau ingin menyarankan topik untuk tutorial selanjutnya. Anda juga dapat menghubungi saya @reifman di Twitter atau email saya di Lookahead Consulting.

Apa itu Validator?

Jika Anda seorang pengembang web, Anda mungkin tahu bahwa masukan pengguna tidak dapat dipercaya. Misalnya, pengguna dapat menggunakan teknik injeksi SQL untuk mencoba menjalankan kueri yang mengubah atau mengekspos kata sandi. Seseorang pernah memanfaatkan injeksi SQL terhadap instalasi PHPList sumber terbuka saya dan berhasil menemukan salah satu kata sandi saya (PHPList menyimpannya dalam teks biasa). Lebih umum, Anda hanya ingin memastikan bahwa data yang disediakan pengguna sesuai dengan jenis, bentuk dan rentang aplikasi Anda.

Membangun validator di PHP secara manual membutuhkan waktu. Kerangka Yii menyediakan banyak fitur validasi dasar sehingga tidak perlu membangunnya dari awal. Namun, jika Anda memerlukan beberapa ekstensi kustom, itu juga mudah.

Validasi adalah alasan lain mengapa saya pikir itu selalu masuk akal untuk membangun aplikasi pada kerangka web seperti Yii daripada PHP biasa.

Pada episode sebelumnya, kita juga telah berbicara banyak tentang generator kode Yii, Gii. Salah satu manfaat dari Gii adalah bahwa ia akan menulis aturan validasi yang sesuai untuk model Anda berdasarkan definisi tipe SQL dalam skema. Ini adalah penghemat waktu yang banyak.

Anda mungkin ingin kembali ke episode terakhir kami untuk membaca lebih lanjut tentang validasi tipe dasar Yii2.

Sekarang, mari kita mulai melihat set validator bawaan Yii2 berikutnya.

Set Validator Berikutnya

Validator Captcha

Mari kita mulai dengan CaptchaValidator yang memeriksa bahwa ada respon yang tepat untuk field verifikasi CAPTCHA. CAPTCHA membantu memastikan bahwa manusia mengisi formulir, mudah-mudahan menjaga skrip otomatis dari mengirimkannya.

Berikut ini contoh Yii Captcha beraksi:

Yii2 Validators CAPTCHA ValidatorYii2 Validators CAPTCHA ValidatorYii2 Validators CAPTCHA Validator

Yii2 Validators CAPTCHA ValidatorDalam basis kode Hello kita, saya telah menyederhanakan formulir sampel kita untuk hanya menyertakan field Thought and Captcha untuk saat ini. Berikut ini tampilan definisi aturan kode model:

1
class Sample extends \yii\db\ActiveRecord
2
{
3
    public $captcha;
4
    
5
    /**

6
     * @inheritdoc

7
     */
8
    public function rules()
9
    {
10
        return [
11
          [['thought'], 'string', 'max' => 255],
12
          [['thought'], 'trim'],
13
          [['thought'], 'required'],
14
          [['captcha'], 'captcha'],
15
        ];
16
    }

Captcha bukan bagian dari skema database kita—itu hanya digunakan untuk memverifikasi formulir. Oleh karena itu, saya menambahkan atribut ke model untuknya, mis. public $captcha;.

Berikut kode view untuk formulir. Kita harus menyertakan perpustakaan Captcha di bagian atas.

1
<?php
2
3
use yii\helpers\Html;
4
use yii\widgets\ActiveForm;
5
use yii\captcha\Captcha;
6
7
/* @var $this yii\web\View */
8
/* @var $model app\models\Sample */
9
/* @var $form yii\widgets\ActiveForm */
10
?>
11
12
<div class="sample-form">
13
14
    <?php $form = ActiveForm::begin(); ?>
15
    <?= $form->errorSummary($model); ?>    
16
17
    <?= $form->field($model, 'thought')->textInput(['maxlength' => 255]) ?>
18
19
    <?= $form->field($model, 'captcha')->widget(\yii\captcha\Captcha::classname(), [
20
        // configure additional widget properties here

21
    ]) ?>
22
    
23
    <div class="form-group">
24
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
25
    </div>
26
27
    <?php ActiveForm::end(); ?>
28
29
</div>

Inilah validasi Captcha dalam aksinya:

Yii2 Validators Sample CAPTCHA validation errorYii2 Validators Sample CAPTCHA validation errorYii2 Validators Sample CAPTCHA validation error

Jika Anda mengklik Captcha, Yii akan menghasilkan gambar baru.

Validator Perbandingan

Sekarang, mari kita lanjutkan ke CompareValidator. Validator ini membandingkan dua nilai dari bentuk atau nilai bentuk tunggal ke konstanta, seperti x harus kurang dari 99.

Untuk contoh ini, saya ingin memastikan bahwa masukan pengguna untuk peringkat lebih besar dari nol tetapi kurang dari atau sama dengan 100.

Pertama, saya akan menambahkan field masukan ke formulir kita untuk atribut peringkat:

1
<?php $form = ActiveForm::begin(); ?>
2
<?= $form->errorSummary($model); ?>    
3
4
<?= $form->field($model, 'thought')->textInput(['maxlength' => 255]) ?>
5
6
<?= $form->field($model, 'rank')->textInput() ?>
7
8
<?= $form->field($model, 'captcha')->widget(\yii\captcha\Captcha::classname(), [
9
    // configure additional widget properties here

10
]) ?>

Kemudian saya akan menambahkan dua aturan validasi perbandingan ke model kita:

1
    public function rules()
2
    {
3
        return [
4
          [['thought'], 'string', 'max' => 255],
5
          [['thought'], 'trim'],
6
          [['thought'], 'required'],
7
          [['captcha'], 'captcha'],
8
          [['rank'], 'integer'],
9
          ['rank', 'compare', 'compareValue' => 0, 'operator' => '>'],
10
          ['rank', 'compare', 'compareValue' => 100, 'operator' => '<='],
11
        ];
12
    }

Anda dapat melihat daftar lengkap operator perbandingan yang tersedia di sini.

Inilah formulir kita ketika pengguna mengirimkan atribut yang tidak valid:

Yii2 Validators CompareYii2 Validators CompareYii2 Validators Compare

Yii2 Validators CompareJika kita ingin memberikan aturan kendala spesifik dalam satu pesan kesalahan, Yii Validators memungkinkan Anda untuk menyesuaikan kesalahan yang ditampilkan kepada pengguna, seperti ini:

Yii2 Validators The Compare validator with custom error messageYii2 Validators The Compare validator with custom error messageYii2 Validators The Compare validator with custom error message

Yii2 Validators The Compare validator with custom error messageMenerapkan ini cukup sederhana dengan penambahan atribut message:

1
public function rules()
2
    {
3
        return [
4
          [['thought'], 'string', 'max' => 255],
5
          [['thought'], 'trim'],
6
          [['thought'], 'required'],
7
          [['captcha'], 'captcha'],
8
          [['rank'], 'integer'],
9
          ['rank', 'compare', 'compareValue' => 0, 'operator' => '>','message'=>Yii::t('app','Rank must be between 0 and 100 inclusive.')],
10
          ['rank', 'compare', 'compareValue' => 100, 'operator' => '<=','message'=>Yii::t('app','Rank must be between 0 and 100 inclusive.')],
11
        ];
12
    }

Memperbarui Skema Kita untuk Menguji Lebih Banyak Validasi

Untuk beberapa pengujian validasi berikutnya, saya akan meminta Anda untuk menambahkan beberapa kolom ke database.

Dalam \migrations\m150219_235923_create_sample_table.php, kita akan menambahkan beberapa field baru untuk menguji rangkaian validator berikutnya: email, URL, filename, dll.

1
$this->createTable('{{%sample}}', [
2
              'id' => Schema::TYPE_PK,
3
              'thought' => Schema::TYPE_STRING.' NOT NULL DEFAULT ""',
4
              'goodness' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0',
5
              'rank' => Schema::TYPE_INTEGER . ' NOT NULL',
6
              'censorship' => Schema::TYPE_STRING . ' NOT NULL',
7
              'occurred' => Schema::TYPE_DATE . ' NOT NULL',
8
              'email' => Schema::TYPE_STRING . ' NOT NULL DEFAULT ""',
9
              'url' => Schema::TYPE_STRING . ' NOT NULL DEFAULT ""',
10
              'filename' => Schema::TYPE_STRING.' NOT NULL',
11
              'avatar' => Schema::TYPE_STRING.' NOT NULL',
12
          ], $tableOptions);  

Kemudian jalankan migrasi turun untuk drop tabel dan kemudian naik:

1
Admins-MBP:hello Jeff$ ./yii migrate/down 1
2
Yii Migration Tool (based on Yii v2.0.2)
3
4
Total 1 migration to be reverted:
5
    m150219_235923_create_sample_table
6
7
Revert the above migration? (yes|no) [no]:yes
8
*** reverting m150219_235923_create_sample_table
9
    > drop table {{%sample}} ... done (time: 0.002s)
10
*** reverted m150219_235923_create_sample_table (time: 0.005s)
11
12
Migrated down successfully.
13
Admins-MBP:hello Jeff$ ./yii migrate/up 1
14
Yii Migration Tool (based on Yii v2.0.2)
15
16
Total 1 new migration to be applied:
17
  m150219_235923_create_sample_table
18
19
Apply the above migration? (yes|no) [no]:yes
20
*** applying m150219_235923_create_sample_table
21
    > create table {{%sample}} ... done (time: 0.007s)
22
*** applied m150219_235923_create_sample_table (time: 0.010s)
23
24
Migrated up successfully.

Kita sekarang siap menguji validator email dan URL.

Validator Email & URL

EmailValidator memastikan nilai adalah alamat email yang valid dan UrlValidator memastikan nilai dalam format URL, mis. http://yourdomain.com.

Ini cukup mudah untuk membuat aturan untuk field email dan URL baru kita:

1
    public function rules()
2
    {
3
        return [
4
          [['thought'], 'string', 'max' => 255],
5
          [['email'], 'email'],
6
          [['url'], 'url'],

Berikut kode view untuk formulir. Perhatikan bagaimana saya menggunakan label kustom untuk meningkatkan kegunaan formulir:

1
<div class="sample-form">
2
3
    <?php $form = ActiveForm::begin(); ?>
4
    <?= $form->errorSummary($model); ?>    
5
6
    <?= $form->field($model, 'thought')->textInput(['maxlength' => 255]) ?>
7
8
    <?= $form->field($model, 'email')->textInput()->label(Yii::t('app','Your email address')) ?>
9
10
    <?= $form->field($model, 'url')->textInput()->label(Yii::t('app','Your website')) ?>

Berikut adalah validator dalam aksinya:

Yii2 Validators The Email and URL ValidatorsYii2 Validators The Email and URL ValidatorsYii2 Validators The Email and URL Validators

Ini jelas sangat berguna untuk aplikasi web.

Validator Eksistensi

ExistValidator sangat berguna dalam skenario tertentu. Ini dapat memastikan bahwa nilai ada di tabel lain. Dan itu dapat digunakan dalam berbagai cara—berikut beberapa contoh yang diberikan dalam dokumentasinya:

1
// a1 needs to exist

2
['a1', 'exist']
3
// a1 needs to exist, but its value will use a2 to check for the existence

4
['a1', 'exist', 'targetAttribute' => 'a2']
5
// a1 and a2 need to exist together, and they both will receive error message

6
[['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']]
7
// a1 and a2 need to exist together, only a1 will receive error message

8
['a1', 'exist', 'targetAttribute' => ['a1', 'a2']]
9
// a1 needs to exist by checking the existence of both a2 and a3 (using a1 value)

10
['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']]

Dokumentasi Yii menyoroti bahwa Exist dapat digunakan untuk "memverifikasi bahwa foreign key mengandung nilai yang dapat ditemukan di tabel asing."

Untuk contoh kita, saya akan membuat aturan yang memeriksa bahwa alamat email dalam formulir sudah ada di tabel User terdaftar kita. Untuk melakukan ini, kita menggunakan targetClass yang memberi tahu Yii mana Kelas (atau tabel Model) untuk mencari alamat email pengguna untuk divalidasi.

Berikut definisi aturan—perhatikan penyertaan model User kita di bagian atas:

1
<?php
2
3
namespace app\models;
4
5
use Yii;
6
use yii\models\User;
7
8
/**

9
 * This is the model class for table "sample".

10
 *

11
 * @property integer $id

12
 * @property string $thought

13
 * @property integer $goodness

14
 * @property integer $rank

15
 * @property string $censorship

16
 * @property string $occurred

17
 */
18
class Sample extends \yii\db\ActiveRecord
19
{
20
    public $captcha;
21
    
22
    /**

23
     * @inheritdoc

24
     */
25
    public function rules()
26
    {
27
        return [
28
          [['thought'], 'string', 'max' => 255],
29
          [['email'], 'email'],
30
          [['email'], 'exist','targetClass'=>'\app\models\User','message'=>Yii::t('app','Sorry, that person hasn\'t registered yet')],
31
          [['url'], 'url'],

Itu menginstruksikan Yii agar melakukan kueri tabel User untuk memastikan bahwa alamat email yang diberikan cocok dengan pengguna yang terdaftar sebelumnya.

Inilah yang terlihat seperti dalam aksinya:

Yii2 Validators Exist with Email LookupYii2 Validators Exist with Email LookupYii2 Validators Exist with Email Lookup

Anda dapat mempelajari lebih lanjut tentang validasi Exist dan permutasinya di sini.

Validator File dan Gambar

Selanjutnya, saya akan menunjukkan kepada Anda contoh FileValidator, yang memastikan keberadaan, jenis MIME dan ukuran file yang diunggah, dan ImageValidator, yang memvalidasi gambar dan propertinya.

Untuk menjelajahi validator File dan Gambar, mari kita lihat contoh dari Serial Membangun Startup Anda dengan PHP: Pengaturan Pengguna, Gambar Profil, dan Rincian Kontak. Di episode itu dalam model UserSettings, kita mengizinkan pengguna untuk mengunggah file untuk gambar profil mereka.

Atribut gambar menerima file yang diunggah:

1
    public function rules()
2
    {
3
        return [
4
            [['user_id', ], 'required'],
5
            [['user_id', ], 'unique'],
6
            [['image'], 'safe'],
7
            [['image'], 'file', 'extensions'=>'jpg, gif, png'],
8
            [['image'], 'file', 'maxSize'=>'100000'],
9
            ['image', 'image', 'extensions' => 'png, jpg, gif',
10
                    'minWidth' => 100, 'maxWidth' => 400,
11
                    'minHeight' => 100, 'maxHeight' => 400,
12
                ],

FileValidators memastikan bahwa gambar berakhir dengan ekstensi gambar yang tepat dan kurang dari 100.000 byte.

ImageValidator juga memverifikasi jenis ekstensi serta rentang lebar dan tinggi untuk gambar.

Berikut contoh kesalahan yang dihasilkan dengan mengunggah gambar yang dimensinya lebih besar dari 400 x 400 piksel:

Yii2 Validators Image and File ValidationYii2 Validators Image and File ValidationYii2 Validators Image and File Validation

Yii2 Validators Image and File ValidationItu asisten saya di atas yang suka menyalin tutorial saya.

Rentang dalam Validator

Ada juga RangeValidator yang memastikan nilai ada dalam daftar entri yang diperbolehkan.

Untuk contoh kita, mari tambahkan bidang untuk penyensoran kembali ke dalam formulir:

1
<div class="sample-form">
2
3
    <?php $form = ActiveForm::begin(); ?>
4
    <?= $form->errorSummary($model); ?>    
5
6
    <?= $form->field($model, 'thought')->textInput(['maxlength' => 255]) ?>
7
8
    <?= $form->field($model, 'email')->textInput()->label(Yii::t('app','Your email address')) ?>
9
10
    <?= $form->field($model, 'url')->textInput()->label(Yii::t('app','Your website')) ?>
11
12
    <?= $form->field($model, 'censorship')->textInput() ?>
13
    
14
    <?= $form->field($model, 'rank')->textInput() ?>
15
16
    <?= $form->field($model, 'captcha')->widget(\yii\captcha\Captcha::classname(), [
17
        // configure additional widget properties here

18
    ]) ?>

Kemudian, kita akan menambahkan RangeValidator untuk mencocokkan respons dengan string yes atau no:

1
    public function rules()
2
    {
3
        return [
4
          [['thought'], 'string', 'max' => 255],
5
          ['thought', 'match', 'pattern' => '/^[a-z][A-Za-z,;\"\\s]+[!?.]$/i','message'=>Yii::t('app','Your thoughts should form a complete sentence of alphabetic characters.')],
6
          [['email'], 'email'],
7
          [['email'], 'exist','targetClass'=>'\app\models\User','message'=>Yii::t('app','Sorry, that person hasn\'t registered yet')],
8
          [['url'], 'url'],
9
          ['censorship', 'in', 'range' => ['yes','no','Yes','No'],'message'=>Yii::t('app','The censors demand a yes or no answer.')],

Berikut contoh aksi RangeValidator:

Yii2 Validators Range In ValidatorYii2 Validators Range In ValidatorYii2 Validators Range In Validator

Validator Kecocokan Regular Expression

Selanjutnya, mari kita lihat RegularExpressionValidator, yang melakukan validasi terhadap kondisi yang ditentukan oleh regular expression.

Dalam contoh kita, saya menggunakan regex berikut untuk mencocokkan kalimat lengkap dengan karakter alfabet. Ini berarti mereka harus diakhiri dengan salah satu (!, ? atau .) dan tidak memiliki karakter numerik.

1
    public function rules()
2
    {
3
        return [
4
          [['thought'], 'string', 'max' => 255],
5
          ['thought', 'match', 'pattern' => '/^[a-z][A-Za-z,;\"\\s]+[!?.]$/i','message'=>Yii::t('app','Your thoughts should form a complete sentence of alphabetic characters.')],

Berikut ini contoh masukan pengguna yang gagal pengujian karena angka dan kurangnya tanda baca di belakang:

Yii2 Validator Regular Expression Match FailureYii2 Validator Regular Expression Match FailureYii2 Validator Regular Expression Match Failure

Berikut kalimat yang valid:

Yii2 Validator Regular Expression Match SuccessYii2 Validator Regular Expression Match SuccessYii2 Validator Regular Expression Match Success

Anda mungkin juga tertarik dengan Delapan Regular Expression yang Harus Anda Ketahui (Tuts+) sebagai referensi untuk pola umum regex.

Validator Unik

Akhirnya, mari kita tinjau UniqueValidator, yang memastikan bahwa nilai unik dalam tabel, seperti alamat email atau slug.

Saya meninjau SluggableBehavior sebelumnya dalam seri ini, yang menawarkan dukungan keunikan bawaan. Namun, mari kita lihat beberapa contoh lain dari serial Membangun Startup Anda dengan PHP.

Dalam basis kode untuk Meeting Planner (dari episode tutorial yang lebih baru) di model Place (\frontend\models\Place.php), kami menggunakan validator unik dalam beberapa cara:

1
public function rules()
2
     {
3
         return [
4
             [['name','slug'], 'required'],
5
             [['place_type', 'status', 'created_by', 'created_at', 'updated_at'], 'integer'],
6
             [['name', 'google_place_id', 'slug', 'website', 'full_address', 'vicinity'], 'string', 'max' => 255],
7
             [['website'], 'url'],
8
             [['slug'], 'unique'],
9
             [['searchbox'], 'unique','targetAttribute' => 'google_place_id'],             
10
             [['name', 'full_address'], 'unique', 'targetAttribute' => ['name', 'full_address']],
11
         ];
12
     }

Pertama, kami menggunakan aturan unik dengan slug untuk menambah SluggableBehavior, yang berlebihan; tetapi Anda dapat melihat format validasinya.

Kedua, kita memeriksa bahwa hasil kotak pencarian Google Places Autocomplete menghasilkan bidang tersembunyi untuk google_place_id yang unik karena belum ada dalam tabel Places. Kami pada dasarnya mencegah duplikat ID Google Place.

Bagian penting dari ini adalah validator unik Yii2 yang memungkinkan kita untuk menerapkan keunikan pada bidang yang terlihat (searchbox) ketika memvalidasi pada kolom sekunder yang dikembalikan melalui AJAX dari Google (google_place_id).

Ketiga, kita memastikan bahwa name dan full_address sama-sama unik. Dengan kata lain, nama tempat duplikat adalah baik-baik saja. Mungkin ada sangat banyak Starbucks. Namun, kita tidak ingin siapa pun memasuki lokasi Starbucks yang sama dua kali.

Catatan: Kopi Starbucks bukan stimulan yang efektif untuk pengembang perangkat lunak. Saya mendorong Anda untuk sering kedai kopi yang independen.

Berikut ini contohnya dalam aksi:

Yii2 Validators UniqueYii2 Validators UniqueYii2 Validators Unique

Apa berikutnya?

Saya harap Anda setuju bagaimana validasi Yii2 yang sederhana dan berguna untuk pengembangan web. Saya tidak bisa membayangkan pernah kembali ke pengembangan PHP vanilla tanpa bantuan kerangka kerja.

Tonton tutorial yang akan datang dalam seri Pemrograman dengan Yii2 saya karena saya terus menyelam ke dalam berbagai aspek kerangka kerjanya. Di episode berikutnya, saya akan meninjau fitur validasi lanjutan Yii2 seperti:

  • Validasi bersyarat untuk melakukan aturan validasi hanya jika peristiwa tertentu adalah true
  • Validator kustom untuk membuat validasi penting di luar apa yang Yii tawarkan di luar kotak
  • Validasi sisi klien untuk menggunakan validasi ActiveForm JavaScript bawaan Yii tanpa memerlukan penyegaran halaman
  • Validasi AJAX untuk menerapkan validasi AJAX sisi server untuk memperluas kemampuan validasi halaman JavaScript sisi klien Yii.
  • Event validasi untuk menggantikan validasi atau melakukan fungsi tertentu sebelum dan/atau setelah validasi
  • Menentukan skenario untuk secara selektif menerapkan aturan untuk situasi tertentu
  • Validasi Ad Hoc untuk menggunakan aturan validasi secara independen dari pengiriman formulir

Saya menyambut permintaan fitur dan topik. Anda dapat mempostingnya di komentar di bawah, hubungi saya @reifman di Twitter, atau email saya di Lookahead Consulting.

Jika Anda ingin tahu kapan tutorial Yii2 berikutnya tiba, Anda juga dapat memeriksa halaman instruktur Tuts+ saya. Ini selalu menyertakan tautan ke artikel saya segera setelah diterbitkan.

Tautan Terkait

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.