---
title: "European B2B Search Engine for Promotional Products (European Sourcing)"
description: "B2B search engine acting as an online tradeshow for European promotional products resellers - a precursor to today's marketplaces."
locale: "en"
canonical: "https://portfolio.josedacosta.info/en/achievements/moteur-de-recherche-europeen-b2b-objets-publicitaires"
source: "https://portfolio.josedacosta.info/en/achievements/moteur-de-recherche-europeen-b2b-objets-publicitaires.md"
html_source: "https://portfolio.josedacosta.info/en/achievements/moteur-de-recherche-europeen-b2b-objets-publicitaires"
author: "José DA COSTA"
date: "2010"
type: "achievement"
slug: "moteur-de-recherche-europeen-b2b-objets-publicitaires"
tags: ["PHP 5.x", "Symfony 2/3", "MySQL", "Elasticsearch", "AngularJS", "Propel/Doctrine ORM", "Memcache", "RabbitMQ", "Apache", "Proxmox VE", "AWS SES", "PhoneGap/Cordova"]
generated_at: "2026-04-23T15:47:53.976Z"
---

# European B2B Search Engine for Promotional Products (European Sourcing)

B2B search engine acting as an online tradeshow for European promotional products resellers - a precursor to today's marketplaces.

**Date:** 2010 - 2016  
**Duration:** ~6 years  
**Role:** Software Engineer then Senior Software Engineer  
**Technologies:** PHP 5.x, Symfony 2/3, MySQL, Elasticsearch, AngularJS, Propel/Doctrine ORM, Memcache, RabbitMQ, Apache, Proxmox VE, AWS SES, PhoneGap/Cordova

### Key Metrics

- Lines of Code: **-** - PHP, JS, Twig, CSS, HTML
- Database Tables: **-** - MySQL (master-slave)
- Sub-Applications: **-** - Microservices ecosystem
- Languages Supported: **-** - FR, EN, DE, ES, IT, NL, PT
- Dedicated Servers: **-** - OVH Proxmox VE
- Supplier Connectors: **-** - Automated data import
- Versioning Entries: **-** - 836 Git + 398 SVN
- Reseller Websites: **-** - MyEasyWeb hosted CMS

## Presentation & Project Definition

_Fifteen interconnected sub-applications, four search-engine generations, 8 years of development_

### Domain

B2B communication through promotional objects - connecting European suppliers, resellers, and agencies in the promotional products industry.

### Target Users

