├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── src ├── app │ ├── Contracts │ │ └── GJobContract.php │ ├── Exceptions │ │ ├── FieldsValidationException.php │ │ └── WrongParameterException.php │ ├── Facades │ │ └── GJob.php │ ├── GJob.php │ ├── Providers │ │ └── LaravelGoogleJobsServiceProvider.php │ └── Validator.php └── resources │ └── config │ └── laravelgooglejobs.php └── tests ├── BaseTest.php └── app ├── ExampleTest.php └── GJobsTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | # Spaces in coffee 13 | [**.coffee] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | [**.js] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | # Tabs in less 22 | [**.less] 23 | indent_style = tab 24 | indent_size = 2 25 | 26 | [**.css] 27 | indent_style = tab 28 | indent_size = 2 29 | 30 | [**.php] 31 | indent_style = space 32 | indent_size = 4 33 | 34 | [**.html] 35 | indent_style = tab 36 | indent_size = 2 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | /composer.lock 19 | 20 | # composer itself is not needed 21 | composer.phar 22 | 23 | # Mac DS_Store Files 24 | .DS_Store 25 | 26 | # phpunit itself is not needed 27 | phpunit.phar 28 | # local phpunit config 29 | /phpunit.xml 30 | # phpunit cache 31 | .phpunit.result.cache 32 | 33 | # build files 34 | build/ 35 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # .travis.yml 2 | dist: bionic 3 | 4 | language: php 5 | 6 | php: 7 | - 7.2 8 | 9 | cache: 10 | directories: 11 | - node_modules 12 | - vendor 13 | 14 | before_script: 15 | - composer self-update 16 | - composer install --no-interaction 17 | 18 | script: 19 | - vendor/bin/phpunit tests/app 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Light-it Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Google Job Posting Metadata Generator 2 | [![Build Status](https://travis-ci.com/Light-it-labs/laravel-google-jobs.svg?branch=master)](https://travis-ci.com/Light-it-labs/laravel-google-jobs) 3 | 4 | This package allows you to generate the required metadata for Google Jobs Announcements in a easy and Laravel way. 5 | 6 | ## Installation 7 | You can install this package via composer 8 | `composer require lightit/laravel-google-jobs` 9 | 10 | The service provider will be auto discovered and then automatically added to your providers array. 11 | 12 | ## Usage 13 | Laravel Google Jobs provides two different ways of json generation: 14 | 15 | 1) You can use the `GJob` facade available at: 16 | `Lightit\LaravelGoogleJobs\Facades` namespace 17 | 18 | 2) You can use Laravel's dependency injection system. From your class constructor, inject the `GJobContract`. This will return a singleton instance 19 | of `Lightit\LaravelGoogleJobs\GJob` class. 20 | 21 | ```php 22 | use Lightit\LaravelGoogleJobs\Contracts\GJobContract; 23 | 24 | class JobOfferController extends Controller 25 | { 26 | /* @var GjobContract */ 27 | private $gjob; 28 | 29 | public function __construct(GJobContract $gjob) 30 | { 31 | // $this->gjob is now a GJob class singleton instance 32 | $this->gjob = $gjob; 33 | } 34 | 35 | } 36 | ``` 37 | 38 | ## Available API 39 | Google Job Posting allows a specific set of fields for your jobs. Check: https://developers.google.com/search/docs/data-types/job-posting for more information. 40 | 41 | Some of these fields are required, and others are optional. This package will help you through the 42 | process of generating and validating all this data properly, so you don't have to care about the formatting or the definitions of the JSON. 43 | 44 | #### Methods 45 | `$this->gjob->fields(array $parameters): GJob` 46 | 47 | This method adds all `array $parameters` into your current instance and performs data validations. 48 | If one of the required parameters is missing from the array a`Lightit\LaravelGoogleJobs\Exceptions\FieldsValidationsException` will be thrown specifying the missing required fields. 49 | 50 | ----- 51 | 52 | `$this->gjob->withOptionals(array $parameters): GJob` 53 | 54 | As the name says, this method adds all `array $parameters` into your current instance, performing data validations. Only format validations are performed over these fields. 55 | 56 | 57 | ----- 58 | 59 | `$this->gjob->generate(): string` 60 | 61 | Generates the proper JSON format and validates all the instance parameters. 62 | 63 | ## Example 64 | ```php 65 | public function show(Request $request, $id) 66 | { 67 | // Lets say we want to allow google to render our job offer 68 | 69 | // Cool! Is time to do some magic with this package, we are going to use the Facade for this example 70 | // All You have to do is create an array like this one. 71 | // We strongly recomend the use of a model accessor in order to avoid duplicated code and provide one single source of truth for your job offer array representation 72 | $jobArray = [ 73 | 'datePosted' => '...', 74 | 'text' => '...', 75 | 'hiringOrganization' => [ 76 | '@type' => '...', 77 | 'name' => '...', 78 | 'sameAs' => '...', 79 | 'logo' => '...' 80 | ], 81 | 'jobLocation' => [ 82 | '@type' => '...', 83 | 'streetAddress'=> '...', 84 | 'addressLocality'=> '...', 85 | 'addressRegion'=> '...', 86 | 'postalCode'=> '...', 87 | 'addressCountry'=> '...' 88 | ], 89 | 'title' => '...', 90 | 'validThrough' => '...' 91 | ]; 92 | 93 | // Add your array into the singleton instance 94 | GJob::fields($jobArray); 95 | 96 | return view('details'); 97 | } 98 | ``` 99 | 100 | Now, all you have to do is call to the `generate()` method directly on your view before you close the `` tag 101 | 102 | ```php 103 | . 104 | . 105 | . 106 | . 107 | 108 |

