Download the PHP package homlity/sdk-simi without Composer
On this page you can find all versions of the php package homlity/sdk-simi. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package sdk-simi
SDK SIMI para PHP
Cliente PHP oficial mantenido por Homlity para consumir el API de SIMI (CRM inmobiliario) desde cualquier proyecto PHP, Laravel o WordPress.
🏠 homlity.com · 👩💻 Portal de desarrolladores · 📦 GitHub · 📝 Changelog
📘 ¿Prefieres leerlo como página web? El repositorio incluye una versión navegable con el mismo contenido en
docs/index.html(autocontenida, lista para GitHub Pages). Los ejemplos ejecutables están enexamples/.
Tabla de contenido
- ¿Qué es este SDK y para qué sirve?
- Requisitos
- Instalación
- El token de SIMI
- Primeros pasos (Quickstart)
- Arquitectura del SDK
- Referencia del API (
ApiFachada) - Filtros disponibles
- Referencia de modelos
- Servicios de aplicación
- Paginación
- Recetas y ejemplos completos
- Integración con Laravel
- Integración con WordPress
- Rendimiento y caché
- Manejo de errores
- Advertencias y comportamientos a tener en cuenta
- Pruebas
- Versionado y contribución
- Soporte
- Licencia
1. ¿Qué es este SDK y para qué sirve?
SIMI es un CRM inmobiliario usado por inmobiliarias y constructoras (principalmente en Colombia) para administrar su inventario de inmuebles, sus asesores y sus sedes. SIMI expone ese inventario mediante un API HTTP público por inmobiliaria, autenticado con un token.
Ese API devuelve JSON "crudo", con nombres de campos inconsistentes entre endpoints
(Codigo_Inmueble vs idInm, banios vs banos, Venta vs ValorVenta, precios con símbolos y puntos
mezclados dentro de strings, etc.). Este SDK existe para que nunca tengas que tocar ese JSON.
Con el SDK obtienes:
| Sin SDK | Con SDK |
|---|---|
Construir URLs a mano tipo .../filtroInmueble/ciudad/5/total/12 |
$api->getInmuebles(["ciudad" => 5, "total" => 12]) |
curl + json_decode + validar status en cada llamada |
Objetos Response* con isSuccess() |
Leer $json["Inmuebles"][0]["Codigo_Inmueble"] |
$inmueble->identificacion() |
Limpiar "$ 350.000.000" con regex |
$inmueble->valorVenta() → 350.000.000 |
| Descubrir qué filtros acepta el API a base de errores | Filtros validados: filtro inválido → excepción inmediata |
| Reimplementar paginación en cada proyecto | PaginadorInmueblePreview + PaginatorHTML |
Casos de uso típicos
- Portales inmobiliarios: listados con filtros, ficha de detalle, mapa, galería, video y fotos 360.
- Landing pages / home: carrusel de inmuebles destacados.
- Buscadores: selects encadenados departamento → ciudad → barrio, tipos de inmueble y gestiones.
- Página "Nuestro equipo": listado paginado de asesores con foto, celular y correo.
- Sincronizaciones / feeds: exportar inventario hacia portales externos u otros sistemas.
- Widgets y shortcodes de WordPress alimentados con inventario real.
2. Requisitos
| Requisito | Detalle |
|---|---|
| PHP | 7.x u 8.x (el código es compatible desde PHP 7.1; usa tipado de retorno y array_filter con ARRAY_FILTER_USE_BOTH) |
ext-curl |
Obligatoria: toda petición HTTP se hace con cURL |
ext-json |
Obligatoria: parseo de las respuestas |
ext-mbstring |
Obligatoria |
| Token SIMI | Provisto por SIMI/la inmobiliaria (ver §4) |
| Salida a internet | El servidor debe poder alcanzar simi-api.com y api.simicrm.app |
3. Instalación
Vía Composer (recomendado)
El nombre del paquete en
composer.jsoneshomlity/sdk-simiy el repositorio es github.com/homlity/sdk-simi.
Migración desde codwelt/sdk-simi
El paquete se publicaba antes bajo el vendor codwelt. El vendor y el namespace ahora son homlity,
y ese es un cambio incompatible hacia atrás: todo el código que use el SDK debe actualizar sus
importaciones.
Un solo comando actualiza todas las referencias de tu proyecto:
Después ejecuta composer dump-autoload. Ninguna clase, método ni firma cambió: solo el namespace.
Nota sobre versiones. Cambiar el namespace rompe la compatibilidad, así que corresponde una versión mayor:
v3.0.0. Publica ese tag antes de usar la restricción^3.0; mientras no exista, apunta adev-master.
Vía repositorio VCS
Si el paquete no está disponible en tu Packagist (por ejemplo, si trabajas contra un fork, una rama de
desarrollo o un Packagist privado), agrégalo como repositorio VCS en el composer.json de tu proyecto:
Para fijar una versión exacta usa cualquiera de los tags publicados (v2.5.7, v2.5.6, …):
Autoload
El paquete usa PSR-4:
Basta con incluir el autoloader de Composer:
4. El token de SIMI
Todas las peticiones se autentican con un único token que entrega SIMI a cada inmobiliaria.
Formato
El SDK valida el token contra esta expresión regular antes de permitir cualquier llamada:
Es decir: entre 40 y 50 caracteres alfanuméricos, un guion, y un número (el identificador de la inmobiliaria/sede). Ejemplo con forma válida:
Si el token no cumple el formato, setTokenProvider() lanza:
Cómo se envía
| Destino | Mecanismo |
|---|---|
http://simi-api.com/ApiSimiweb/response/ |
HTTP Basic Auth, con usuario vacío y el token como contraseña (CURLOPT_USERPWD = ":$token") |
https://api.simicrm.app/crm/ (solo getEstadoInmueble) |
Cabeceras token: <token> y Accept: application/vnd.apisimi.v3+json |
Nunca lo publiques
El token da acceso completo al inventario de la inmobiliaria. No lo escribas en el código fuente ni lo
subas al repositorio. Cárgalo desde variables de entorno; para eso existe la interfaz
TokenServiceProviderRespository (ver §5).
5. Primeros pasos (Quickstart)
Paso 1 — Implementa tu proveedor de token
El SDK nunca recibe el token "a mano": recibe un objeto que sabe de dónde sacarlo. Así puedes leerlo de
.env, de la base de datos, de un secreto de tu infraestructura o de la configuración multi-sitio.
Paso 2 — Construye el API
Atajo: si no necesitas el proveedor puedes instanciar la fachada directamente. Ojo: esta vía no valida el formato del token.
Paso 3 — Consulta inmuebles
Paso 4 — Ficha de detalle
6. Arquitectura del SDK
El paquete sigue una separación por capas al estilo de arquitectura hexagonal:
Flujo de una llamada
Por qué te importa esta separación
- Puedes tipar contra
ApiFachadaRepository(la abstracción) y no contra la implementación concreta. Eso te permite inyectar un doble de prueba, un decorador con caché o un mock en tus tests sin tocar red. - Los servicios de aplicación (
Application/) recibenApiFachadaRepositorypor constructor, así que funcionan igual con la fachada real o con la que tú decores.
7. Referencia del API (ApiFachada)
Todos los métodos pueden lanzar \Exception (URL inválida, filtro no permitido, parámetro requerido faltante).
| Método | Devuelve | Endpoint real |
|---|---|---|
getInmuebles(array $filtros = []) |
['inmuebles' => InmueblePreview[], 'paginador' => PaginadorInmueblePreview\|null] |
v2.1.1/filtroInmueble/... |
getDetalleInmueble($codigoInmueble) |
InmuebleDetail o null |
v2/inmueble/codInmueble/{codigo} |
getInmueblesDestacados(array $filtros = []) |
['inmuebles' => InmueblePreview[], 'paginador' => …] |
v21/inmueblesDestacados/... |
getDepartamentos() |
Departamento[] |
v2/departamento |
getCiudades($idDepartamento) |
Ciudad[] |
v2/ciudad/idDepartamento/{id} |
getBarrios($idCiudad) |
Barrio[] |
v2/barrios/idCiudad/{id} |
getTiposInmueble() |
TipoInmueble[] |
v2/tipoInmuebles/unique/1 |
getGestionesInmueble() |
GestionInmueble[] |
gestion |
getAsesores(array $filtros = []) |
['asesores' => AsesorUsuario[], 'paginador' => PaginadorAsesores\|null] |
usuarios/... |
getEstadoInmueble(int $idEstado, $idGestion) |
InmueblePreview[] |
api.simicrm.app/crm/inmuebles?estado=…&gestion=… |
getToken() |
string |
— |
getInmuebles(array $filtros = [])
Listado paginado con filtros. Es el método central del SDK.
- Los filtros con valor "vacío" (
"",null,0,[]) se descartan antes de armar la URL. - Si
isSuccess()falla, devuelve['inmuebles' => [], 'paginador' => null]— sin excepción. - Valores por defecto:
total = 30,limite = 1.
getDetalleInmueble($codigo)
Recibe el código público del inmueble (formato sede-consecutivo, p. ej. "503-4848").
Devuelve InmuebleDetail o null si el API respondió sin cuerpo útil.
Lanza excepción si $codigo está vacío:
El codigo del inmueble es requerido para obtener el detalle del inmueble.
getInmueblesDestacados(array $filtros = [])
Solo acepta limite y total. Ideal para el home.
getDepartamentos() / getCiudades($id) / getBarrios($id)
Catálogo geográfico de la inmobiliaria (solo devuelve zonas donde hay inventario). Los tres modelos
implementan JsonSerializable, así que puedes devolverlos directamente desde un endpoint JSON propio:
getTiposInmueble()
Tipos con conteo de inventario, útil para menús tipo "Apartamentos (124)".
getGestionesInmueble()
Las gestiones/operaciones configuradas (Venta, Arriendo, Arriendo/Venta…). El id() es el valor que se pasa
en el filtro tipOper.
getAsesores(array $filtros = [])
Filtros permitidos: limite (página), cantidad (por página, por defecto 30) y asesor (id puntual).
getEstadoInmueble(int $idEstado, $idGestion)
Usa un API distinto (https://api.simicrm.app/crm/, cabecera token, versión v3). Devuelve un array
plano de InmueblePreview filtrando por estado y gestión. El SDK acepta las tres formas de respuesta que
usa ese endpoint (data, Inmuebles o array plano).
Si tu token no está habilitado para el API v3 del CRM, este método devolverá un array vacío aunque los demás métodos funcionen correctamente.
8. Filtros disponibles
getInmuebles()
Cualquier clave fuera de esta lista lanza Exception: Filtro (x) no esta permitido en APISIMI.
| Filtro | Significado | Ejemplo |
|---|---|---|
departamento |
Id de departamento (de getDepartamentos()) |
5 |
ciudad |
Id de ciudad (de getCiudades()) |
1 |
zona |
Id de zona | 12 |
barrio |
Id de barrio (de getBarrios()) |
320 |
tipoInm |
Id de tipo de inmueble (de getTiposInmueble()) |
1 |
tipOper |
Id de gestión/operación (de getGestionesInmueble()) |
2 |
areamin / areamax |
Rango de área construida en m² | 50 / 180 |
valmin / valmax |
Rango de precio (sin puntos ni símbolos) | 200000000 |
alcobas |
Número de alcobas | 3 |
banios |
Número de baños | 2 |
garajes |
Número de garajes | 1 |
campo |
Campo por el cual ordenar | Venta |
order |
Sentido del orden | ASC / DESC |
limite |
Página solicitada (por defecto 1) |
2 |
total |
Registros por página (por defecto 30) |
12 |
sede |
Id de sede, para inmobiliarias multi-sede | 503 |
getInmueblesDestacados()
limite, total.
getAsesores()
limite, cantidad, asesor.
9. Referencia de modelos
InmueblePreview
Objeto liviano que devuelve getInmuebles(), getInmueblesDestacados() y getEstadoInmueble().
| Método | Devuelve | Campo crudo |
|---|---|---|
identificacion() |
Código público, p. ej. 503-4848 |
Codigo_Inmueble |
nombre() |
"Apartamento - El Poblado, Medellín" (generado) |
— |
tipoInmueble() |
Nombre del tipo | Tipo_Inmueble |
gestion() / idGestion() |
Operación y su id | Gestion / idGestion |
enArriendo() / enArriendoVenta() |
bool según la gestión |
— |
valorVenta(bool $format = true) |
"350.000.000" o 350000000 |
Venta |
valorArriendo(bool $format = true) |
idem | Canon |
administracion($format = false) |
Valor de administración | Administracion |
alcobas() / baños() / garaje() |
Conteos | Alcobas / banios / garaje |
areaConstruida() / areaLote() |
Áreas en m² | AreaConstruida / AreaLote |
estrato() / edad() / estado() |
Datos adicionales | Estrato / EdadInmueble / idEstado |
departamento() / ciudad() / zona() / barrio() |
Ubicación (texto) | Departamento, Ciudad, Zona, Barrio |
latitud() / longitud() |
Coordenadas | latitud / longitud |
descripcion() |
Descripción larga | descripcionlarga |
fotoPortada() |
URL de la foto principal | foto1 |
logo() |
Logo de la inmobiliaria | logo |
video360() |
URL del recorrido 360 | video360 |
InmuebleDetail extends InmueblePreview
Devuelto por getDetalleInmueble(). Sobrescribe los getters porque el endpoint de detalle usa otros
nombres de campo, y agrega:
| Método | Devuelve |
|---|---|
identificacion() |
idInm (id interno del detalle) |
direccion() |
Dirección o null |
barrioId() / ciudadId() / departamentoId() / idZona() |
Ids de ubicación |
idLocalidad() / nlocalidad() |
Localidad (disponible desde v3.4.0) |
idTipoInmueble() / idGestion() / idSede() |
Ids para armar consultas relacionadas |
fotos() |
Array crudo de fotos ([['foto' => 'https://…'], …]) |
fotos360() |
Array de recorridos 360 |
video() |
URL de video normalizada (limpia dobles barras) o null |
caracterisitcasInternas() |
CaracteristicaInterna[] (nota: el nombre del método lleva la errata original) |
caracteristicasExternas() |
CaracteristicaExterna[] |
caracteristicasAlrededores() |
CaracteristicaAlrededores[] |
caracteristicas() |
Todas las anteriores en un solo array |
caracteristicasPorColumnas(int $n = 3) |
Características repartidas en n columnas, listas para maquetar |
asesor() |
AsesorDetalleInmueble o null |
administracionIncluida() |
bool (campo AdmonIncluida == '1') |
valorVenta() / valorArriendo() |
Leen ValorVenta / ValorCanon |
Características
CaracteristicaInterna, CaracteristicaExterna y CaracteristicaAlrededores comparten la misma forma:
Asesores
AsesorUsuario (listado) y AsesorDetalleInmueble (ficha) extienden AsesorRepository:
Catálogos
Departamento, Ciudad, Barrio, GestionInmueble y TipoInmueble exponen id() y nombre()
(TipoInmueble además totalInmuebles()). Todos implementan JsonSerializable.
10. Servicios de aplicación
ObtenedorInmueblesSimilaresService
Devuelve inmuebles parecidos a uno dado (misma zona, mismo tipo, misma gestión), excluyendo el original. Perfecto para el bloque "También te puede interesar" de la ficha.
obtener($detalle, $cantidad)pide$cantidadinmuebles al API y devuelve$cantidad - 1, porque reserva un espacio para descartar el inmueble original. Pide uno más de los que quieras mostrar.
ObtenedorUrlFichaInmuebleService
Construye la URL de la ficha técnica en SIMI para un inmueble.
PaginatorHTML
Paginador de propósito general que genera el HTML de la paginación (compatible con las clases de Bootstrap).
11. Paginación
getInmuebles() y getInmueblesDestacados() devuelven un PaginadorInmueblePreview:
getAsesores() devuelve un PaginadorAsesores con paginaActual(), total(), totalPorPagina(),
numeroPaginaInicio() y numeroPaginaFin().
Recuerda: el paginador es null cuando la petición no fue exitosa. Verifica siempre antes de usarlo.
12. Recetas y ejemplos completos
En la carpeta examples/ encontrarás estos ejemplos como archivos PHP ejecutables.
Buscador con selects encadenados (JSON para tu frontend)
Listado con filtros desde $_GET (saneado)
Filtrar contra la lista blanca antes de llamar al SDK evita que un parámetro inventado en la URL provoque la excepción
Filtro (x) no esta permitido en APISIMI.
Ficha completa con galería, mapa y similares
Precios: formateado vs. numérico
Útil para datos estructurados de SEO:
Exportar todo el inventario (paginando)
13. Integración con Laravel
1. Configuración
config/simi.php:
.env:
2. Proveedor de token
app/Services/Simi/TokenSimiProvider.php:
3. Service provider
app/Providers/SimiServiceProvider.php:
Se instancia
ApiFachadadirectamente en lugar de usarApiServiceProvider::build()para evitar el singleton estático del SDK (ver §17). Si quieres conservar la validación del formato del token, replícala o llama asetTokenProvider()una sola vez en elregister().
4. Uso en un controlador
Ojo con el caché: los objetos del SDK son serializables porque solo guardan arrays, pero si prefieres cachear los datos crudos usa
Request*/Response*directamente y guardagetBody().
14. Integración con WordPress
Un shortcode [simi_destacados total="6"] para mostrar inventario en cualquier página:
Guarda el token en wp-config.php, nunca en la base de datos ni en el tema:
15. Rendimiento y caché
El API de SIMI es la parte lenta de cualquier página que lo consuma. Cachea siempre.
Como los servicios del SDK dependen de la abstracción ApiFachadaRepository, puedes escribir un decorador
con caché y seguir usando todo el resto del SDK sin cambios:
TTL sugeridos:
| Dato | TTL |
|---|---|
| Departamentos, ciudades, barrios, tipos, gestiones | 12–24 h (cambian muy poco) |
| Listados y destacados | 5–15 min |
| Ficha de detalle | 10–30 min |
16. Manejo de errores
El SDK usa dos mecanismos distintos, y conviene tener claro cuál aplica:
Excepciones (\Exception)
Se lanzan antes de hacer la petición, por errores del programador o de configuración:
| Mensaje | Causa |
|---|---|
El token es invalido |
El token no cumple el patrón de §4 |
No a seteado el Proveedor del token... |
Llamaste a getAPi() sin setTokenProvider() |
Filtro (x) no esta permitido en APISIMI |
Filtro fuera de la lista blanca |
El codigo del inmueble es requerido... |
getDetalleInmueble('') |
El id del departemento es necesario... |
getCiudades(null) |
El id de la ciudad es necesaria... |
getBarrios(null) |
Url Invalida |
La URL construida no pasó FILTER_VALIDATE_URL |
Respuestas vacías (sin excepción)
Si el API responde con error, no responde, o devuelve un cuerpo inesperado, no hay excepción: recibes
listas vacías o null.
Patrón recomendado
17. Advertencias y comportamientos a tener en cuenta
Estas son particularidades reales del código. Conocerlas ahorra horas de depuración.
1. build() es un singleton compartido entre proveedores.
ApiServiceProviderRepository::build() guarda la instancia en una propiedad estática de la clase padre.
Si en el mismo proceso llamas primero a ApiServiceProvider::build() y luego a
ApiModelRepositoryServiceProvider::build(), la segunda llamada devuelve la primera instancia.
→ Si necesitas ambas variantes, instancia las fachadas directamente:
2. Filtros con valor 0 se descartan. getInmuebles() filtra con !empty($value), así que
['garajes' => 0] nunca llega al API. Para "sin garaje" tendrás que filtrar del lado de tu aplicación.
3. idTipoInmueble() es protected en InmueblePreview. Solo es público en InmuebleDetail.
Llamarlo sobre un preview desde fuera de la clase produce un Error de PHP.
4. fotoPortada() en InmuebleDetail asume que hay fotos. Accede a fotos()[0]["foto"] sin validar;
si el inmueble no tiene fotos, genera un aviso. Valida antes:
5. Domain\ModelRepository\Inmueble::valorArriendo() devuelve el valor de venta. Es un defecto conocido
de esa clase auxiliar. Usa InmueblePreview::valorArriendo() / InmuebleDetail::valorArriendo().
6. caracterisitcasInternas() está escrito con errata (caracterisitcas, no caracteristicas). Se
mantiene así por compatibilidad hacia atrás.
7. La URL base por defecto es HTTP, no HTTPS (http://simi-api.com/ApiSimiweb/response/). Solo
getEstadoInmueble() usa https://api.simicrm.app/crm/.
8. cURL no define timeouts. Una caída del API puede colgar tu petición. Si es crítico para ti, envuelve las llamadas en tu propia capa con timeout y caché (§15), o considera un job en segundo plano.
9. getEstadoInmueble() habla con otro API y otra versión (v3 del CRM, autenticación por cabecera).
Que funcionen los demás métodos no garantiza que este también.
10. Los métodos de catálogo no verifican isSuccess() antes de iterar. getDepartamentos() itera
directamente sobre la respuesta; si el API falla, puede propagarse un aviso de PHP. Envuélvelos en
try/catch en producción.
18. Pruebas
Las pruebas del repositorio golpean el API real, así que necesitan un token válido.
Edita tests/testing.env.php:
Ejecuta:
tests/testing.env.php está en .gitignore: no subas tu token.
Probar tu propio código sin red
Extiende la abstracción y devuelve datos fijos:
19. Versionado y contribución
- El proyecto sigue Semantic Versioning.
- Los cambios se registran en
CHANGELOG.mdsiguiendo Keep a Changelog. - Fija la versión en tu
composer.json("homlity/sdk-simi": "^3.0") y revisa el changelog antes de subir de versión menor.
Para contribuir
- Haz un fork de
homlity/sdk-simi. - Crea una rama desde
master:git checkout -b fix/mi-arreglo. - Si agregas un endpoint, sigue el patrón existente: una clase en
Requests/, una enResponses/, su modelo enModelos/, y expón el método enApiFachaday enApiFachadaRepository. - Agrega la entrada correspondiente en
CHANGELOG.md. - Abre el Pull Request describiendo el cambio y su impacto en las versiones.
20. Soporte
| Recurso | Enlace |
|---|---|
| Sitio principal | https://homlity.com/ |
| Portal de desarrolladores | https://homlity.com/desarrolladores/ |
| Repositorio | https://github.com/homlity/sdk-simi |
| Reportar un problema | https://github.com/homlity/sdk-simi/issues |
| Historial de cambios | CHANGELOG.md |
| Licencia | MIT |
21. Licencia
Este SDK se distribuye bajo la licencia MIT. Puedes usarlo, modificarlo, integrarlo en proyectos
comerciales y redistribuirlo, siempre que conserves el aviso de copyright. El texto completo está en
LICENSE.
La licencia cubre el SDK, no el acceso al API de SIMI: para consumir datos necesitas un token válido entregado por SIMI o por la inmobiliaria propietaria del inventario.
Hecho con ☕ por el equipo de Homlity.
All versions of sdk-simi with dependencies
ext-json Version *
ext-mbstring Version *