B2B professionals across Europe - communication agencies, distributors and examples of integrated European suppliers (Midocean, PF Concept, BIC, Paul Stricker, SOL'S, TopTex, Topico, Inspirion, Makito, Xindao, Clipper, Cybernecard, Pixika, Delta, Passot, Lm, Boomerang, Axpol, Goya, GetImpressed, Giving, Lensen Toppoint, Cottel, Eljte, Frezal, Imbretex).

**Content:** European Sourcing is a **B2B search engine for promotional products** acting as a permanent online tradeshow at European scale - a **precursor to what we call marketplaces today**, aimed at all European promotional products resellers. The project constitutes a **complete application ecosystem** composed of fifteen interconnected sub-applications, developed over more than 6 years (2010-2017).

The platform connects three types of actors in the promotional products market:
- **Suppliers** (manufacturers/wholesalers) who list their product catalogs → **B2B**
- **Resellers/Distributors** (communication agencies) who search products for their clients → **B2B**
- **Visitors** who browse the online catalog on reseller sites (end clients) → **B2C**

The system functions as a **permanent professional online tradeshow**, offering suppliers a multi-channel showcase (online catalog, newsletters, advertising banners, annual guidebook, Google Ads) and resellers a multilingual product search engine covering 7 European languages.

**Domain:** Business Domain

**Target Users:** Target Users

**Functional Scope:** Functional Scope

**Scope Catalog:** Multilingual Product Catalog (7 languages)

**Scope Search:** Full-Text Search (Elasticsearch)

**Scope Extranet:** Supplier/Reseller Back-Office

**Scope Flux:** Automated Supplier Data Import (26+ connectors)

**Scope Api:** REST API with WSSE Authentication

**Scope Translate:** Centralized Translation System

**Scope Payment:** Online Payment (Sogenactif)

**Scope Mew:** Reseller Mini-Sites CMS (MyEasyWeb)

**Scope Mobile:** Mobile Applications (PhoneGap/Cordova)

**Scope Stats:** Consultation Statistics (views, searches, clicks)

**Scope Export:** Data Export (CSV + product images)

**Scope Seo:** SEO / Marketing Back-Office

## Objectives, Context, Stakes & Risks

_Digitalizing the European promotional products market_

### Context

The initial project (v1/v2) was developed by **SQLI**, a French IT services company, with a custom PHP framework and Smarty templates. The legacy code contained 398 SVN revisions covering 2010-2013.

When I joined SQLI, **5 full-time PHP developers** were dedicated to the project. Over time, I took on a growing share of the technical scope, eventually handling **the entire perimeter on my own** - a role that naturally evolved with my expertise and the autonomy that came with the PME environment. After covering the full perimeter solo for a while, I asked for reinforcement and obtained the hiring of a second developer.

From 2014-2016, **our new Medialeads team** undertook a **complete rewrite** of the platform, progressively migrating from the custom framework to **Symfony 2/3** while maintaining the public site on a lighter custom MVC framework.

The platform was **multilingual** (7 languages), **multi-country**, with high product data volumes, and the need to maintain compatibility with existing supplier data feeds - **all hosted on fully self-managed OVH dedicated servers: we handled absolutely everything ourselves, from system configuration to deployments**.

### Stake Business

Revenue from supplier subscriptions (240-288 EUR/year) and advertising services (banners, newsletters, guidebook, Google Ads, media planning).

### Stake Position

European Sourcing positioned itself as the go-to reference for online promotional product sourcing in Europe - a precursor to today's B2B marketplaces, replacing traditional paper catalogs and physical tradeshows.

### Stake Ecosystem

The company also operated TendanceObjet.com, Kadobjet.fr, FranceObjet.com, Omyague.com, GourmetOnline.pro, Recherche-Publicitaire.com, GraphicSourcing.com, CPrint-Sourcing.com, WineSpiritSourcing.com, Tradexpo-Online.fr - each targeting a specific market segment.

- Position the platform as **the European reference** for online B2B promotional products sourcing, replacing paper catalogs and physical tradeshows
- Build a **multilingual product catalog** aggregating **several million products and variants** from dozens of suppliers
- Provide resellers with an **advanced search engine** with filters by category, brand, price, attributes, marking
- Automate the **import of supplier data feeds** (prices, stocks, docs, descriptions) from 26+ suppliers
- Offer resellers a **turnkey mini-site e-commerce solution** (MyEasyWeb) with their own branded storefront connected to the central catalog
- Generate **detailed consultation statistics** for suppliers (product views, searches, clicks)

**Objectives:** Objectives

**Context:** Context

**Stakes:** Stakes

**Stake Business:** Business Model

**Stake Position:** Strategic Position

**Stake Ecosystem:** Brand Ecosystem

**Risks:** Identified Risks

**Risk1 Title:** Technical Debt

**Risk1 Desc:** Progressive migration from a custom framework to Symfony, coexistence of two architectures (SVN legacy + Git modern), MD5 password hashing with a single iteration and no salt - consistent with the state of the art of PHP security practices during the 2008-2014 decade, before bcrypt became the default standard.

**Risk2 Title:** Integration Complexity

**Risk2 Desc:** Supplier data feeds were heterogeneous (CSV, XML, API), requiring a specific adapter per supplier maintained in flux.europeansourcing.com.

**Risk3 Title:** Infrastructure Dependency

**Risk3 Desc:** 9 dedicated OVH servers with Proxmox virtualization, MySQL master/slave replication, manual deployments via svn up - reflecting the technical constraints of the era, before the democratization of Docker and modern CI/CD pipelines.

**Risk4 Title:** Bus Factor

**Risk4 Desc:** Only 3 main developers for the entire ecosystem of 38 sub-projects and 9 servers.

## The Steps - What I Did

_From SQLI monolith to distributed microservices architecture_

**Phase1 Name:** Phase 1

**Phase1 Title:** SQLI Development & SVN Legacy (2008-2013)

**Phase1 Period:** 2008 - 2013

**Phase2 Name:** Phase 2

**Phase2 Title:** Internal Takeover & Microservices (2014-2016)

**Phase2 Period:** Jan 2016 - Dec 2016

**Phase3 Name:** Phase 3

**Phase3 Title:** Architectural Modernization (2016-2017)

**Phase3 Period:** Mar 2016 - Nov 2016

## The Actors - Interactions

_Collaborating within a small but highly productive team_

### Development Team

3 to 5 active developers depending on the period, with clearly divided responsibilities:

### Development Workflow

GitHub organization medialeads (Bordeaux), branches per developer (jose, fancyweb, wamania), internal DokuWiki documentation. No formal Pull Request process was identified - the team relied on direct branch merges and developer-owned areas of the codebase.

## The Results

_Measurable impact for the business and for my career_

### For Me

- **Massive data management & SQL optimization**: mastery of **SQL normal forms** (1NF, 2NF, 3NF, BCNF), all **join types** (INNER/LEFT/RIGHT/CROSS/SELF), **advanced indexing** (B-tree, composite, covering indexes), constant **`EXPLAIN ANALYZE`** plan analysis, **MySQL master-slave replication** and **Memcache caching**. Ran **nightly batches of several hours** to recompute stock levels, prices and promotions across the whole catalog - at that scale a missing index could turn a 50 ms query into a 30-second timeout, so every millisecond saved per query compounded over millions of executions.
- **Search engines & indexing**: hands-on progression across **four generations** of search engines - (1) **MySQL LIKE / FULLTEXT** (MyISAM/InnoDB), (2) **PostgreSQL full-text search** with `tsvector`/`tsquery`, **GIN indexes** and `to_tsvector`/`ts_rank` functions, (3) **Apache Solr** indexing hundreds of thousands of products with advanced faceting (categories, colors, prices, suppliers), spell-checking and custom relevance scoring, (4) **Elasticsearch** with inverted indexes, multilingual analyzers (stemming, tokenization, normalization), TF-IDF scoring, aggregations and facets. Learned the deep differences between a relational engine and a dedicated search engine.
- **Complex algorithms & business rules**: design and implementation of **numerous complex algorithms** and **intricate business rules** - for example computing every possible combination of price, product variants and availability (**Cartesian product / combinatorial explosion** generating thousands of combinations per product across sizes, colors, quantities, marking types, marking zones and finishes). Mastery of dynamic pricing rule modeling and business decision engines.
- Mastered **Symfony 2/3 ecosystem** at production scale (Propel, Doctrine, bundles, services, security, WSSE)
- Developed strong skills in **legacy code migration** - transitioning from SVN monolith to Git-based microservices without downtime
- Built domain knowledge in **B2B promotional products** market, data feed automation, and multi-country e-commerce
- Learned to coordinate within a small team where each developer owns significant portions of the codebase

**Delivered Features:** **Key features delivered:**
- Multilingual product catalog with dedicated Elasticsearch indexes and custom relevance scoring
- REST API with WSSE stateless authentication (nonce + timestamp + digest)
- Automated supplier data import connectors handling heterogeneous CSV / XML / API feeds
- Supplier/reseller back-office with complete product management
- SPA supplier dashboard (AngularJS 1.2 + CoffeeScript + Grunt + Bower)
- Reseller mini-sites CMS (MyEasyWeb) with branded storefronts connected to the central catalog
- Online payment integration (Sogenactif, Société Générale)
- SEO / marketing back-office (Zend Framework + ExtJS + web crawler)
- Hybrid mobile applications (jQuery Mobile + PhoneGap/Cordova)

## The Aftermath

_What happened after I left the project_

**Content:** **I left the project in November 2016**, handing over a platform in full running order. The team continued operating and evolving European Sourcing - **the project was not interrupted**, it simply continued without me. The final consolidation phase around shared Symfony bundles, which I had started, was carried on by the team.

With hindsight, the architectural choices made in Phase 2 proved **sound and modern for their era**: the service-oriented approach with dedicated subdomains, the WSSE stateless inter-service authentication, the search engine architecture and the automated supplier connector infrastructure remained technically impressive long after I had moved on.

## My Critical Perspective

_Honest retrospective on 8 years of development_

### Would Do Differently

With todays standards and hindsight, a few choices could have been made differently - each decision made sense within the constraints of its era:
- **Adopting a single framework** from the start rather than maintaining a custom PHP framework alongside Symfony, though historical context justified coexistence during migration.
- **Setting up CI/CD** from the GitHub migration (January 2016) - Jenkins, Travis CI or GitLab CI were available even if GitHub Actions did not exist yet.
- **Using Docker** for dev and deploy environments, though Proxmox was the mature virtualization standard for PHP PME at the time.
- **Centralizing data access** via a single API rather than direct MySQL from each service - a pattern that only became widespread after 2017.

**Strengths:** Strengths

**Improvements:** Areas for Improvement

**Would Do Differently:** What I Would Do Differently

**Lessons:** Lasting Lessons
