001
014
015 package com.liferay.util.bridges.php;
016
017 import com.caucho.quercus.servlet.QuercusServlet;
018 import com.caucho.vfs.Path;
019 import com.caucho.vfs.SchemeMap;
020 import com.caucho.vfs.Vfs;
021
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
025 import com.liferay.portal.kernel.servlet.DynamicServletConfig;
026 import com.liferay.portal.kernel.servlet.PortletServletObjectsFactory;
027 import com.liferay.portal.kernel.servlet.ServletContextUtil;
028 import com.liferay.portal.kernel.servlet.ServletObjectsFactory;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.InstanceFactory;
031 import com.liferay.portal.kernel.util.StringBundler;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.util.bridges.common.ScriptPostProcess;
034
035 import java.io.IOException;
036 import java.io.PrintWriter;
037
038 import java.net.URI;
039
040 import java.util.Enumeration;
041 import java.util.HashMap;
042 import java.util.Map;
043
044 import javax.portlet.ActionRequest;
045 import javax.portlet.ActionResponse;
046 import javax.portlet.GenericPortlet;
047 import javax.portlet.PortletConfig;
048 import javax.portlet.PortletException;
049 import javax.portlet.PortletURL;
050 import javax.portlet.RenderRequest;
051 import javax.portlet.RenderResponse;
052
053 import javax.servlet.ServletConfig;
054 import javax.servlet.http.HttpServletRequest;
055 import javax.servlet.http.HttpServletResponse;
056
057
060 public class PHPPortlet extends GenericPortlet {
061
062 @Override
063 public void destroy() {
064 if (quercusServlet != null) {
065 quercusServlet.destroy();
066 }
067 }
068
069 @Override
070 public void doDispatch(
071 RenderRequest renderRequest, RenderResponse renderResponse)
072 throws IOException, PortletException {
073
074 String phpUri = renderRequest.getParameter(_PHP_URI_PARAM);
075
076 if (phpUri != null) {
077 processPHP(phpUri, renderRequest, renderResponse);
078 }
079 else {
080 super.doDispatch(renderRequest, renderResponse);
081 }
082 }
083
084 @Override
085 public void doEdit(
086 RenderRequest renderRequest, RenderResponse renderResponse)
087 throws IOException, PortletException {
088
089 if (renderRequest.getPreferences() == null) {
090 super.doEdit(renderRequest, renderResponse);
091 }
092 else {
093 processPHP(editUri, renderRequest, renderResponse);
094 }
095 }
096
097 @Override
098 public void doHelp(
099 RenderRequest renderRequest, RenderResponse renderResponse) {
100
101 processPHP(helpUri, renderRequest, renderResponse);
102 }
103
104 @Override
105 public void doView(
106 RenderRequest renderRequest, RenderResponse renderResponse) {
107
108 processPHP(viewUri, renderRequest, renderResponse);
109 }
110
111 @Override
112 public void init(PortletConfig portletConfig) throws PortletException {
113 super.init(portletConfig);
114
115 editUri = getInitParameter("edit-uri");
116 helpUri = getInitParameter("help-uri");
117 viewUri = getInitParameter("view-uri");
118
119 addPortletParams = GetterUtil.getBoolean(
120 portletConfig.getInitParameter("add-portlet-params"), true);
121
122 String servletObjectsFactoryName = GetterUtil.getString(
123 getInitParameter("servlet-objects-factory"),
124 PortletServletObjectsFactory.class.getName());
125
126 try {
127 Class<?> servletObjectsFactoryClass = Class.forName(
128 servletObjectsFactoryName);
129
130 servletObjectsFactory =
131 (ServletObjectsFactory)servletObjectsFactoryClass.newInstance();
132 }
133 catch (Exception e) {
134 throw new PortletException(
135 "Unable to instantiate factory" + servletObjectsFactoryName, e);
136 }
137 }
138
139 @Override
140 public void processAction(
141 ActionRequest actionRequest, ActionResponse actionResponse) {
142
143 String phpURI = actionRequest.getParameter(_PHP_URI_PARAM);
144
145 if (phpURI != null) {
146 actionResponse.setRenderParameter(_PHP_URI_PARAM, phpURI);
147 }
148 }
149
150 protected synchronized void initQuercus(ServletConfig servletConfig)
151 throws PortletException {
152
153 if (quercusServlet != null) {
154 return;
155 }
156
157 try {
158 SchemeMap schemeMap = Vfs.getDefaultScheme();
159
160 URI rootURI = ServletContextUtil.getRootURI(
161 servletConfig.getServletContext());
162
163 schemeMap.put(
164 rootURI.getScheme(),
165 new ServletContextPath(servletConfig.getServletContext()));
166
167 Path.setDefaultSchemeMap(schemeMap);
168
169 quercusServlet = (QuercusServlet)InstanceFactory.newInstance(
170 _QUERCUS_SERVLET);
171
172 Map<String, String> params = new HashMap<String, String>();
173
174 Enumeration<String> enu = servletConfig.getInitParameterNames();
175
176 while (enu.hasMoreElements()) {
177 String name = enu.nextElement();
178
179 if (!name.equals("portlet-class")) {
180 params.put(name, servletConfig.getInitParameter(name));
181 }
182 }
183
184 servletConfig = new DynamicServletConfig(servletConfig, params);
185
186 QuercusServlet.PhpIni phpIni = quercusServlet.createPhpIni();
187
188 phpIni.setProperty("unicode.http_input_encoding", StringPool.UTF8);
189 phpIni.setProperty("unicode.output_encoding", StringPool.UTF8);
190 phpIni.setProperty("unicode.runtime_encoding", StringPool.UTF8);
191 phpIni.setProperty("unicode.semantics", Boolean.TRUE.toString());
192
193 quercusServlet.init(servletConfig);
194 }
195 catch (Exception e) {
196 throw new PortletException(e);
197 }
198 }
199
200 protected void processPHP(
201 String phpURI, RenderRequest renderRequest,
202 RenderResponse renderResponse) {
203
204 try {
205 ServletConfig servletConfig =
206 servletObjectsFactory.getServletConfig(
207 getPortletConfig(), renderRequest);
208
209 initQuercus(servletConfig);
210
211 HttpServletRequest request =
212 servletObjectsFactory.getServletRequest(renderRequest);
213 HttpServletResponse response =
214 servletObjectsFactory.getServletResponse(
215 renderRequest, renderResponse);
216
217 PHPServletRequest phpRequest = new PHPServletRequest(
218 request, servletConfig, renderRequest, renderResponse,
219 getPortletConfig(), phpURI, addPortletParams);
220
221 BufferCacheServletResponse bufferCacheServletResponse =
222 new BufferCacheServletResponse(response);
223
224 quercusServlet.service(phpRequest, bufferCacheServletResponse);
225
226 String result = bufferCacheServletResponse.getString();
227
228 String contentType = bufferCacheServletResponse.getContentType();
229
230 if (contentType.startsWith("text/")) {
231 result = rewriteURLs(result, renderResponse.createRenderURL());
232 }
233
234 renderResponse.setContentType(contentType);
235
236 PrintWriter writer = renderResponse.getWriter();
237
238 writer.write(result.toCharArray());
239 }
240 catch (Exception e) {
241 _log.error("Error processing PHP", e);
242 }
243 }
244
245 protected String rewriteURLs(String page, PortletURL portletURL) {
246 ScriptPostProcess scriptPostProcess = new ScriptPostProcess();
247
248 scriptPostProcess.setInitalPage(new StringBundler(page));
249
250 scriptPostProcess.postProcessPage(portletURL, _PHP_URI_PARAM);
251
252 return scriptPostProcess.getFinalizedPage();
253 }
254
255 protected boolean addPortletParams;
256 protected String editUri;
257 protected String helpUri;
258 protected QuercusServlet quercusServlet;
259 protected ServletObjectsFactory servletObjectsFactory;
260 protected String viewUri;
261
262 private static final String _PHP_URI_PARAM = "phpURI";
263
264 private static final String _QUERCUS_SERVLET =
265 "com.caucho.quercus.servlet.QuercusServlet";
266
267 private static Log _log = LogFactoryUtil.getLog(PHPPortlet.class);
268
269 }