usar renderPartial fuera de ccontroller

Buenas,

En mi estructura de código, tengo que enviar correos, pero resulta que esta función se encuentra fuera de la logca del site.

os explico:

mi site envía correos cuando se ejecutan ciertas acciones.

en las que está fallando es cuando se ejecuta en el "preload"

Cuando se carga la web, necesito que ciertas funciones se ejecuten antes que todo, dentro de estas hay la posibilidad de enviar correos, esta funcion de enviar correos hace renders partials:




public function plainEmail($to, $replyTo = '', $subject, $message){ // $to, $from, $subject, $message

    $template = '_plainEmail';

    $body = Yii::app()->controller->renderPartial($this->pathViews.'.'.$template, array('message' => $message), true);

    //echo $body;

    $this->_SendEmail($to, $replyTo, $subject, $body);

}



Cual es el problema??

Pues, resulta que este código tal como está, si se ejecuta desde el "preload", salta un error de que no se puede ejecutar "renderPartial" puesto que no encuentra controller.

Mi solución, para salir del paso, ha sido que la class "mail" extienda "CController", y usar:




$this->renderParial(....)



personalmente no me gusta la solución, hay alguna otra que se les pueda ocurrir??

usar de algo que no sea el preload???

Gracias!!!

(perdon por el tocho)

Una buena solución que implementamos en varios proyectos de forma exitosa es si podés ejecutar un CRON, llamar a una página via WGET y que se ocupe de estas acciones. La misma tiene solo acceso desde cierto IP.

Saludos!

@sebas tiene la via que deberias aplicar: una delegacion de este proceso a un componente dedicado a ello, pero si no la vas a implementar del todo usa esto:

1.crea un componente llamado “Emailer.php” en tu carpeta ‘components’ con este codigo:




<?php 

class Emailer {

	

	public static function funcionEspecificaDePrueba($para, $subj, $nombre,$apellido){




       $desde = 'sender@gmail.com';




		$c = new CController('emailer');

		$body = $c->renderPartial('application.views.emailer._patron1'

			,array('nombre'=>$nombre,'apellido'=>$apellido),true);

		

		// listo...tienes el cuerpo del correo listo 

		// para enviarlo usando tu metodo de correo preferido

		//

		$headers="From: {$desde }";

		Yii::log("funcionEspecificaDePrueba: body=".$body,"info");

		return @mail($para,$subj,$body,$headers);

	}

	

}



  1. si te das cuenta, en el componente mailer, hago una referencia directa

a una vista ‘_patron1’, el cual sera renderizado usando una nueva instancia

de CController, para usar su metodo renderPartial.

guarda esto bajo:

"protected/views/emailer/_patron1.php"




hola email de prueba. 

Nombre es :  <?php echo $nombre; ?> <br/>

y apellido es: <?php echo $apellido; ?> 



  1. PRUBEAS:

en cualquier controller de pruebas, haz una llamada para probar:




public function actionTest(){

$em = new Emailer();

		echo "resultado=".$em->funcionEspecificaDePrueba(

                  "prueba@gmail.com","probando","pedro","perez");

	}



  1. VERIFICA:

en tu logger (si en config tienes ‘info’ habilitado) mostrara lo siguiente.

(este log es lanzado desde el componente Emailer)

2012/06/01 11:29:40 [info] [application]

funcionEspecificaDePrueba: body=hola email de prueba. Nombre es : pedro <br/>

y apellido es: perez

de esta forma tendras un "componente" dedicado y aislado, y de ahi a aplicar la solucion

que @sebas indica sera muy sencillo de implementar.

Muchas gracias a los dos,

@bluyell, lo había implementado tal como dices :) para salir del paso, pero es algo que no me convence.

Por ahora lo dejo así y con mas tiempo para implementación iré migrando a la solución que propone @sebas que me parece la mas correcta.

Saludos y gracias.

Con esta via que te paso logras "aislar" el proceso especifico de envio de emails, utilizando el framework para "renderizar" los cuerpos de los correos, y además es "un punto de arranque" para implementar la solcuión de @sebas. Es parecida a lo que tu habias implementado, con la diferencia de que aqui el controller no esta fuera de contexto como en tu caso, lo que te generó el error.

adicionalmente, y hablando por experiencia fuerte en el tema de envío y recepción de correo masivo (12.000 peticiones diarias en mi caso en un cliente de Caracas Venezuela) , además considera lo siguiente:

1-es necesario implementar un proceso aislado ?

[indent]si => si tu demanda de correo es muy alta.

no => si tu demanda es baja. ( no matas una mosca con un fusil )[/indent]

2-considera el uso de captcha. Un proceso externo que se aproveche de tu exposición del sistema de envío de correo (un robot escaneador de servicios hecho por algun malvado ), puede usarte para envio de "spam", por tanto bloquearán la IP de tu HOSTING COMPLETO, y te amonestarán con la posible suspensión de tu servicio si el caso es grave, en el caso mas leve, si usas tu propio servidor, caerás en una lista negra a diario, y los proveedores terminarán rechazando todos tus correos.

3-el proceso aislado de correo, no es otra cosa sino lo mismo que quieres hacer en tu aplicación, pero de forma dedicada a ello, quiza implementando sistemas de reenvio de correo fallido, contabilizador de envios efectivos y control de envios programados por fecha.

pero cualquier que sea tu solucion (proceso aislado o local), deberás aislar en tu aplicación el proceso de envio de correo dependiente de funciones especificas (como mail() o cualquier otra), que fué lo que yo te envié, nada mas y nada menos, por lo cual me tomo la libertad de responderte explayadamente, asumiendo que realmente comprendiste el objetivo al que quiero llegar: EL USO DE COMPONENTES.

byebye