I'm the best job offer ever!

109 | 110 | 113 | 114 | 115 | ``` 116 | 117 | And voila! A beautiful and fully compatible JSON is rendered for you. 118 | 119 | ## About Lightit 120 | [Light-it](https://lightit.io) is a digital product development studio with offices in the US, Uruguay and Paraguay. 121 | 122 | 123 | 124 | ## License 125 | This project and the Laravel framework are open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). 126 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lightit/laravel-google-jobs", 3 | "description": "Google Job Posting integration for Laravel", 4 | "keywords": [ 5 | "google-job-posting", 6 | "google-jobs", 7 | "laravel-google-jobs", 8 | "laravel-google-job-posting", 9 | "laravel" 10 | ], 11 | "type": "library", 12 | "license": "MIT", 13 | "require": { 14 | "php": "^8.0", 15 | "ext-json": "*", 16 | "illuminate/support": "5.8.*|^6.0|^7.0|^8.0|^9.0|^10.0" 17 | }, 18 | "require-dev": { 19 | "orchestra/testbench": "~3.8.4|^4.0", 20 | "phpspec/phpspec": "^6.1.1" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Lightit\\LaravelGoogleJobs\\": "src/app" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Lightit\\LaravelGoogleJobs\\Tests\\": "tests" 30 | } 31 | }, 32 | "extra": { 33 | "laravel": { 34 | "providers": [ 35 | "Lightit\\LaravelGoogleJobs\\Providers\\LaravelGoogleJobsServiceProvider" 36 | ], 37 | "aliases": { 38 | "GJob": "Lightit\\LaravelGoogleJobs\\Facades\\GJob" 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/app/Contracts/GJobContract.php: -------------------------------------------------------------------------------- 1 | validator = $validator; 38 | $this->requiredFields = []; 39 | $this->optionalFields = []; 40 | } 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | public function fields(array $parameters): GJob 46 | { 47 | // Set default parameters 48 | $parameters['@context'] = self::CONTEXT; 49 | $parameters['@type'] = self::JOB_POSTING_TYPE; 50 | 51 | $this->requiredFields = $parameters; 52 | 53 | return $this; 54 | } 55 | 56 | /** 57 | * @inheritDoc 58 | */ 59 | public function withOptionals(array $parameters): GJob 60 | { 61 | $this->optionalFields = $parameters; 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * @inheritDoc 68 | * @throws FieldsValidationException 69 | * @throws Exceptions\WrongParameterException 70 | */ 71 | public function generate(): string 72 | { 73 | $googleJobData = array_merge($this->requiredFields, $this->optionalFields); 74 | $validator = $this->validator->make($googleJobData); 75 | 76 | if($validator->fails()) { 77 | throw new FieldsValidationException($validator->errors()); 78 | } 79 | 80 | return json_encode($googleJobData); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/app/Providers/LaravelGoogleJobsServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton(GJobContract::class, function($app) { 20 | return new GJob(new Validator()); 21 | }); 22 | } 23 | 24 | /** 25 | * Bootstrap services. 26 | * 27 | * @return void 28 | */ 29 | public function boot() 30 | { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/app/Validator.php: -------------------------------------------------------------------------------- 1 | 'required', 26 | '@type' => 'required', 27 | 'datePosted' => 'required|date', 28 | 'hiringOrganization' => 'required|array', 29 | 'jobLocation' => 'required|array', 30 | 'title' => 'required|string', 31 | 'validThrough' => 'required|date', 32 | 'description' => 'nullable', 33 | 'baseSalary' => 'nullable', 34 | 'employmentType' => 'nullable' 35 | ]; 36 | } 37 | 38 | /** 39 | * @param array $dataToValidate 40 | * @return \Illuminate\Contracts\Validation\Validator 41 | * @throws WrongParameterException 42 | */ 43 | public function make(array $dataToValidate): \Illuminate\Contracts\Validation\Validator 44 | { 45 | // Check if $dataToValidate have only Google Job Announcements compatible keys 46 | foreach($dataToValidate as $key => $value) { 47 | if(! isset($this->rules()[$key])) { 48 | throw new WrongParameterException($key); 49 | } 50 | } 51 | 52 | return \Illuminate\Support\Facades\Validator::make($dataToValidate, $this->rules()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/resources/config/laravelgooglejobs.php: -------------------------------------------------------------------------------- 1 | '2016-02-18', 27 | 'hiringOrganization' => [ 28 | '@type' => 'Organization', 29 | 'name' => 'Test company', 30 | 'sameAs' => 'https://google.com', 31 | 'logo' => 'https://google.com' 32 | ], 33 | 'jobLocation' => [ 34 | '@type' => 'Place', 35 | 'streetAddress'=> '555 Clancy St', 36 | 'addressLocality'=> 'Detroit', 37 | 'addressRegion'=> 'MI', 38 | 'postalCode'=> '48201', 39 | 'addressCountry'=> 'US' 40 | ], 41 | 'title' => 'Software Engineer', 42 | 'validThrough' => '2017-03-18T00:00' 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/app/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(2, $total); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/app/GJobsTest.php: -------------------------------------------------------------------------------- 1 | gJob = $this->app->make(GJob::class); 21 | } 22 | 23 | /** @test 24 | * @throws FieldsValidationException 25 | */ 26 | public function test_generate() 27 | { 28 | // Given 29 | $jobArray = $this->basicJobOffer(); 30 | 31 | $gJobObject = $this->gJob->fields($jobArray); 32 | 33 | // Performing 34 | $result = $gJobObject->generate(); 35 | // Add @context and @type attributes to confirm if default insertion is working properly 36 | $jobArray['@context'] = GJob::CONTEXT; 37 | $jobArray['@type'] = GJob::JOB_POSTING_TYPE; 38 | 39 | // Expect 40 | $this->assertEquals($result, json_encode($jobArray)); 41 | 42 | // Check if the default values are added 43 | $this->assertArrayHasKey('@context', json_decode($result, true)); 44 | $this->assertArrayHasKey('@type', json_decode($result, true)); 45 | } 46 | 47 | /** 48 | * @throws FieldsValidationException 49 | */ 50 | public function test_misspelled_or_not_existing_fields_throws_an_exception() 51 | { 52 | $this->expectException(WrongParameterException::class); 53 | 54 | // Given 55 | $jobArray = $this->basicJobOffer(); 56 | $jobArray['notValidKey'] = 'not valid value'; 57 | 58 | $gJobObject = $this->gJob->fields($jobArray); 59 | 60 | // Performing 61 | $result = $gJobObject->generate(); // Should throw WrongParameterException 62 | } 63 | } 64 | --------------------------------------------------------------------------------