Installation:
composer require ekyna/news-bundle
Add to config/app.php under extra.bundles:
Ekyna\NewsBundle\EkynaNewsBundle::class
Database Migration:
Run migrations (if provided in the bundle). Check vendor/ekyna/news-bundle/Resources/config/doctrine for News.orm.xml or News.php entity definitions. If missing, manually create a news table:
php artisan make:migration create_news_table
Example schema:
Schema::create('news', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content')->nullable();
$table->boolean('is_published')->default(false);
$table->timestamps();
});
First Use Case: Create a controller to fetch and display news:
use Ekyna\NewsBundle\Entity\News;
use Ekyna\NewsBundle\Repository\NewsRepository;
class NewsController extends Controller
{
public function index(NewsRepository $newsRepo)
{
$news = $newsRepo->findBy(['is_published' => true]);
return view('news.index', compact('news'));
}
}
Routing:
Add routes in routes/web.php:
use Ekyna\NewsBundle\Controller\NewsController;
Route::get('/news', [NewsController::class, 'index']);
CRUD Operations:
Use the NewsRepository for database interactions:
// Create
$news = new News();
$news->setTitle('Breaking News');
$news->setContent('Content here...');
$news->setPublished(true);
$entityManager->persist($news);
$entityManager->flush();
// Read
$newsRepo->findAll(); // All news
$newsRepo->findBy(['is_published' => true]); // Published only
// Update
$news = $newsRepo->find($id);
$news->setTitle('Updated Title');
$entityManager->flush();
// Delete
$newsRepo->remove($news, true);
Integration with Forms:
Use Symfony’s FormBuilder to create a news submission form:
use Ekyna\NewsBundle\Form\NewsType; // If provided; otherwise, create manually
$form = $this->createForm(NewsType::class, $news);
Displaying News in Views: Loop through published news in Blade:
@foreach($news as $item)
<article>
<h2>{{ $item->getTitle() }}</h2>
<p>{{ $item->getContent() }}</p>
<small>Published: {{ $item->getCreatedAt()->format('M d, Y') }}</small>
</article>
@endforeach
API Endpoints:
Use Symfony’s JsonResponse for RESTful APIs:
public function apiNews(NewsRepository $newsRepo)
{
$news = $newsRepo->findBy(['is_published' => true]);
return new JsonResponse($news);
}
Event Listeners:
Attach listeners to news lifecycle events (e.g., prePersist, preUpdate). Example:
// In a service or listener class
public function onNewsPublish(News $news)
{
// Send notification, log, etc.
}
Register in services.yaml:
services:
App\EventListener\NewsListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
Custom Queries:
Extend NewsRepository to add custom methods:
namespace App\Repository;
use Ekyna\NewsBundle\Repository\NewsRepository as BaseNewsRepository;
class NewsRepository extends BaseNewsRepository
{
public function findPublishedByCategory($category)
{
return $this->createQueryBuilder('n')
->where('n.category = :category')
->andWhere('n.is_published = :published')
->setParameter('category', $category)
->setParameter('published', true)
->getQuery()
->getResult();
}
}
Caching: Cache frequently accessed news to improve performance:
use Symfony\Contracts\Cache\CacheInterface;
public function getCachedNews(CacheInterface $cache, NewsRepository $newsRepo)
{
return $cache->get('published_news', function () use ($newsRepo) {
return $newsRepo->findBy(['is_published' => true]);
}, 3600); // Cache for 1 hour
}
Missing Documentation:
README or detailed documentation. Expect to reverse-engineer from Entity classes and tests (if any).vendor/ekyna/news-bundle/src/Entity/News.php and vendor/ekyna/news-bundle/src/Repository/NewsRepository.php for defaults and methods.Outdated Code:
NewsRepository) to adapt to newer Doctrine/Symfony versions.No Built-in Admin:
News.Missing Form Types:
FormType classes for News.NewsType:
namespace App\Form;
use Ekyna\NewsBundle\Entity\News;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class NewsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('content', TextareaType::class)
->add('is_published', CheckboxType::class);
}
}
No Soft Deletes:
deleted_at column and use Laravel Soft Deletes or Doctrine lifecycle callbacks.Check Entity Metadata:
If fields are missing or methods undefined, verify the News entity:
php bin/console doctrine:schema:update --dump-sql
Or inspect the entity with:
$reflection = new ReflectionClass(Ekyna\NewsBundle\Entity\News::class);
print_r($reflection->getProperties());
Query Debugging:
Enable Doctrine debugging in .env:
APP_DEBUG=true
Or use:
$query = $newsRepo->createQueryBuilder('n');
dump($query->getQuery()->getSQL()); // Show raw SQL
Event Debugging:
If events (e.g., prePersist) aren’t firing, verify listeners are registered:
php bin/console debug:event-dispatcher
Custom Fields:
Extend the News entity to add fields (e.g., category, author):
namespace App\Entity;
use Ekyna\NewsBundle\Entity\News as BaseNews;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class News extends BaseNews
{
#[ORM\Column(type: 'string', length: 255)]
private $category;
// Getters/setters...
}
Validation:
Add validation rules to the NewsType or entity:
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
class News extends BaseNews
{
#[Assert\NotBlank]
#[Assert\Length(max: 255)]
private $title;
}
API Resources: Use API Platform or Laravel Transformers to shape API responses:
use App\Transformers\NewsTransformer;
return Fractal::item($news, new NewsTransformer)->toArray();
Testing: Write feature tests for news CRUD:
public function testNewsCreation()
How can I help you explore Laravel packages today?